From patchwork Thu Nov 2 02:53:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740861 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F637C4332F for ; Thu, 2 Nov 2023 02:54:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348035AbjKBCyL (ORCPT ); Wed, 1 Nov 2023 22:54:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347248AbjKBCyK (ORCPT ); Wed, 1 Nov 2023 22:54:10 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFBC911D for ; Wed, 1 Nov 2023 19:54:06 -0700 (PDT) X-ASG-Debug-ID: 1698893643-1eb14e538b03ad0002-PT6Irj Received: from ZXSHMBX3.zhaoxin.com (ZXSHMBX3.zhaoxin.com [10.28.252.165]) by mx2.zhaoxin.com with ESMTP id kqxDGmCxhBpZXNkK (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:03 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX3.zhaoxin.com (10.28.252.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:03 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:02 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 01/12] i2c: wmt: Reduce redundant: bus busy check Date: Thu, 2 Nov 2023 10:53:51 +0800 X-ASG-Orig-Subj: [PATCH v3 01/12] i2c: wmt: Reduce redundant: bus busy check Message-ID: <740a0a0cff29b236eff4fce9225ee256ceedd8d1.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX3.zhaoxin.com[10.28.252.165] X-Barracuda-Start-Time: 1698893643 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 1716 X-Barracuda-BRTS-Status: 1 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Put wmt_i2c_wait_bus_not_busy() in a more appropriate place to reduce code redundancy Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index 76118abc6e10..d554c6377533 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -128,12 +128,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, unsigned long wait_result; int xfer_len = 0; - if (!(pmsg->flags & I2C_M_NOSTART)) { - ret = wmt_i2c_wait_bus_not_busy(i2c_dev); - if (ret < 0) - return ret; - } - if (pmsg->len == 0) { /* * We still need to run through the while (..) once, so @@ -219,12 +213,6 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, unsigned long wait_result; u32 xfer_len = 0; - if (!(pmsg->flags & I2C_M_NOSTART)) { - ret = wmt_i2c_wait_bus_not_busy(i2c_dev); - if (ret < 0) - return ret; - } - val = readw(i2c_dev->base + REG_CR); val &= ~CR_TX_END; writew(val, i2c_dev->base + REG_CR); @@ -297,11 +285,18 @@ static int wmt_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg; int i, is_last; int ret = 0; + struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); for (i = 0; ret >= 0 && i < num; i++) { is_last = ((i + 1) == num); pmsg = &msgs[i]; + if (!(pmsg->flags & I2C_M_NOSTART)) { + ret = wmt_i2c_wait_bus_not_busy(i2c_dev); + if (ret < 0) + return ret; + } + if (pmsg->flags & I2C_M_RD) ret = wmt_i2c_read(adap, pmsg, is_last); else From patchwork Thu Nov 2 02:53:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740860 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C60C1C4167B for ; Thu, 2 Nov 2023 02:54:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347177AbjKBCyM (ORCPT ); Wed, 1 Nov 2023 22:54:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344988AbjKBCyK (ORCPT ); Wed, 1 Nov 2023 22:54:10 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 119DA8E for ; Wed, 1 Nov 2023 19:54:07 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0001-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id zIZWUBaNEHZEgsD9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:04 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:04 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:03 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 02/12] i2c: wmt: Reduce redundant: wait event complete Date: Thu, 2 Nov 2023 10:53:52 +0800 X-ASG-Orig-Subj: [PATCH v3 02/12] i2c: wmt: Reduce redundant: wait event complete Message-ID: <5931f8affc8992a229a4bae5bf9a8ad04a564107.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893644 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 2110 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Put the handling of interrupt events in a function class to reduce code redundancy. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index d554c6377533..1b31330ba4eb 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -109,6 +109,12 @@ static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev) static int wmt_check_status(struct wmt_i2c_dev *i2c_dev) { int ret = 0; + unsigned long wait_result; + + wait_result = wait_for_completion_timeout(&i2c_dev->complete, + msecs_to_jiffies(500)); + if (!wait_result) + return -ETIMEDOUT; if (i2c_dev->cmd_status & ISR_NACK_ADDR) ret = -EIO; @@ -125,7 +131,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val; int ret; - unsigned long wait_result; int xfer_len = 0; if (pmsg->len == 0) { @@ -167,12 +172,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, } while (xfer_len < pmsg->len) { - wait_result = wait_for_completion_timeout(&i2c_dev->complete, - msecs_to_jiffies(500)); - - if (wait_result == 0) - return -ETIMEDOUT; - ret = wmt_check_status(i2c_dev); if (ret) return ret; @@ -210,7 +209,6 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val; int ret; - unsigned long wait_result; u32 xfer_len = 0; val = readw(i2c_dev->base + REG_CR); @@ -251,12 +249,6 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, } while (xfer_len < pmsg->len) { - wait_result = wait_for_completion_timeout(&i2c_dev->complete, - msecs_to_jiffies(500)); - - if (!wait_result) - return -ETIMEDOUT; - ret = wmt_check_status(i2c_dev); if (ret) return ret; From patchwork Thu Nov 2 02:53:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 418D1C41535 for ; Thu, 2 Nov 2023 02:54:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348179AbjKBCyL (ORCPT ); Wed, 1 Nov 2023 22:54:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347257AbjKBCyK (ORCPT ); Wed, 1 Nov 2023 22:54:10 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11C76B9 for ; Wed, 1 Nov 2023 19:54:07 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0002-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id X40x139H80wrFMTX (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:04 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:04 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:03 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 03/12] i2c: wmt: Reduce redundant: clock mode setting Date: Thu, 2 Nov 2023 10:53:53 +0800 X-ASG-Orig-Subj: [PATCH v3 03/12] i2c: wmt: Reduce redundant: clock mode setting Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893644 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 3041 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org The frequency setting mode is adjusted to reduce the code redundancy, and it is also convenient to share with zhaoxin Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index 1b31330ba4eb..a44ce5fdde8a 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -74,9 +74,6 @@ #define MCR_APB_96M 7 #define MCR_APB_166M 12 -#define I2C_MODE_STANDARD 0 -#define I2C_MODE_FAST 1 - #define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000)) struct wmt_i2c_dev { @@ -85,7 +82,7 @@ struct wmt_i2c_dev { struct device *dev; void __iomem *base; struct clk *clk; - int mode; + u16 tcr; int irq; u16 cmd_status; }; @@ -129,7 +126,7 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, int last) { struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); - u16 val, tcr_val; + u16 val, tcr_val = i2c_dev->tcr; int ret; int xfer_len = 0; @@ -156,11 +153,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, reinit_completion(&i2c_dev->complete); - if (i2c_dev->mode == I2C_MODE_STANDARD) - tcr_val = TCR_STANDARD_MODE; - else - tcr_val = TCR_FAST_MODE; - tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK)); writew(tcr_val, i2c_dev->base + REG_TCR); @@ -207,7 +199,7 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, int last) { struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); - u16 val, tcr_val; + u16 val, tcr_val = i2c_dev->tcr; int ret; u32 xfer_len = 0; @@ -233,11 +225,6 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, reinit_completion(&i2c_dev->complete); - if (i2c_dev->mode == I2C_MODE_STANDARD) - tcr_val = TCR_STANDARD_MODE; - else - tcr_val = TCR_FAST_MODE; - tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK); writew(tcr_val, i2c_dev->base + REG_TCR); @@ -346,10 +333,10 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev) readw(i2c_dev->base + REG_CSR); /* read clear */ writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR); - if (i2c_dev->mode == I2C_MODE_STANDARD) - writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR); - else + if (i2c_dev->tcr == TCR_FAST_MODE) writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR); + else + writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR); return 0; } @@ -382,10 +369,9 @@ static int wmt_i2c_probe(struct platform_device *pdev) return PTR_ERR(i2c_dev->clk); } - i2c_dev->mode = I2C_MODE_STANDARD; err = of_property_read_u32(np, "clock-frequency", &clk_rate); if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) - i2c_dev->mode = I2C_MODE_FAST; + i2c_dev->tcr = TCR_FAST_MODE; i2c_dev->dev = &pdev->dev; From patchwork Thu Nov 2 02:53:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 882EEC0018A for ; Thu, 2 Nov 2023 02:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348182AbjKBCyM (ORCPT ); Wed, 1 Nov 2023 22:54:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347897AbjKBCyK (ORCPT ); Wed, 1 Nov 2023 22:54:10 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E21E83 for ; Wed, 1 Nov 2023 19:54:07 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0003-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id a4NVjYMoRkg8vkpq (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:05 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:04 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:03 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 04/12] i2c: wmt: Reduce redundant: REG_CR setting Date: Thu, 2 Nov 2023 10:53:54 +0800 X-ASG-Orig-Subj: [PATCH v3 04/12] i2c: wmt: Reduce redundant: REG_CR setting Message-ID: <0fce410bbf7c3d5e01cf679fd435fa0065e55e53.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893644 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 2314 X-Barracuda-BRTS-Status: 1 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org These Settings for the same register, REG_CR, can be put together to reduce code redundancy. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index a44ce5fdde8a..d503e85752ea 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -144,9 +144,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, if (!(pmsg->flags & I2C_M_NOSTART)) { val = readw(i2c_dev->base + REG_CR); val &= ~CR_TX_END; - writew(val, i2c_dev->base + REG_CR); - - val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } @@ -204,24 +201,15 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, u32 xfer_len = 0; val = readw(i2c_dev->base + REG_CR); - val &= ~CR_TX_END; - writew(val, i2c_dev->base + REG_CR); + val &= ~(CR_TX_END | CR_TX_NEXT_NO_ACK); - val = readw(i2c_dev->base + REG_CR); - val &= ~CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + REG_CR); - - if (!(pmsg->flags & I2C_M_NOSTART)) { - val = readw(i2c_dev->base + REG_CR); + if (!(pmsg->flags & I2C_M_NOSTART)) val |= CR_CPU_RDY; - writew(val, i2c_dev->base + REG_CR); - } - if (pmsg->len == 1) { - val = readw(i2c_dev->base + REG_CR); + if (pmsg->len == 1) val |= CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + REG_CR); - } + + writew(val, i2c_dev->base + REG_CR); reinit_completion(&i2c_dev->complete); @@ -243,15 +231,10 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8; xfer_len++; - if (xfer_len == pmsg->len - 1) { - val = readw(i2c_dev->base + REG_CR); - val |= (CR_TX_NEXT_NO_ACK | CR_CPU_RDY); - writew(val, i2c_dev->base + REG_CR); - } else { - val = readw(i2c_dev->base + REG_CR); - val |= CR_CPU_RDY; - writew(val, i2c_dev->base + REG_CR); - } + val = readw(i2c_dev->base + REG_CR) | CR_CPU_RDY; + if (xfer_len == pmsg->len - 1) + val |= CR_TX_NEXT_NO_ACK; + writew(val, i2c_dev->base + REG_CR); } return 0; From patchwork Thu Nov 2 02:53:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740858 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D391AC001B2 for ; Thu, 2 Nov 2023 02:54:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348186AbjKBCyO (ORCPT ); Wed, 1 Nov 2023 22:54:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348183AbjKBCyN (ORCPT ); Wed, 1 Nov 2023 22:54:13 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 745C1110 for ; Wed, 1 Nov 2023 19:54:09 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0004-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id H5BB3rbabDyTXfVr (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:05 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:04 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 05/12] i2c: wmt: Reduce redundant: function parameter Date: Thu, 2 Nov 2023 10:53:55 +0800 X-ASG-Orig-Subj: [PATCH v3 05/12] i2c: wmt: Reduce redundant: function parameter Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893645 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 2001 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Use more appropriate parameter passing to reduce the amount of code Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index d503e85752ea..ec2a8da134e5 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -122,10 +122,9 @@ static int wmt_check_status(struct wmt_i2c_dev *i2c_dev) return ret; } -static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, +static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg, int last) { - struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val = i2c_dev->tcr; int ret; int xfer_len = 0; @@ -192,10 +191,8 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, return 0; } -static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, - int last) +static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg) { - struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val = i2c_dev->tcr; int ret; u32 xfer_len = 0; @@ -245,13 +242,11 @@ static int wmt_i2c_xfer(struct i2c_adapter *adap, int num) { struct i2c_msg *pmsg; - int i, is_last; + int i; int ret = 0; struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); for (i = 0; ret >= 0 && i < num; i++) { - is_last = ((i + 1) == num); - pmsg = &msgs[i]; if (!(pmsg->flags & I2C_M_NOSTART)) { ret = wmt_i2c_wait_bus_not_busy(i2c_dev); @@ -260,9 +255,9 @@ static int wmt_i2c_xfer(struct i2c_adapter *adap, } if (pmsg->flags & I2C_M_RD) - ret = wmt_i2c_read(adap, pmsg, is_last); + ret = wmt_i2c_read(i2c_dev, pmsg); else - ret = wmt_i2c_write(adap, pmsg, is_last); + ret = wmt_i2c_write(i2c_dev, pmsg, (i + 1) == num); } return (ret < 0) ? ret : i; From patchwork Thu Nov 2 02:53:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740859 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A694EC4708E for ; Thu, 2 Nov 2023 02:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347257AbjKBCyN (ORCPT ); Wed, 1 Nov 2023 22:54:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344988AbjKBCyM (ORCPT ); Wed, 1 Nov 2023 22:54:12 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76685128 for ; Wed, 1 Nov 2023 19:54:09 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0005-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id HiLL9FC3Xxwh5Mja (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:05 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:04 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 06/12] i2c: wmt: delete .remove_new Date: Thu, 2 Nov 2023 10:53:56 +0800 X-ASG-Orig-Subj: [PATCH v3 06/12] i2c: wmt: delete .remove_new Message-ID: <5b4dc259cb10e8e8c4a1dcb2aab37f2d4d89dbef.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893645 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 1369 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org use API devm_i2c_add_adapter instead of i2c_add_adapter, remove callback remove_new. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index ec2a8da134e5..406b6827c42d 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -376,23 +376,9 @@ static int wmt_i2c_probe(struct platform_device *pdev) return err; } - err = i2c_add_adapter(adap); - if (err) - return err; - platform_set_drvdata(pdev, i2c_dev); - return 0; -} - -static void wmt_i2c_remove(struct platform_device *pdev) -{ - struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - - /* Disable interrupts, clock and delete adapter */ - writew(0, i2c_dev->base + REG_IMR); - clk_disable_unprepare(i2c_dev->clk); - i2c_del_adapter(&i2c_dev->adapter); + return devm_i2c_add_adapter(&pdev->dev, &i2c_dev->adapter); } static const struct of_device_id wmt_i2c_dt_ids[] = { @@ -402,7 +388,6 @@ static const struct of_device_id wmt_i2c_dt_ids[] = { static struct platform_driver wmt_i2c_driver = { .probe = wmt_i2c_probe, - .remove_new = wmt_i2c_remove, .driver = { .name = "wmt-i2c", .of_match_table = wmt_i2c_dt_ids, From patchwork Thu Nov 2 02:53:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740586 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E264DC0018C for ; Thu, 2 Nov 2023 02:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344988AbjKBCyN (ORCPT ); Wed, 1 Nov 2023 22:54:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348175AbjKBCyM (ORCPT ); Wed, 1 Nov 2023 22:54:12 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 861FD12A for ; Wed, 1 Nov 2023 19:54:09 -0700 (PDT) X-ASG-Debug-ID: 1698893644-1eb14e538e03af0006-PT6Irj Received: from ZXSHMBX2.zhaoxin.com (ZXSHMBX2.zhaoxin.com [10.28.252.164]) by mx2.zhaoxin.com with ESMTP id IKfu7GCXRb0RiZvj (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:06 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX2.zhaoxin.com (10.28.252.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.164 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 07/12] i2c: wmt: create wmt_i2c_init for general init Date: Thu, 2 Nov 2023 10:53:57 +0800 X-ASG-Orig-Subj: [PATCH v3 07/12] i2c: wmt: create wmt_i2c_init for general init Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX2.zhaoxin.com[10.28.252.164] X-Barracuda-Start-Time: 1698893645 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 3404 X-Barracuda-BRTS-Status: 1 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Some common initialization actions are put in the function wmt_i2c_init(), which is convenient to share with zhaoxin. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 70 ++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index 406b6827c42d..b2fb2e7e4f0d 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -286,6 +286,47 @@ static irqreturn_t wmt_i2c_isr(int irq, void *data) return IRQ_HANDLED; } +int wmt_i2c_init(struct platform_device *pdev, struct wmt_i2c_dev **pi2c_dev) +{ + int err; + int irq_flags; + struct wmt_i2c_dev *i2c_dev; + struct device_node *np = pdev->dev.of_node; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); + if (!i2c_dev) + return -ENOMEM; + + i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(i2c_dev->base)) + return PTR_ERR(i2c_dev->base); + + if (np) { + irq_flags = 0; + i2c_dev->irq = irq_of_parse_and_map(np, 0); + if (!i2c_dev->irq) + return -EINVAL; + } else { + irq_flags = IRQF_SHARED; + i2c_dev->irq = platform_get_irq(pdev, 0); + if (i2c_dev->irq < 0) + return i2c_dev->irq; + } + + err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, + irq_flags, pdev->name, i2c_dev); + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to request irq %i\n", i2c_dev->irq); + + i2c_dev->dev = &pdev->dev; + init_completion(&i2c_dev->complete); + platform_set_drvdata(pdev, i2c_dev); + + *pi2c_dev = i2c_dev; + return 0; +} + static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev) { int err; @@ -327,19 +368,9 @@ static int wmt_i2c_probe(struct platform_device *pdev) int err; u32 clk_rate; - i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); - if (!i2c_dev) - return -ENOMEM; - - i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); - if (IS_ERR(i2c_dev->base)) - return PTR_ERR(i2c_dev->base); - - i2c_dev->irq = irq_of_parse_and_map(np, 0); - if (!i2c_dev->irq) { - dev_err(&pdev->dev, "irq missing or invalid\n"); - return -EINVAL; - } + err = wmt_i2c_init(pdev, &i2c_dev); + if (err) + return err; i2c_dev->clk = of_clk_get(np, 0); if (IS_ERR(i2c_dev->clk)) { @@ -351,15 +382,6 @@ static int wmt_i2c_probe(struct platform_device *pdev) if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) i2c_dev->tcr = TCR_FAST_MODE; - i2c_dev->dev = &pdev->dev; - - err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, 0, - "i2c", i2c_dev); - if (err) { - dev_err(&pdev->dev, "failed to request irq %i\n", i2c_dev->irq); - return err; - } - adap = &i2c_dev->adapter; i2c_set_adapdata(adap, i2c_dev); strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name)); @@ -368,16 +390,12 @@ static int wmt_i2c_probe(struct platform_device *pdev) adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; - init_completion(&i2c_dev->complete); - err = wmt_i2c_reset_hardware(i2c_dev); if (err) { dev_err(&pdev->dev, "error initializing hardware\n"); return err; } - platform_set_drvdata(pdev, i2c_dev); - return devm_i2c_add_adapter(&pdev->dev, &i2c_dev->adapter); } From patchwork Thu Nov 2 02:53:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 524CFC001DB for ; Thu, 2 Nov 2023 02:54:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348190AbjKBCyO (ORCPT ); Wed, 1 Nov 2023 22:54:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348186AbjKBCyN (ORCPT ); Wed, 1 Nov 2023 22:54:13 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8895D12B for ; Wed, 1 Nov 2023 19:54:09 -0700 (PDT) X-ASG-Debug-ID: 1698893646-1eb14e538d03ae0001-PT6Irj Received: from ZXSHMBX1.zhaoxin.com (ZXSHMBX1.zhaoxin.com [10.28.252.163]) by mx2.zhaoxin.com with ESMTP id ZcJhODkvCPA2OEjV (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:06 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.163 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX1.zhaoxin.com (10.28.252.163) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.163 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 08/12] i2c: wmt: rename marcos with prefix WMTI2C_ Date: Thu, 2 Nov 2023 10:53:58 +0800 X-ASG-Orig-Subj: [PATCH v3 08/12] i2c: wmt: rename marcos with prefix WMTI2C_ Message-ID: <248fe879a97e16c58b9d6e24b44cd51c4b9a82df.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX1.zhaoxin.com[10.28.252.163] X-Barracuda-Start-Time: 1698893646 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 10537 X-Barracuda-BRTS-Status: 1 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Tweaked a few formatting things: rename marcos with prefix WMTI2C_ Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 174 +++++++++++++++++------------------ 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index b2fb2e7e4f0d..ec9e4bfc52b0 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -20,59 +20,59 @@ #include #include -#define REG_CR 0x00 -#define REG_TCR 0x02 -#define REG_CSR 0x04 -#define REG_ISR 0x06 -#define REG_IMR 0x08 -#define REG_CDR 0x0A -#define REG_TR 0x0C -#define REG_MCR 0x0E -#define REG_SLAVE_CR 0x10 -#define REG_SLAVE_SR 0x12 -#define REG_SLAVE_ISR 0x14 -#define REG_SLAVE_IMR 0x16 -#define REG_SLAVE_DR 0x18 -#define REG_SLAVE_TR 0x1A +#define WMTI2C_REG_CR 0x00 +#define WMTI2C_REG_TCR 0x02 +#define WMTI2C_REG_CSR 0x04 +#define WMTI2C_REG_ISR 0x06 +#define WMTI2C_REG_IMR 0x08 +#define WMTI2C_REG_CDR 0x0A +#define WMTI2C_REG_TR 0x0C +#define WMTI2C_REG_MCR 0x0E +#define WMTI2C_REG_SLAVE_CR 0x10 +#define WMTI2C_REG_SLAVE_SR 0x12 +#define WMTI2C_REG_SLAVE_ISR 0x14 +#define WMTI2C_REG_SLAVE_IMR 0x16 +#define WMTI2C_REG_SLAVE_DR 0x18 +#define WMTI2C_REG_SLAVE_TR 0x1A /* REG_CR Bit fields */ -#define CR_TX_NEXT_ACK 0x0000 -#define CR_ENABLE 0x0001 -#define CR_TX_NEXT_NO_ACK 0x0002 -#define CR_TX_END 0x0004 -#define CR_CPU_RDY 0x0008 -#define SLAV_MODE_SEL 0x8000 +#define WMTI2C_CR_TX_NEXT_ACK 0x0000 +#define WMTI2C_CR_ENABLE 0x0001 +#define WMTI2C_CR_TX_NEXT_NO_ACK 0x0002 +#define WMTI2C_CR_TX_END 0x0004 +#define WMTI2C_CR_CPU_RDY 0x0008 +#define WMTI2C_SLAV_MODE_SEL 0x8000 /* REG_TCR Bit fields */ -#define TCR_STANDARD_MODE 0x0000 -#define TCR_MASTER_WRITE 0x0000 -#define TCR_HS_MODE 0x2000 -#define TCR_MASTER_READ 0x4000 -#define TCR_FAST_MODE 0x8000 -#define TCR_SLAVE_ADDR_MASK 0x007F +#define WMTI2C_TCR_STANDARD_MODE 0x0000 +#define WMTI2C_TCR_MASTER_WRITE 0x0000 +#define WMTI2C_TCR_HS_MODE 0x2000 +#define WMTI2C_TCR_MASTER_READ 0x4000 +#define WMTI2C_TCR_FAST_MODE 0x8000 +#define WMTI2C_TCR_SLAVE_ADDR_MASK 0x007F /* REG_ISR Bit fields */ -#define ISR_NACK_ADDR 0x0001 -#define ISR_BYTE_END 0x0002 -#define ISR_SCL_TIMEOUT 0x0004 -#define ISR_WRITE_ALL 0x0007 +#define WMTI2C_ISR_NACK_ADDR 0x0001 +#define WMTI2C_ISR_BYTE_END 0x0002 +#define WMTI2C_ISR_SCL_TIMEOUT 0x0004 +#define WMTI2C_ISR_WRITE_ALL 0x0007 /* REG_IMR Bit fields */ -#define IMR_ENABLE_ALL 0x0007 +#define WMTI2C_IMR_ENABLE_ALL 0x0007 /* REG_CSR Bit fields */ -#define CSR_RCV_NOT_ACK 0x0001 -#define CSR_RCV_ACK_MASK 0x0001 -#define CSR_READY_MASK 0x0002 +#define WMTI2C_CSR_RCV_NOT_ACK 0x0001 +#define WMTI2C_CSR_RCV_ACK_MASK 0x0001 +#define WMTI2C_CSR_READY_MASK 0x0002 /* REG_TR */ -#define SCL_TIMEOUT(x) (((x) & 0xFF) << 8) -#define TR_STD 0x0064 -#define TR_HS 0x0019 +#define WMTI2C_SCL_TIMEOUT(x) (((x) & 0xFF) << 8) +#define WMTI2C_TR_STD 0x0064 +#define WMTI2C_TR_HS 0x0019 /* REG_MCR */ -#define MCR_APB_96M 7 -#define MCR_APB_166M 12 +#define WMTI2C_MCR_APB_96M 7 +#define WMTI2C_MCR_APB_166M 12 #define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -92,7 +92,7 @@ static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev) unsigned long timeout; timeout = jiffies + WMT_I2C_TIMEOUT; - while (!(readw(i2c_dev->base + REG_CSR) & CSR_READY_MASK)) { + while (!(readw(i2c_dev->base + WMTI2C_REG_CSR) & WMTI2C_CSR_READY_MASK)) { if (time_after(jiffies, timeout)) { dev_warn(i2c_dev->dev, "timeout waiting for bus ready\n"); return -EBUSY; @@ -113,10 +113,10 @@ static int wmt_check_status(struct wmt_i2c_dev *i2c_dev) if (!wait_result) return -ETIMEDOUT; - if (i2c_dev->cmd_status & ISR_NACK_ADDR) + if (i2c_dev->cmd_status & WMTI2C_ISR_NACK_ADDR) ret = -EIO; - if (i2c_dev->cmd_status & ISR_SCL_TIMEOUT) + if (i2c_dev->cmd_status & WMTI2C_ISR_SCL_TIMEOUT) ret = -ETIMEDOUT; return ret; @@ -135,28 +135,28 @@ static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg, * start at -1 and break out early from the loop */ xfer_len = -1; - writew(0, i2c_dev->base + REG_CDR); + writew(0, i2c_dev->base + WMTI2C_REG_CDR); } else { - writew(pmsg->buf[0] & 0xFF, i2c_dev->base + REG_CDR); + writew(pmsg->buf[0] & 0xFF, i2c_dev->base + WMTI2C_REG_CDR); } if (!(pmsg->flags & I2C_M_NOSTART)) { - val = readw(i2c_dev->base + REG_CR); - val &= ~CR_TX_END; - val |= CR_CPU_RDY; - writew(val, i2c_dev->base + REG_CR); + val = readw(i2c_dev->base + WMTI2C_REG_CR); + val &= ~WMTI2C_CR_TX_END; + val |= WMTI2C_CR_CPU_RDY; + writew(val, i2c_dev->base + WMTI2C_REG_CR); } reinit_completion(&i2c_dev->complete); - tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK)); + tcr_val |= (WMTI2C_TCR_MASTER_WRITE | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK)); - writew(tcr_val, i2c_dev->base + REG_TCR); + writew(tcr_val, i2c_dev->base + WMTI2C_REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { - val = readw(i2c_dev->base + REG_CR); - val |= CR_CPU_RDY; - writew(val, i2c_dev->base + REG_CR); + val = readw(i2c_dev->base + WMTI2C_REG_CR); + val |= WMTI2C_CR_CPU_RDY; + writew(val, i2c_dev->base + WMTI2C_REG_CR); } while (xfer_len < pmsg->len) { @@ -166,25 +166,25 @@ static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg, xfer_len++; - val = readw(i2c_dev->base + REG_CSR); - if ((val & CSR_RCV_ACK_MASK) == CSR_RCV_NOT_ACK) { + val = readw(i2c_dev->base + WMTI2C_REG_CSR); + if ((val & WMTI2C_CSR_RCV_ACK_MASK) == WMTI2C_CSR_RCV_NOT_ACK) { dev_dbg(i2c_dev->dev, "write RCV NACK error\n"); return -EIO; } if (pmsg->len == 0) { - val = CR_TX_END | CR_CPU_RDY | CR_ENABLE; - writew(val, i2c_dev->base + REG_CR); + val = WMTI2C_CR_TX_END | WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE; + writew(val, i2c_dev->base + WMTI2C_REG_CR); break; } if (xfer_len == pmsg->len) { if (last != 1) - writew(CR_ENABLE, i2c_dev->base + REG_CR); + writew(WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); } else { writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base + - REG_CDR); - writew(CR_CPU_RDY | CR_ENABLE, i2c_dev->base + REG_CR); + WMTI2C_REG_CDR); + writew(WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); } } @@ -197,27 +197,27 @@ static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg) int ret; u32 xfer_len = 0; - val = readw(i2c_dev->base + REG_CR); - val &= ~(CR_TX_END | CR_TX_NEXT_NO_ACK); + val = readw(i2c_dev->base + WMTI2C_REG_CR); + val &= ~(WMTI2C_CR_TX_END | WMTI2C_CR_TX_NEXT_NO_ACK); if (!(pmsg->flags & I2C_M_NOSTART)) - val |= CR_CPU_RDY; + val |= WMTI2C_CR_CPU_RDY; if (pmsg->len == 1) - val |= CR_TX_NEXT_NO_ACK; + val |= WMTI2C_CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + REG_CR); + writew(val, i2c_dev->base + WMTI2C_REG_CR); reinit_completion(&i2c_dev->complete); - tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK); + tcr_val |= WMTI2C_TCR_MASTER_READ | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK); - writew(tcr_val, i2c_dev->base + REG_TCR); + writew(tcr_val, i2c_dev->base + WMTI2C_REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { - val = readw(i2c_dev->base + REG_CR); - val |= CR_CPU_RDY; - writew(val, i2c_dev->base + REG_CR); + val = readw(i2c_dev->base + WMTI2C_REG_CR); + val |= WMTI2C_CR_CPU_RDY; + writew(val, i2c_dev->base + WMTI2C_REG_CR); } while (xfer_len < pmsg->len) { @@ -225,13 +225,13 @@ static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg) if (ret) return ret; - pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8; + pmsg->buf[xfer_len] = readw(i2c_dev->base + WMTI2C_REG_CDR) >> 8; xfer_len++; - val = readw(i2c_dev->base + REG_CR) | CR_CPU_RDY; + val = readw(i2c_dev->base + WMTI2C_REG_CR) | WMTI2C_CR_CPU_RDY; if (xfer_len == pmsg->len - 1) - val |= CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + REG_CR); + val |= WMTI2C_CR_TX_NEXT_NO_ACK; + writew(val, i2c_dev->base + WMTI2C_REG_CR); } return 0; @@ -278,8 +278,8 @@ static irqreturn_t wmt_i2c_isr(int irq, void *data) struct wmt_i2c_dev *i2c_dev = data; /* save the status and write-clear it */ - i2c_dev->cmd_status = readw(i2c_dev->base + REG_ISR); - writew(i2c_dev->cmd_status, i2c_dev->base + REG_ISR); + i2c_dev->cmd_status = readw(i2c_dev->base + WMTI2C_REG_ISR); + writew(i2c_dev->cmd_status, i2c_dev->base + WMTI2C_REG_ISR); complete(&i2c_dev->complete); @@ -344,18 +344,18 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev) return err; } - writew(0, i2c_dev->base + REG_CR); - writew(MCR_APB_166M, i2c_dev->base + REG_MCR); - writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR); - writew(IMR_ENABLE_ALL, i2c_dev->base + REG_IMR); - writew(CR_ENABLE, i2c_dev->base + REG_CR); - readw(i2c_dev->base + REG_CSR); /* read clear */ - writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR); + writew(0, i2c_dev->base + WMTI2C_REG_CR); + writew(WMTI2C_MCR_APB_166M, i2c_dev->base + WMTI2C_REG_MCR); + writew(WMTI2C_ISR_WRITE_ALL, i2c_dev->base + WMTI2C_REG_ISR); + writew(WMTI2C_IMR_ENABLE_ALL, i2c_dev->base + WMTI2C_REG_IMR); + writew(WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); + readw(i2c_dev->base + WMTI2C_REG_CSR); /* read clear */ + writew(WMTI2C_ISR_WRITE_ALL, i2c_dev->base + WMTI2C_REG_ISR); - if (i2c_dev->tcr == TCR_FAST_MODE) - writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR); + if (i2c_dev->tcr == WMTI2C_TCR_FAST_MODE) + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_HS, i2c_dev->base + WMTI2C_REG_TR); else - writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR); + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_STD, i2c_dev->base + WMTI2C_REG_TR); return 0; } @@ -380,7 +380,7 @@ static int wmt_i2c_probe(struct platform_device *pdev) err = of_property_read_u32(np, "clock-frequency", &clk_rate); if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) - i2c_dev->tcr = TCR_FAST_MODE; + i2c_dev->tcr = WMTI2C_TCR_FAST_MODE; adap = &i2c_dev->adapter; i2c_set_adapdata(adap, i2c_dev); From patchwork Thu Nov 2 02:53:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740857 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50DFBC4167D for ; Thu, 2 Nov 2023 02:54:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348175AbjKBCyP (ORCPT ); Wed, 1 Nov 2023 22:54:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347897AbjKBCyN (ORCPT ); Wed, 1 Nov 2023 22:54:13 -0400 Received: from mx2.zhaoxin.com (mx2.zhaoxin.com [203.110.167.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ADF0183 for ; Wed, 1 Nov 2023 19:54:09 -0700 (PDT) X-ASG-Debug-ID: 1698893646-1eb14e538d03ae0002-PT6Irj Received: from ZXSHMBX1.zhaoxin.com (ZXSHMBX1.zhaoxin.com [10.28.252.163]) by mx2.zhaoxin.com with ESMTP id 6nhHifHqUAnf0SeU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:06 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.163 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX1.zhaoxin.com (10.28.252.163) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:05 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.163 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 09/12] i2c: wmt: adjust line length to meet style Date: Thu, 2 Nov 2023 10:53:59 +0800 X-ASG-Orig-Subj: [PATCH v3 09/12] i2c: wmt: adjust line length to meet style Message-ID: <4f1477e7354aba68cd9398fcfcc7698c77d5dc1f.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX1.zhaoxin.com[10.28.252.163] X-Barracuda-Start-Time: 1698893646 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.36:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 13575 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116192 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Tweaked a few formatting things: rename wmt_i2c_dev to wmt_i2c, i2c_dev to i2c, etc. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-wmt.c | 203 ++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 96 deletions(-) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index ec9e4bfc52b0..3dea153c62aa 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -76,7 +76,7 @@ #define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000)) -struct wmt_i2c_dev { +struct wmt_i2c { struct i2c_adapter adapter; struct completion complete; struct device *dev; @@ -87,14 +87,16 @@ struct wmt_i2c_dev { u16 cmd_status; }; -static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev) +static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c *i2c) { unsigned long timeout; + void __iomem *base = i2c->base; timeout = jiffies + WMT_I2C_TIMEOUT; - while (!(readw(i2c_dev->base + WMTI2C_REG_CSR) & WMTI2C_CSR_READY_MASK)) { + while (!(readw(base + WMTI2C_REG_CSR) & WMTI2C_CSR_READY_MASK)) { if (time_after(jiffies, timeout)) { - dev_warn(i2c_dev->dev, "timeout waiting for bus ready\n"); + dev_warn(i2c->dev, + "timeout waiting for bus ready\n"); return -EBUSY; } msleep(20); @@ -103,31 +105,32 @@ static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev) return 0; } -static int wmt_check_status(struct wmt_i2c_dev *i2c_dev) +static int wmt_check_status(struct wmt_i2c *i2c) { int ret = 0; unsigned long wait_result; - wait_result = wait_for_completion_timeout(&i2c_dev->complete, + wait_result = wait_for_completion_timeout(&i2c->complete, msecs_to_jiffies(500)); if (!wait_result) return -ETIMEDOUT; - if (i2c_dev->cmd_status & WMTI2C_ISR_NACK_ADDR) + if (i2c->cmd_status & WMTI2C_ISR_NACK_ADDR) ret = -EIO; - if (i2c_dev->cmd_status & WMTI2C_ISR_SCL_TIMEOUT) + if (i2c->cmd_status & WMTI2C_ISR_SCL_TIMEOUT) ret = -ETIMEDOUT; return ret; } -static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg, +static int wmt_i2c_write(struct wmt_i2c *i2c, struct i2c_msg *pmsg, int last) { - u16 val, tcr_val = i2c_dev->tcr; + u16 val, tcr_val = i2c->tcr; int ret; int xfer_len = 0; + void __iomem *base = i2c->base; if (pmsg->len == 0) { /* @@ -135,69 +138,73 @@ static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg, * start at -1 and break out early from the loop */ xfer_len = -1; - writew(0, i2c_dev->base + WMTI2C_REG_CDR); + writew(0, base + WMTI2C_REG_CDR); } else { - writew(pmsg->buf[0] & 0xFF, i2c_dev->base + WMTI2C_REG_CDR); + writew(pmsg->buf[0] & 0xFF, base + WMTI2C_REG_CDR); } if (!(pmsg->flags & I2C_M_NOSTART)) { - val = readw(i2c_dev->base + WMTI2C_REG_CR); + val = readw(base + WMTI2C_REG_CR); val &= ~WMTI2C_CR_TX_END; val |= WMTI2C_CR_CPU_RDY; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + writew(val, base + WMTI2C_REG_CR); } - reinit_completion(&i2c_dev->complete); + reinit_completion(&i2c->complete); - tcr_val |= (WMTI2C_TCR_MASTER_WRITE | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK)); + tcr_val |= (WMTI2C_TCR_MASTER_WRITE + | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK)); - writew(tcr_val, i2c_dev->base + WMTI2C_REG_TCR); + writew(tcr_val, base + WMTI2C_REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { - val = readw(i2c_dev->base + WMTI2C_REG_CR); + val = readw(base + WMTI2C_REG_CR); val |= WMTI2C_CR_CPU_RDY; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + writew(val, base + WMTI2C_REG_CR); } while (xfer_len < pmsg->len) { - ret = wmt_check_status(i2c_dev); + ret = wmt_check_status(i2c); if (ret) return ret; xfer_len++; - val = readw(i2c_dev->base + WMTI2C_REG_CSR); - if ((val & WMTI2C_CSR_RCV_ACK_MASK) == WMTI2C_CSR_RCV_NOT_ACK) { - dev_dbg(i2c_dev->dev, "write RCV NACK error\n"); + val = readw(base + WMTI2C_REG_CSR); + if (val & WMTI2C_CSR_RCV_NOT_ACK) { + dev_dbg(i2c->dev, "write RCV NACK error\n"); return -EIO; } if (pmsg->len == 0) { - val = WMTI2C_CR_TX_END | WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + val = WMTI2C_CR_TX_END | WMTI2C_CR_CPU_RDY + | WMTI2C_CR_ENABLE; + writew(val, base + WMTI2C_REG_CR); break; } if (xfer_len == pmsg->len) { if (last != 1) - writew(WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); + writew(WMTI2C_CR_ENABLE, base + WMTI2C_REG_CR); } else { - writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base + - WMTI2C_REG_CDR); - writew(WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); + writew(pmsg->buf[xfer_len] & 0xFF, + base + WMTI2C_REG_CDR); + writew(WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE, + base + WMTI2C_REG_CR); } } return 0; } -static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg) +static int wmt_i2c_read(struct wmt_i2c *i2c, struct i2c_msg *pmsg) { - u16 val, tcr_val = i2c_dev->tcr; + u16 val, tcr_val = i2c->tcr; int ret; u32 xfer_len = 0; + void __iomem *base = i2c->base; - val = readw(i2c_dev->base + WMTI2C_REG_CR); + val = readw(base + WMTI2C_REG_CR); val &= ~(WMTI2C_CR_TX_END | WMTI2C_CR_TX_NEXT_NO_ACK); if (!(pmsg->flags & I2C_M_NOSTART)) @@ -206,32 +213,33 @@ static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg) if (pmsg->len == 1) val |= WMTI2C_CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + writew(val, base + WMTI2C_REG_CR); - reinit_completion(&i2c_dev->complete); + reinit_completion(&i2c->complete); - tcr_val |= WMTI2C_TCR_MASTER_READ | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK); + tcr_val |= WMTI2C_TCR_MASTER_READ + | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK); - writew(tcr_val, i2c_dev->base + WMTI2C_REG_TCR); + writew(tcr_val, base + WMTI2C_REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { - val = readw(i2c_dev->base + WMTI2C_REG_CR); + val = readw(base + WMTI2C_REG_CR); val |= WMTI2C_CR_CPU_RDY; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + writew(val, base + WMTI2C_REG_CR); } while (xfer_len < pmsg->len) { - ret = wmt_check_status(i2c_dev); + ret = wmt_check_status(i2c); if (ret) return ret; - pmsg->buf[xfer_len] = readw(i2c_dev->base + WMTI2C_REG_CDR) >> 8; + pmsg->buf[xfer_len] = readw(base + WMTI2C_REG_CDR) >> 8; xfer_len++; - val = readw(i2c_dev->base + WMTI2C_REG_CR) | WMTI2C_CR_CPU_RDY; + val = readw(base + WMTI2C_REG_CR) | WMTI2C_CR_CPU_RDY; if (xfer_len == pmsg->len - 1) val |= WMTI2C_CR_TX_NEXT_NO_ACK; - writew(val, i2c_dev->base + WMTI2C_REG_CR); + writew(val, base + WMTI2C_REG_CR); } return 0; @@ -244,20 +252,20 @@ static int wmt_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg; int i; int ret = 0; - struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); + struct wmt_i2c *i2c = i2c_get_adapdata(adap); for (i = 0; ret >= 0 && i < num; i++) { pmsg = &msgs[i]; if (!(pmsg->flags & I2C_M_NOSTART)) { - ret = wmt_i2c_wait_bus_not_busy(i2c_dev); + ret = wmt_i2c_wait_bus_not_busy(i2c); if (ret < 0) return ret; } if (pmsg->flags & I2C_M_RD) - ret = wmt_i2c_read(i2c_dev, pmsg); + ret = wmt_i2c_read(i2c, pmsg); else - ret = wmt_i2c_write(i2c_dev, pmsg, (i + 1) == num); + ret = wmt_i2c_write(i2c, pmsg, (i + 1) == num); } return (ret < 0) ? ret : i; @@ -275,87 +283,90 @@ static const struct i2c_algorithm wmt_i2c_algo = { static irqreturn_t wmt_i2c_isr(int irq, void *data) { - struct wmt_i2c_dev *i2c_dev = data; + struct wmt_i2c *i2c = data; /* save the status and write-clear it */ - i2c_dev->cmd_status = readw(i2c_dev->base + WMTI2C_REG_ISR); - writew(i2c_dev->cmd_status, i2c_dev->base + WMTI2C_REG_ISR); + i2c->cmd_status = readw(i2c->base + WMTI2C_REG_ISR); + writew(i2c->cmd_status, i2c->base + WMTI2C_REG_ISR); - complete(&i2c_dev->complete); + complete(&i2c->complete); return IRQ_HANDLED; } -int wmt_i2c_init(struct platform_device *pdev, struct wmt_i2c_dev **pi2c_dev) +int wmt_i2c_init(struct platform_device *pdev, struct wmt_i2c **pi2c) { int err; int irq_flags; - struct wmt_i2c_dev *i2c_dev; + struct wmt_i2c *i2c; struct device_node *np = pdev->dev.of_node; - i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); - if (!i2c_dev) + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) return -ENOMEM; - i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); - if (IS_ERR(i2c_dev->base)) - return PTR_ERR(i2c_dev->base); + i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); if (np) { irq_flags = 0; - i2c_dev->irq = irq_of_parse_and_map(np, 0); - if (!i2c_dev->irq) + i2c->irq = irq_of_parse_and_map(np, 0); + if (!i2c->irq) return -EINVAL; } else { irq_flags = IRQF_SHARED; - i2c_dev->irq = platform_get_irq(pdev, 0); - if (i2c_dev->irq < 0) - return i2c_dev->irq; + i2c->irq = platform_get_irq(pdev, 0); + if (i2c->irq < 0) + return i2c->irq; } - err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, - irq_flags, pdev->name, i2c_dev); + err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr, + irq_flags, pdev->name, i2c); if (err) return dev_err_probe(&pdev->dev, err, - "failed to request irq %i\n", i2c_dev->irq); + "failed to request irq %i\n", i2c->irq); - i2c_dev->dev = &pdev->dev; - init_completion(&i2c_dev->complete); - platform_set_drvdata(pdev, i2c_dev); + i2c->dev = &pdev->dev; + init_completion(&i2c->complete); + platform_set_drvdata(pdev, i2c); - *pi2c_dev = i2c_dev; + *pi2c = i2c; return 0; } -static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev) +static int wmt_i2c_reset_hardware(struct wmt_i2c *i2c) { int err; + void __iomem *base = i2c->base; - err = clk_prepare_enable(i2c_dev->clk); + err = clk_prepare_enable(i2c->clk); if (err) { - dev_err(i2c_dev->dev, "failed to enable clock\n"); + dev_err(i2c->dev, "failed to enable clock\n"); return err; } - err = clk_set_rate(i2c_dev->clk, 20000000); + err = clk_set_rate(i2c->clk, 20000000); if (err) { - dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n"); - clk_disable_unprepare(i2c_dev->clk); + dev_err(i2c->dev, "failed to set clock = 20Mhz\n"); + clk_disable_unprepare(i2c->clk); return err; } - writew(0, i2c_dev->base + WMTI2C_REG_CR); - writew(WMTI2C_MCR_APB_166M, i2c_dev->base + WMTI2C_REG_MCR); - writew(WMTI2C_ISR_WRITE_ALL, i2c_dev->base + WMTI2C_REG_ISR); - writew(WMTI2C_IMR_ENABLE_ALL, i2c_dev->base + WMTI2C_REG_IMR); - writew(WMTI2C_CR_ENABLE, i2c_dev->base + WMTI2C_REG_CR); - readw(i2c_dev->base + WMTI2C_REG_CSR); /* read clear */ - writew(WMTI2C_ISR_WRITE_ALL, i2c_dev->base + WMTI2C_REG_ISR); - - if (i2c_dev->tcr == WMTI2C_TCR_FAST_MODE) - writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_HS, i2c_dev->base + WMTI2C_REG_TR); + writew(0, base + WMTI2C_REG_CR); + writew(WMTI2C_MCR_APB_166M, base + WMTI2C_REG_MCR); + writew(WMTI2C_ISR_WRITE_ALL, base + WMTI2C_REG_ISR); + writew(WMTI2C_IMR_ENABLE_ALL, base + WMTI2C_REG_IMR); + writew(WMTI2C_CR_ENABLE, base + WMTI2C_REG_CR); + readw(base + WMTI2C_REG_CSR); /* read clear */ + writew(WMTI2C_ISR_WRITE_ALL, base + WMTI2C_REG_ISR); + + if (i2c->tcr == WMTI2C_TCR_FAST_MODE) + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_HS, + base + WMTI2C_REG_TR); else - writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_STD, i2c_dev->base + WMTI2C_REG_TR); + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_STD, + base + WMTI2C_REG_TR); return 0; } @@ -363,40 +374,40 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev) static int wmt_i2c_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct wmt_i2c_dev *i2c_dev; + struct wmt_i2c *i2c; struct i2c_adapter *adap; int err; u32 clk_rate; - err = wmt_i2c_init(pdev, &i2c_dev); + err = wmt_i2c_init(pdev, &i2c); if (err) return err; - i2c_dev->clk = of_clk_get(np, 0); - if (IS_ERR(i2c_dev->clk)) { + i2c->clk = of_clk_get(np, 0); + if (IS_ERR(i2c->clk)) { dev_err(&pdev->dev, "unable to request clock\n"); - return PTR_ERR(i2c_dev->clk); + return PTR_ERR(i2c->clk); } err = of_property_read_u32(np, "clock-frequency", &clk_rate); if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) - i2c_dev->tcr = WMTI2C_TCR_FAST_MODE; + i2c->tcr = WMTI2C_TCR_FAST_MODE; - adap = &i2c_dev->adapter; - i2c_set_adapdata(adap, i2c_dev); + adap = &i2c->adapter; + i2c_set_adapdata(adap, i2c); strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name)); adap->owner = THIS_MODULE; adap->algo = &wmt_i2c_algo; adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; - err = wmt_i2c_reset_hardware(i2c_dev); + err = wmt_i2c_reset_hardware(i2c); if (err) { dev_err(&pdev->dev, "error initializing hardware\n"); return err; } - return devm_i2c_add_adapter(&pdev->dev, &i2c_dev->adapter); + return devm_i2c_add_adapter(&pdev->dev, &i2c->adapter); } static const struct of_device_id wmt_i2c_dt_ids[] = { From patchwork Thu Nov 2 02:54:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740581 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93C43C4167B for ; Thu, 2 Nov 2023 03:10:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346646AbjKBDKu (ORCPT ); Wed, 1 Nov 2023 23:10:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232949AbjKBDKs (ORCPT ); Wed, 1 Nov 2023 23:10:48 -0400 X-Greylist: delayed 990 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Wed, 01 Nov 2023 20:10:42 PDT Received: from mx1.zhaoxin.com (MX1.ZHAOXIN.COM [210.0.225.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A549110 for ; Wed, 1 Nov 2023 20:10:42 -0700 (PDT) X-ASG-Debug-ID: 1698893646-086e236fed038f0001-PT6Irj Received: from ZXSHMBX3.zhaoxin.com (ZXSHMBX3.zhaoxin.com [10.28.252.165]) by mx1.zhaoxin.com with ESMTP id ZfaOfCkwuLEFd2Bk (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:07 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX3.zhaoxin.com (10.28.252.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 10/12] i2c: wmt: split out common files Date: Thu, 2 Nov 2023 10:54:00 +0800 X-ASG-Orig-Subj: [PATCH v3 10/12] i2c: wmt: split out common files Message-ID: <4828df34481090f188e4d311c92b970e91b43d45.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX3.zhaoxin.com[10.28.252.165] X-Barracuda-Start-Time: 1698893647 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.35:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 24402 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116190 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Since the I2C IP of both wmt and zhaoxin come from VIA, the common driver is named as i2c-viai2c-common.c. Old i2c-wmt.c renamed to i2c-wmt-plt.c. Signed-off-by: Hans Hu --- drivers/i2c/busses/Makefile | 2 + drivers/i2c/busses/i2c-viai2c-common.c | 232 +++++++++++++ drivers/i2c/busses/i2c-viai2c-common.h | 72 +++++ drivers/i2c/busses/i2c-wmt-plt.c | 139 ++++++++ drivers/i2c/busses/i2c-wmt.c | 431 ------------------------- 5 files changed, 445 insertions(+), 431 deletions(-) create mode 100644 drivers/i2c/busses/i2c-viai2c-common.c create mode 100644 drivers/i2c/busses/i2c-viai2c-common.h create mode 100644 drivers/i2c/busses/i2c-wmt-plt.c delete mode 100644 drivers/i2c/busses/i2c-wmt.c diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index af56fe2c75c0..19262f4d30fe 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -120,7 +120,9 @@ obj-$(CONFIG_I2C_TEGRA_BPMP) += i2c-tegra-bpmp.o obj-$(CONFIG_I2C_UNIPHIER) += i2c-uniphier.o obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-uniphier-f.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o +i2c-wmt-objs := i2c-wmt-plt.o i2c-viai2c-common.o obj-$(CONFIG_I2C_WMT) += i2c-wmt.o + i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o diff --git a/drivers/i2c/busses/i2c-viai2c-common.c b/drivers/i2c/busses/i2c-viai2c-common.c new file mode 100644 index 000000000000..45ac56941bee --- /dev/null +++ b/drivers/i2c/busses/i2c-viai2c-common.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include "i2c-viai2c-common.h" + +#define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000)) + +int viai2c_wait_bus_ready(struct viai2c *i2c) +{ + unsigned long timeout; + void __iomem *base = i2c->base; + + timeout = jiffies + WMT_I2C_TIMEOUT; + while (!(readw(base + VIAI2C_REG_CSR) & VIAI2C_CSR_READY_MASK)) { + if (time_after(jiffies, timeout)) { + dev_warn(i2c->dev, "timeout waiting for bus ready\n"); + return -EBUSY; + } + msleep(20); + } + + return 0; +} + +int viai2c_wait_status(struct viai2c *i2c, u8 status) +{ + unsigned long wait_result; + + wait_result = wait_for_completion_timeout(&i2c->complete, + msecs_to_jiffies(500)); + if (!wait_result) + return -ETIMEDOUT; + + if (i2c->cmd_status & status) + return 0; + + return -EIO; +} + +static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, bool last) +{ + u16 val, tcr_val = i2c->tcr; + int xfer_len = 0; + void __iomem *base = i2c->base; + + if (pmsg->len == 0) { + /* + * We still need to run through the while (..) once, so + * start at -1 and break out early from the loop + */ + xfer_len = -1; + writew(0, base + VIAI2C_REG_CDR); + } else { + writew(pmsg->buf[0] & 0xFF, base + VIAI2C_REG_CDR); + } + + if (!(pmsg->flags & I2C_M_NOSTART)) { + val = readw(base + VIAI2C_REG_CR); + val &= ~VIAI2C_CR_TX_END; + val |= VIAI2C_CR_CPU_RDY; + writew(val, base + VIAI2C_REG_CR); + } + + reinit_completion(&i2c->complete); + writew(tcr_val | pmsg->addr, base + VIAI2C_REG_TCR); + + if (pmsg->flags & I2C_M_NOSTART) { + val = readw(base + VIAI2C_REG_CR); + val |= VIAI2C_CR_CPU_RDY; + writew(val, base + VIAI2C_REG_CR); + } + + while (xfer_len < pmsg->len) { + int err; + + err = viai2c_wait_status(i2c, VIAI2C_ISR_BYTE_END); + if (err) + return err; + + xfer_len++; + + val = readw(base + VIAI2C_REG_CSR); + if (val & VIAI2C_CSR_RCV_NOT_ACK) { + dev_dbg(i2c->dev, "write RCV NACK error\n"); + return -EIO; + } + + if (pmsg->len == 0) { + val = VIAI2C_CR_TX_END | VIAI2C_CR_CPU_RDY + | VIAI2C_CR_ENABLE; + writew(val, base + VIAI2C_REG_CR); + break; + } + + if (xfer_len == pmsg->len) { + if (!last) + writew(VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR); + } else { + writew(pmsg->buf[xfer_len] & 0xFF, + base + VIAI2C_REG_CDR); + writew(VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE, + base + VIAI2C_REG_CR); + } + } + + return 0; +} + +static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg) +{ + u16 val, tcr_val = i2c->tcr; + u32 xfer_len = 0; + void __iomem *base = i2c->base; + + val = readw(base + VIAI2C_REG_CR); + val &= ~(VIAI2C_CR_TX_END | VIAI2C_CR_RX_END); + + if (!(pmsg->flags & I2C_M_NOSTART)) + val |= VIAI2C_CR_CPU_RDY; + + if (pmsg->len == 1) + val |= VIAI2C_CR_RX_END; + + writew(val, base + VIAI2C_REG_CR); + + reinit_completion(&i2c->complete); + + tcr_val |= VIAI2C_TCR_MASTER_READ | pmsg->addr; + + writew(tcr_val, base + VIAI2C_REG_TCR); + + if (pmsg->flags & I2C_M_NOSTART) { + val = readw(base + VIAI2C_REG_CR); + val |= VIAI2C_CR_CPU_RDY; + writew(val, base + VIAI2C_REG_CR); + } + + while (xfer_len < pmsg->len) { + int err; + + err = viai2c_wait_status(i2c, VIAI2C_ISR_BYTE_END); + if (err) + return err; + + pmsg->buf[xfer_len] = readw(base + VIAI2C_REG_CDR) >> 8; + xfer_len++; + + val = readw(base + VIAI2C_REG_CR) | VIAI2C_CR_CPU_RDY; + if (xfer_len == pmsg->len - 1) + val |= VIAI2C_CR_RX_END; + writew(val, base + VIAI2C_REG_CR); + } + + return 0; +} + +int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + struct i2c_msg *pmsg; + int i; + int ret = 0; + struct viai2c *i2c = i2c_get_adapdata(adap); + + for (i = 0; ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + if (!(pmsg->flags & I2C_M_NOSTART)) { + ret = viai2c_wait_bus_ready(i2c); + if (ret < 0) + return ret; + } + + if (pmsg->flags & I2C_M_RD) + ret = viai2c_read(i2c, pmsg); + else + ret = viai2c_write(i2c, pmsg, i == (num - 1)); + } + + return (ret < 0) ? ret : i; +} + +static irqreturn_t viai2c_isr(int irq, void *data) +{ + struct viai2c *i2c = data; + + /* save the status and write-clear it */ + i2c->cmd_status = readw(i2c->base + VIAI2C_REG_ISR); + writew(i2c->cmd_status, i2c->base + VIAI2C_REG_ISR); + + complete(&i2c->complete); + + return IRQ_HANDLED; +} + +int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c) +{ + int err; + int irq_flags; + struct viai2c *i2c; + struct device_node *np = pdev->dev.of_node; + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + i2c->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + + if (np) { + irq_flags = 0; + i2c->irq = irq_of_parse_and_map(np, 0); + if (!i2c->irq) + return -EINVAL; + } else { + irq_flags = IRQF_SHARED; + i2c->irq = platform_get_irq(pdev, 0); + if (i2c->irq < 0) + return i2c->irq; + } + + err = devm_request_irq(&pdev->dev, i2c->irq, viai2c_isr, + irq_flags, pdev->name, i2c); + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to request irq %i\n", i2c->irq); + + i2c->dev = &pdev->dev; + init_completion(&i2c->complete); + platform_set_drvdata(pdev, i2c); + + *pi2c = i2c; + return 0; +} diff --git a/drivers/i2c/busses/i2c-viai2c-common.h b/drivers/i2c/busses/i2c-viai2c-common.h new file mode 100644 index 000000000000..f3dcc609679e --- /dev/null +++ b/drivers/i2c/busses/i2c-viai2c-common.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __I2C_VIAI2C_COMMON_H_ +#define __I2C_VIAI2C_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* REG_CR Bit fields */ +#define VIAI2C_REG_CR 0x00 +#define VIAI2C_CR_ENABLE BIT(0) +#define VIAI2C_CR_RX_END BIT(1) +#define VIAI2C_CR_TX_END BIT(2) +#define VIAI2C_CR_END_MASK GENMASK(2, 1) +#define VIAI2C_CR_CPU_RDY BIT(3) + +/* REG_TCR Bit fields */ +#define VIAI2C_REG_TCR 0x02 +#define VIAI2C_TCR_HS_MODE BIT(13) +#define VIAI2C_TCR_MASTER_READ BIT(14) +#define VIAI2C_TCR_FAST BIT(15) + +/* REG_CSR Bit fields */ +#define VIAI2C_REG_CSR 0x04 +#define VIAI2C_CSR_RCV_NOT_ACK BIT(0) +#define VIAI2C_CSR_READY_MASK BIT(1) + +/* REG_ISR Bit fields */ +#define VIAI2C_REG_ISR 0x06 +#define VIAI2C_ISR_NACK_ADDR BIT(0) +#define VIAI2C_ISR_BYTE_END BIT(1) +#define VIAI2C_ISR_SCL_TIMEOUT BIT(2) +#define VIAI2C_ISR_MASK_ALL GENMASK(2, 0) + +/* REG_IMR Bit fields */ +#define VIAI2C_REG_IMR 0x08 +#define VIAI2C_IMR_ADDRNACK BIT(0) +#define VIAI2C_IMR_BYTE BIT(1) +#define VIAI2C_IMR_SCL_TIMEOUT BIT(2) +#define VIAI2C_IMR_ENABLE_ALL GENMASK(2, 0) + +#define VIAI2C_REG_CDR 0x0A +#define VIAI2C_REG_TR 0x0C +#define VIAI2C_REG_MCR 0x0E + +enum { + VIAI2C_PLAT_WMT = 1, +}; + +struct viai2c { + struct i2c_adapter adapter; + struct completion complete; + struct device *dev; + void __iomem *base; + struct clk *clk; + u16 tcr; + int irq; + u16 cmd_status; + u8 platform; +}; + +int viai2c_wait_bus_ready(struct viai2c *i2c); +int viai2c_wait_status(struct viai2c *i2c, u8 status); +int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num); +int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c); + +#endif diff --git a/drivers/i2c/busses/i2c-wmt-plt.c b/drivers/i2c/busses/i2c-wmt-plt.c new file mode 100644 index 000000000000..1789156a656e --- /dev/null +++ b/drivers/i2c/busses/i2c-wmt-plt.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Wondermedia I2C Master Mode Driver + * + * Copyright (C) 2012 Tony Prisk + * + * Derived from GPLv2+ licensed source: + * - Copyright (C) 2008 WonderMedia Technologies, Inc. + */ + +#include +#include +#include +#include "i2c-viai2c-common.h" + +#define WMTI2C_REG_SLAVE_CR 0x10 +#define WMTI2C_REG_SLAVE_SR 0x12 +#define WMTI2C_REG_SLAVE_ISR 0x14 +#define WMTI2C_REG_SLAVE_IMR 0x16 +#define WMTI2C_REG_SLAVE_DR 0x18 +#define WMTI2C_REG_SLAVE_TR 0x1A + +/* REG_TR */ +#define WMTI2C_SCL_TIMEOUT(x) (((x) & 0xFF) << 8) +#define WMTI2C_TR_STD 0x0064 +#define WMTI2C_TR_HS 0x0019 + +/* REG_MCR */ +#define WMTI2C_MCR_APB_96M 7 +#define WMTI2C_MCR_APB_166M 12 + +#define wmt_i2c viai2c + +static u32 wmt_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART; +} + +static const struct i2c_algorithm wmt_i2c_algo = { + .master_xfer = viai2c_xfer, + .functionality = wmt_i2c_func, +}; + +static int wmt_i2c_reset_hardware(struct wmt_i2c *i2c) +{ + int err; + void __iomem *base = i2c->base; + + err = clk_prepare_enable(i2c->clk); + if (err) { + dev_err(i2c->dev, "failed to enable clock\n"); + return err; + } + + err = clk_set_rate(i2c->clk, 20000000); + if (err) { + dev_err(i2c->dev, "failed to set clock = 20Mhz\n"); + clk_disable_unprepare(i2c->clk); + return err; + } + + writew(0, base + VIAI2C_REG_CR); + writew(WMTI2C_MCR_APB_166M, base + VIAI2C_REG_MCR); + writew(VIAI2C_ISR_MASK_ALL, base + VIAI2C_REG_ISR); + writew(VIAI2C_IMR_ENABLE_ALL, base + VIAI2C_REG_IMR); + writew(VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR); + readw(base + VIAI2C_REG_CSR); /* read clear */ + writew(VIAI2C_ISR_MASK_ALL, base + VIAI2C_REG_ISR); + + if (i2c->tcr == VIAI2C_TCR_FAST) + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_HS, + base + VIAI2C_REG_TR); + else + writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_STD, + base + VIAI2C_REG_TR); + + return 0; +} + +static int wmt_i2c_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct wmt_i2c *i2c; + struct i2c_adapter *adap; + int err; + u32 clk_rate; + + err = viai2c_init(pdev, &i2c); + if (err) + return err; + + i2c->platform = VIAI2C_PLAT_WMT; + + i2c->clk = of_clk_get(np, 0); + if (IS_ERR(i2c->clk)) { + dev_err(&pdev->dev, "unable to request clock\n"); + return PTR_ERR(i2c->clk); + } + + err = of_property_read_u32(np, "clock-frequency", &clk_rate); + if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) + i2c->tcr = VIAI2C_TCR_FAST; + + adap = &i2c->adapter; + i2c_set_adapdata(adap, i2c); + strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name)); + adap->owner = THIS_MODULE; + adap->algo = &wmt_i2c_algo; + adap->dev.parent = &pdev->dev; + adap->dev.of_node = pdev->dev.of_node; + + err = wmt_i2c_reset_hardware(i2c); + if (err) { + dev_err(&pdev->dev, "error initializing hardware\n"); + return err; + } + + return devm_i2c_add_adapter(&pdev->dev, &i2c->adapter); +} + +static const struct of_device_id wmt_i2c_dt_ids[] = { + { .compatible = "wm,wm8505-i2c" }, + { /* Sentinel */ }, +}; + +static struct platform_driver wmt_i2c_driver = { + .probe = wmt_i2c_probe, + .driver = { + .name = "wmt-i2c", + .of_match_table = wmt_i2c_dt_ids, + }, +}; + +module_platform_driver(wmt_i2c_driver); + +MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter"); +MODULE_AUTHOR("Tony Prisk "); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids); diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c deleted file mode 100644 index 3dea153c62aa..000000000000 --- a/drivers/i2c/busses/i2c-wmt.c +++ /dev/null @@ -1,431 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Wondermedia I2C Master Mode Driver - * - * Copyright (C) 2012 Tony Prisk - * - * Derived from GPLv2+ licensed source: - * - Copyright (C) 2008 WonderMedia Technologies, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WMTI2C_REG_CR 0x00 -#define WMTI2C_REG_TCR 0x02 -#define WMTI2C_REG_CSR 0x04 -#define WMTI2C_REG_ISR 0x06 -#define WMTI2C_REG_IMR 0x08 -#define WMTI2C_REG_CDR 0x0A -#define WMTI2C_REG_TR 0x0C -#define WMTI2C_REG_MCR 0x0E -#define WMTI2C_REG_SLAVE_CR 0x10 -#define WMTI2C_REG_SLAVE_SR 0x12 -#define WMTI2C_REG_SLAVE_ISR 0x14 -#define WMTI2C_REG_SLAVE_IMR 0x16 -#define WMTI2C_REG_SLAVE_DR 0x18 -#define WMTI2C_REG_SLAVE_TR 0x1A - -/* REG_CR Bit fields */ -#define WMTI2C_CR_TX_NEXT_ACK 0x0000 -#define WMTI2C_CR_ENABLE 0x0001 -#define WMTI2C_CR_TX_NEXT_NO_ACK 0x0002 -#define WMTI2C_CR_TX_END 0x0004 -#define WMTI2C_CR_CPU_RDY 0x0008 -#define WMTI2C_SLAV_MODE_SEL 0x8000 - -/* REG_TCR Bit fields */ -#define WMTI2C_TCR_STANDARD_MODE 0x0000 -#define WMTI2C_TCR_MASTER_WRITE 0x0000 -#define WMTI2C_TCR_HS_MODE 0x2000 -#define WMTI2C_TCR_MASTER_READ 0x4000 -#define WMTI2C_TCR_FAST_MODE 0x8000 -#define WMTI2C_TCR_SLAVE_ADDR_MASK 0x007F - -/* REG_ISR Bit fields */ -#define WMTI2C_ISR_NACK_ADDR 0x0001 -#define WMTI2C_ISR_BYTE_END 0x0002 -#define WMTI2C_ISR_SCL_TIMEOUT 0x0004 -#define WMTI2C_ISR_WRITE_ALL 0x0007 - -/* REG_IMR Bit fields */ -#define WMTI2C_IMR_ENABLE_ALL 0x0007 - -/* REG_CSR Bit fields */ -#define WMTI2C_CSR_RCV_NOT_ACK 0x0001 -#define WMTI2C_CSR_RCV_ACK_MASK 0x0001 -#define WMTI2C_CSR_READY_MASK 0x0002 - -/* REG_TR */ -#define WMTI2C_SCL_TIMEOUT(x) (((x) & 0xFF) << 8) -#define WMTI2C_TR_STD 0x0064 -#define WMTI2C_TR_HS 0x0019 - -/* REG_MCR */ -#define WMTI2C_MCR_APB_96M 7 -#define WMTI2C_MCR_APB_166M 12 - -#define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000)) - -struct wmt_i2c { - struct i2c_adapter adapter; - struct completion complete; - struct device *dev; - void __iomem *base; - struct clk *clk; - u16 tcr; - int irq; - u16 cmd_status; -}; - -static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c *i2c) -{ - unsigned long timeout; - void __iomem *base = i2c->base; - - timeout = jiffies + WMT_I2C_TIMEOUT; - while (!(readw(base + WMTI2C_REG_CSR) & WMTI2C_CSR_READY_MASK)) { - if (time_after(jiffies, timeout)) { - dev_warn(i2c->dev, - "timeout waiting for bus ready\n"); - return -EBUSY; - } - msleep(20); - } - - return 0; -} - -static int wmt_check_status(struct wmt_i2c *i2c) -{ - int ret = 0; - unsigned long wait_result; - - wait_result = wait_for_completion_timeout(&i2c->complete, - msecs_to_jiffies(500)); - if (!wait_result) - return -ETIMEDOUT; - - if (i2c->cmd_status & WMTI2C_ISR_NACK_ADDR) - ret = -EIO; - - if (i2c->cmd_status & WMTI2C_ISR_SCL_TIMEOUT) - ret = -ETIMEDOUT; - - return ret; -} - -static int wmt_i2c_write(struct wmt_i2c *i2c, struct i2c_msg *pmsg, - int last) -{ - u16 val, tcr_val = i2c->tcr; - int ret; - int xfer_len = 0; - void __iomem *base = i2c->base; - - if (pmsg->len == 0) { - /* - * We still need to run through the while (..) once, so - * start at -1 and break out early from the loop - */ - xfer_len = -1; - writew(0, base + WMTI2C_REG_CDR); - } else { - writew(pmsg->buf[0] & 0xFF, base + WMTI2C_REG_CDR); - } - - if (!(pmsg->flags & I2C_M_NOSTART)) { - val = readw(base + WMTI2C_REG_CR); - val &= ~WMTI2C_CR_TX_END; - val |= WMTI2C_CR_CPU_RDY; - writew(val, base + WMTI2C_REG_CR); - } - - reinit_completion(&i2c->complete); - - tcr_val |= (WMTI2C_TCR_MASTER_WRITE - | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK)); - - writew(tcr_val, base + WMTI2C_REG_TCR); - - if (pmsg->flags & I2C_M_NOSTART) { - val = readw(base + WMTI2C_REG_CR); - val |= WMTI2C_CR_CPU_RDY; - writew(val, base + WMTI2C_REG_CR); - } - - while (xfer_len < pmsg->len) { - ret = wmt_check_status(i2c); - if (ret) - return ret; - - xfer_len++; - - val = readw(base + WMTI2C_REG_CSR); - if (val & WMTI2C_CSR_RCV_NOT_ACK) { - dev_dbg(i2c->dev, "write RCV NACK error\n"); - return -EIO; - } - - if (pmsg->len == 0) { - val = WMTI2C_CR_TX_END | WMTI2C_CR_CPU_RDY - | WMTI2C_CR_ENABLE; - writew(val, base + WMTI2C_REG_CR); - break; - } - - if (xfer_len == pmsg->len) { - if (last != 1) - writew(WMTI2C_CR_ENABLE, base + WMTI2C_REG_CR); - } else { - writew(pmsg->buf[xfer_len] & 0xFF, - base + WMTI2C_REG_CDR); - writew(WMTI2C_CR_CPU_RDY | WMTI2C_CR_ENABLE, - base + WMTI2C_REG_CR); - } - } - - return 0; -} - -static int wmt_i2c_read(struct wmt_i2c *i2c, struct i2c_msg *pmsg) -{ - u16 val, tcr_val = i2c->tcr; - int ret; - u32 xfer_len = 0; - void __iomem *base = i2c->base; - - val = readw(base + WMTI2C_REG_CR); - val &= ~(WMTI2C_CR_TX_END | WMTI2C_CR_TX_NEXT_NO_ACK); - - if (!(pmsg->flags & I2C_M_NOSTART)) - val |= WMTI2C_CR_CPU_RDY; - - if (pmsg->len == 1) - val |= WMTI2C_CR_TX_NEXT_NO_ACK; - - writew(val, base + WMTI2C_REG_CR); - - reinit_completion(&i2c->complete); - - tcr_val |= WMTI2C_TCR_MASTER_READ - | (pmsg->addr & WMTI2C_TCR_SLAVE_ADDR_MASK); - - writew(tcr_val, base + WMTI2C_REG_TCR); - - if (pmsg->flags & I2C_M_NOSTART) { - val = readw(base + WMTI2C_REG_CR); - val |= WMTI2C_CR_CPU_RDY; - writew(val, base + WMTI2C_REG_CR); - } - - while (xfer_len < pmsg->len) { - ret = wmt_check_status(i2c); - if (ret) - return ret; - - pmsg->buf[xfer_len] = readw(base + WMTI2C_REG_CDR) >> 8; - xfer_len++; - - val = readw(base + WMTI2C_REG_CR) | WMTI2C_CR_CPU_RDY; - if (xfer_len == pmsg->len - 1) - val |= WMTI2C_CR_TX_NEXT_NO_ACK; - writew(val, base + WMTI2C_REG_CR); - } - - return 0; -} - -static int wmt_i2c_xfer(struct i2c_adapter *adap, - struct i2c_msg msgs[], - int num) -{ - struct i2c_msg *pmsg; - int i; - int ret = 0; - struct wmt_i2c *i2c = i2c_get_adapdata(adap); - - for (i = 0; ret >= 0 && i < num; i++) { - pmsg = &msgs[i]; - if (!(pmsg->flags & I2C_M_NOSTART)) { - ret = wmt_i2c_wait_bus_not_busy(i2c); - if (ret < 0) - return ret; - } - - if (pmsg->flags & I2C_M_RD) - ret = wmt_i2c_read(i2c, pmsg); - else - ret = wmt_i2c_write(i2c, pmsg, (i + 1) == num); - } - - return (ret < 0) ? ret : i; -} - -static u32 wmt_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART; -} - -static const struct i2c_algorithm wmt_i2c_algo = { - .master_xfer = wmt_i2c_xfer, - .functionality = wmt_i2c_func, -}; - -static irqreturn_t wmt_i2c_isr(int irq, void *data) -{ - struct wmt_i2c *i2c = data; - - /* save the status and write-clear it */ - i2c->cmd_status = readw(i2c->base + WMTI2C_REG_ISR); - writew(i2c->cmd_status, i2c->base + WMTI2C_REG_ISR); - - complete(&i2c->complete); - - return IRQ_HANDLED; -} - -int wmt_i2c_init(struct platform_device *pdev, struct wmt_i2c **pi2c) -{ - int err; - int irq_flags; - struct wmt_i2c *i2c; - struct device_node *np = pdev->dev.of_node; - - i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) - return -ENOMEM; - - i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); - if (IS_ERR(i2c->base)) - return PTR_ERR(i2c->base); - - if (np) { - irq_flags = 0; - i2c->irq = irq_of_parse_and_map(np, 0); - if (!i2c->irq) - return -EINVAL; - } else { - irq_flags = IRQF_SHARED; - i2c->irq = platform_get_irq(pdev, 0); - if (i2c->irq < 0) - return i2c->irq; - } - - err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr, - irq_flags, pdev->name, i2c); - if (err) - return dev_err_probe(&pdev->dev, err, - "failed to request irq %i\n", i2c->irq); - - i2c->dev = &pdev->dev; - init_completion(&i2c->complete); - platform_set_drvdata(pdev, i2c); - - *pi2c = i2c; - return 0; -} - -static int wmt_i2c_reset_hardware(struct wmt_i2c *i2c) -{ - int err; - void __iomem *base = i2c->base; - - err = clk_prepare_enable(i2c->clk); - if (err) { - dev_err(i2c->dev, "failed to enable clock\n"); - return err; - } - - err = clk_set_rate(i2c->clk, 20000000); - if (err) { - dev_err(i2c->dev, "failed to set clock = 20Mhz\n"); - clk_disable_unprepare(i2c->clk); - return err; - } - - writew(0, base + WMTI2C_REG_CR); - writew(WMTI2C_MCR_APB_166M, base + WMTI2C_REG_MCR); - writew(WMTI2C_ISR_WRITE_ALL, base + WMTI2C_REG_ISR); - writew(WMTI2C_IMR_ENABLE_ALL, base + WMTI2C_REG_IMR); - writew(WMTI2C_CR_ENABLE, base + WMTI2C_REG_CR); - readw(base + WMTI2C_REG_CSR); /* read clear */ - writew(WMTI2C_ISR_WRITE_ALL, base + WMTI2C_REG_ISR); - - if (i2c->tcr == WMTI2C_TCR_FAST_MODE) - writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_HS, - base + WMTI2C_REG_TR); - else - writew(WMTI2C_SCL_TIMEOUT(128) | WMTI2C_TR_STD, - base + WMTI2C_REG_TR); - - return 0; -} - -static int wmt_i2c_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct wmt_i2c *i2c; - struct i2c_adapter *adap; - int err; - u32 clk_rate; - - err = wmt_i2c_init(pdev, &i2c); - if (err) - return err; - - i2c->clk = of_clk_get(np, 0); - if (IS_ERR(i2c->clk)) { - dev_err(&pdev->dev, "unable to request clock\n"); - return PTR_ERR(i2c->clk); - } - - err = of_property_read_u32(np, "clock-frequency", &clk_rate); - if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) - i2c->tcr = WMTI2C_TCR_FAST_MODE; - - adap = &i2c->adapter; - i2c_set_adapdata(adap, i2c); - strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name)); - adap->owner = THIS_MODULE; - adap->algo = &wmt_i2c_algo; - adap->dev.parent = &pdev->dev; - adap->dev.of_node = pdev->dev.of_node; - - err = wmt_i2c_reset_hardware(i2c); - if (err) { - dev_err(&pdev->dev, "error initializing hardware\n"); - return err; - } - - return devm_i2c_add_adapter(&pdev->dev, &i2c->adapter); -} - -static const struct of_device_id wmt_i2c_dt_ids[] = { - { .compatible = "wm,wm8505-i2c" }, - { /* Sentinel */ }, -}; - -static struct platform_driver wmt_i2c_driver = { - .probe = wmt_i2c_probe, - .driver = { - .name = "wmt-i2c", - .of_match_table = wmt_i2c_dt_ids, - }, -}; - -module_platform_driver(wmt_i2c_driver); - -MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter"); -MODULE_AUTHOR("Tony Prisk "); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids); From patchwork Thu Nov 2 02:54:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740582 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28945C4332F for ; Thu, 2 Nov 2023 03:10:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233010AbjKBDKr (ORCPT ); Wed, 1 Nov 2023 23:10:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232949AbjKBDKq (ORCPT ); Wed, 1 Nov 2023 23:10:46 -0400 Received: from mx1.zhaoxin.com (MX1.ZHAOXIN.COM [210.0.225.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A6AB113 for ; Wed, 1 Nov 2023 20:10:42 -0700 (PDT) X-ASG-Debug-ID: 1698893646-086e236fed038f0002-PT6Irj Received: from ZXSHMBX3.zhaoxin.com (ZXSHMBX3.zhaoxin.com [10.28.252.165]) by mx1.zhaoxin.com with ESMTP id BMKEGRBBC7yXXbzM (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:07 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX3.zhaoxin.com (10.28.252.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:07 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 11/12] i2c: via-common: add zhaoxin platform Date: Thu, 2 Nov 2023 10:54:01 +0800 X-ASG-Orig-Subj: [PATCH v3 11/12] i2c: via-common: add zhaoxin platform Message-ID: <724d41f2ce79314cab76a2141229cc7126fb1c75.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX3.zhaoxin.com[10.28.252.165] X-Barracuda-Start-Time: 1698893647 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.35:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 4761 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116190 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org There are some differences between the design of zhaoxin i2c controller and wmt. Use VIAI2C_PLAT_WMT and VIAI2C_PLAT_ZHAOXIN to identify the two platforms. Signed-off-by: Hans Hu --- drivers/i2c/busses/i2c-viai2c-common.c | 30 +++++++++++++++++++------- drivers/i2c/busses/i2c-viai2c-common.h | 7 ++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-viai2c-common.c b/drivers/i2c/busses/i2c-viai2c-common.c index 45ac56941bee..0247865cb57a 100644 --- a/drivers/i2c/busses/i2c-viai2c-common.c +++ b/drivers/i2c/busses/i2c-viai2c-common.c @@ -15,6 +15,13 @@ int viai2c_wait_bus_ready(struct viai2c *i2c) dev_warn(i2c->dev, "timeout waiting for bus ready\n"); return -EBUSY; } + if (i2c->platform == VIAI2C_PLAT_ZHAOXIN) { + u16 tmp = ioread16(i2c->base + VIAI2C_REG_CR); + + iowrite16(tmp | VIAI2C_CR_END_MASK, + i2c->base + VIAI2C_REG_CR); + } + msleep(20); } @@ -53,7 +60,7 @@ static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, bool last) writew(pmsg->buf[0] & 0xFF, base + VIAI2C_REG_CDR); } - if (!(pmsg->flags & I2C_M_NOSTART)) { + if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) { val = readw(base + VIAI2C_REG_CR); val &= ~VIAI2C_CR_TX_END; val |= VIAI2C_CR_CPU_RDY; @@ -63,7 +70,7 @@ static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, bool last) reinit_completion(&i2c->complete); writew(tcr_val | pmsg->addr, base + VIAI2C_REG_TCR); - if (pmsg->flags & I2C_M_NOSTART) { + if (i2c->platform == VIAI2C_PLAT_WMT && pmsg->flags & I2C_M_NOSTART) { val = readw(base + VIAI2C_REG_CR); val |= VIAI2C_CR_CPU_RDY; writew(val, base + VIAI2C_REG_CR); @@ -92,8 +99,10 @@ static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, bool last) } if (xfer_len == pmsg->len) { - if (!last) + if (i2c->platform == VIAI2C_PLAT_WMT && !last) writew(VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR); + else if (i2c->platform == VIAI2C_PLAT_ZHAOXIN && last) + writeb(VIAI2C_CR_TX_END, base + VIAI2C_REG_CR); } else { writew(pmsg->buf[xfer_len] & 0xFF, base + VIAI2C_REG_CDR); @@ -105,7 +114,7 @@ static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, bool last) return 0; } -static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg) +static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg, bool first) { u16 val, tcr_val = i2c->tcr; u32 xfer_len = 0; @@ -114,7 +123,7 @@ static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg) val = readw(base + VIAI2C_REG_CR); val &= ~(VIAI2C_CR_TX_END | VIAI2C_CR_RX_END); - if (!(pmsg->flags & I2C_M_NOSTART)) + if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) val |= VIAI2C_CR_CPU_RDY; if (pmsg->len == 1) @@ -128,7 +137,8 @@ static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg) writew(tcr_val, base + VIAI2C_REG_TCR); - if (pmsg->flags & I2C_M_NOSTART) { + if ((i2c->platform == VIAI2C_PLAT_WMT && (pmsg->flags & I2C_M_NOSTART)) + || (i2c->platform == VIAI2C_PLAT_ZHAOXIN && !first)) { val = readw(base + VIAI2C_REG_CR); val |= VIAI2C_CR_CPU_RDY; writew(val, base + VIAI2C_REG_CR); @@ -162,14 +172,15 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) for (i = 0; ret >= 0 && i < num; i++) { pmsg = &msgs[i]; - if (!(pmsg->flags & I2C_M_NOSTART)) { + if (!(pmsg->flags & I2C_M_NOSTART) + && (i2c->platform == VIAI2C_PLAT_WMT)) { ret = viai2c_wait_bus_ready(i2c); if (ret < 0) return ret; } if (pmsg->flags & I2C_M_RD) - ret = viai2c_read(i2c, pmsg); + ret = viai2c_read(i2c, pmsg, i == 0); else ret = viai2c_write(i2c, pmsg, i == (num - 1)); } @@ -183,6 +194,9 @@ static irqreturn_t viai2c_isr(int irq, void *data) /* save the status and write-clear it */ i2c->cmd_status = readw(i2c->base + VIAI2C_REG_ISR); + if (!i2c->cmd_status) + return IRQ_NONE; + writew(i2c->cmd_status, i2c->base + VIAI2C_REG_ISR); complete(&i2c->complete); diff --git a/drivers/i2c/busses/i2c-viai2c-common.h b/drivers/i2c/busses/i2c-viai2c-common.h index f3dcc609679e..c1b9ccff24e8 100644 --- a/drivers/i2c/busses/i2c-viai2c-common.h +++ b/drivers/i2c/busses/i2c-viai2c-common.h @@ -50,6 +50,7 @@ enum { VIAI2C_PLAT_WMT = 1, + VIAI2C_PLAT_ZHAOXIN }; struct viai2c { @@ -62,6 +63,12 @@ struct viai2c { int irq; u16 cmd_status; u8 platform; + u8 addr; + u16 tr; + u16 mcr; + u16 csr; + u8 fstp; + u8 hrv; }; int viai2c_wait_bus_ready(struct viai2c *i2c); From patchwork Thu Nov 2 02:54:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Hu X-Patchwork-Id: 740856 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 249DEC4167D for ; Thu, 2 Nov 2023 03:10:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233169AbjKBDKt (ORCPT ); Wed, 1 Nov 2023 23:10:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44272 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233032AbjKBDKs (ORCPT ); Wed, 1 Nov 2023 23:10:48 -0400 Received: from mx1.zhaoxin.com (MX1.ZHAOXIN.COM [210.0.225.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A8A7119 for ; Wed, 1 Nov 2023 20:10:42 -0700 (PDT) X-ASG-Debug-ID: 1698893646-086e236fed038f0003-PT6Irj Received: from ZXSHMBX3.zhaoxin.com (ZXSHMBX3.zhaoxin.com [10.28.252.165]) by mx1.zhaoxin.com with ESMTP id 1kPu1UXLgT44kiCw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 02 Nov 2023 10:54:07 +0800 (CST) X-Barracuda-Envelope-From: HansHu-oc@zhaoxin.com X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 Received: from ZXBJMBX03.zhaoxin.com (10.29.252.7) by ZXSHMBX3.zhaoxin.com (10.28.252.165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:07 +0800 Received: from ml-HP-ProDesk-680-G4-MT.zhaoxin.com (10.28.66.68) by ZXBJMBX03.zhaoxin.com (10.29.252.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 2 Nov 2023 10:54:06 +0800 X-Barracuda-RBL-Trusted-Forwarder: 10.28.252.165 From: Hans Hu X-Barracuda-RBL-Trusted-Forwarder: 10.29.252.7 To: , , CC: Subject: [PATCH v3 12/12] i2c: add zhaoxin i2c controller driver Date: Thu, 2 Nov 2023 10:54:02 +0800 X-ASG-Orig-Subj: [PATCH v3 12/12] i2c: add zhaoxin i2c controller driver Message-ID: <4fe2954b3de313d5b5ade048be7ca05953d05353.1698889581.git.hanshu-oc@zhaoxin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.28.66.68] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To ZXBJMBX03.zhaoxin.com (10.29.252.7) X-Barracuda-Connect: ZXSHMBX3.zhaoxin.com[10.28.252.165] X-Barracuda-Start-Time: 1698893647 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://10.28.252.35:4443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at zhaoxin.com X-Barracuda-Scan-Msg-Size: 11059 X-Barracuda-BRTS-Status: 0 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.116190 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Add Zhaoxin I2C controller driver. It provides the access to the i2c busses, which connects to the touchpad, eeprom, I2S, etc. Zhaoxin I2C controller has two separate busses, so may accommodate up to two I2C adapters. Those adapters are listed in the ACPI namespace with the "IIC1D17" HID, and probed by a platform driver. The driver works with IRQ mode, and supports basic I2C features. Flags I2C_AQ_NO_ZERO_LEN and I2C_AQ_COMB_WRITE_THEN_READ are used to limit the unsupported access. Signed-off-by: Hans Hu --- MAINTAINERS | 8 + drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 2 + drivers/i2c/busses/i2c-zhaoxin-plt.c | 296 +++++++++++++++++++++++++++ 4 files changed, 316 insertions(+) create mode 100644 drivers/i2c/busses/i2c-zhaoxin-plt.c diff --git a/MAINTAINERS b/MAINTAINERS index 2894f0777537..a7f75579fca1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9915,6 +9915,14 @@ L: linux-i2c@vger.kernel.org F: Documentation/i2c/busses/i2c-ismt.rst F: drivers/i2c/busses/i2c-ismt.c +I2C/SMBUS ZHAOXIN DRIVER +M: Hans Hu +L: linux-i2c@vger.kernel.org +S: Maintained +W: https://www.zhaoxin.com +F: drivers/i2c/busses/i2c-viai2c-common.c +F: drivers/i2c/busses/i2c-zhaoxin.c + I2C/SMBUS STUB DRIVER M: Jean Delvare L: linux-i2c@vger.kernel.org diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 6644eebedaf3..d04f3ce64952 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -335,6 +335,16 @@ config I2C_VIAPRO if ACPI + config I2C_ZHAOXIN + tristate "Zhaoxin I2C Interface" + depends on PCI || COMPILE_TEST + help + If you say yes to this option, support will be included for the + ZHAOXIN I2C interface + + This driver can also be built as a module. If so, the module + will be called i2c-zhaoxin. + comment "ACPI drivers" config I2C_SCMI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 19262f4d30fe..4faac9dcbce0 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -29,6 +29,8 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o +i2c-zhaoxin-objs := i2c-zhaoxin-plt.o i2c-viai2c-common.o +obj-$(CONFIG_I2C_ZHAOXIN) += i2c-zhaoxin.o # Mac SMBus host controller drivers obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o diff --git a/drivers/i2c/busses/i2c-zhaoxin-plt.c b/drivers/i2c/busses/i2c-zhaoxin-plt.c new file mode 100644 index 000000000000..08d673eaa406 --- /dev/null +++ b/drivers/i2c/busses/i2c-zhaoxin-plt.c @@ -0,0 +1,296 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright(c) 2021 Shanghai Zhaoxin Semiconductor Corporation. + * All rights reserved. + */ + +#include +#include "i2c-viai2c-common.h" + +#define ZX_I2C_NAME "Zhaoxin-I2C" + +/* + * registers + */ +/* Zhaoxin specific register bit fields */ +/* REG_CR Bit fields */ +#define ZXI2C_CR_MST_RST BIT(7) +#define ZXI2C_CR_FIFO_MODE BIT(14) +/* REG_ISR/IMR Bit fields */ +#define ZXI2C_IRQ_FIFONACK BIT(4) +#define ZXI2C_IRQ_FIFOEND BIT(3) +#define ZXI2C_IRQ_MASK (VIAI2C_ISR_MASK_ALL \ + | ZXI2C_IRQ_FIFOEND \ + | ZXI2C_IRQ_FIFONACK) +/* Zhaoxin specific registers */ +#define ZXI2C_REG_CLK 0x10 +#define ZXI2C_CLK_50M BIT(0) +#define ZXI2C_REG_REV 0x11 +#define ZXI2C_REG_HCR 0x12 +#define ZXI2C_HCR_RST_FIFO GENMASK(1, 0) +#define ZXI2C_REG_HTDR 0x13 +#define ZXI2C_REG_HRDR 0x14 +#define ZXI2C_REG_HTLR 0x15 +#define ZXI2C_REG_HRLR 0x16 +#define ZXI2C_REG_HWCNTR 0x18 +#define ZXI2C_REG_HRCNTR 0x19 + +/* parameters Constants */ +#define ZXI2C_GOLD_FSTP_100K 0xF3 +#define ZXI2C_GOLD_FSTP_400K 0x38 +#define ZXI2C_GOLD_FSTP_1M 0x13 +#define ZXI2C_GOLD_FSTP_3400K 0x37 +#define ZXI2C_HS_MASTER_CODE (0x08 << 8) +#define ZXI2C_FIFO_SIZE 32 + +/* Structure definition */ +#define zxi2c viai2c + +static int zxi2c_fifo_xfer(struct zxi2c *i2c, struct i2c_msg *msg) +{ + u16 xfered_len = 0; + u16 byte_left = msg->len; + u16 tcr_val = i2c->tcr; + void __iomem *base = i2c->base; + bool read = !!(msg->flags & I2C_M_RD); + + while (byte_left) { + u16 i; + u8 tmp; + int error; + u16 xfer_len = min_t(u16, byte_left, ZXI2C_FIFO_SIZE); + + byte_left -= xfer_len; + + /* reset fifo buffer */ + tmp = ioread8(base + ZXI2C_REG_HCR); + iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR); + + /* set xfer len */ + if (read) { + iowrite8(xfer_len - 1, base + ZXI2C_REG_HRLR); + } else { + iowrite8(xfer_len - 1, base + ZXI2C_REG_HTLR); + /* set write data */ + for (i = 0; i < xfer_len; i++) + iowrite8(msg->buf[xfered_len + i], + base + ZXI2C_REG_HTDR); + } + + /* prepare to stop transmission */ + if (i2c->hrv && !byte_left) { + tmp = ioread8(i2c->base + VIAI2C_REG_CR); + tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END; + iowrite8(tmp, base + VIAI2C_REG_CR); + } + + reinit_completion(&i2c->complete); + + if (xfered_len) { + /* continue transmission */ + tmp = ioread8(i2c->base + VIAI2C_REG_CR); + iowrite8(tmp |= VIAI2C_CR_CPU_RDY, + i2c->base + VIAI2C_REG_CR); + } else { + /* start transmission */ + tcr_val |= (read ? VIAI2C_TCR_MASTER_READ : 0); + writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR); + } + + error = viai2c_wait_status(i2c, ZXI2C_IRQ_FIFOEND); + if (error) + return error; + + /* get the received data */ + if (read) + for (i = 0; i < xfer_len; i++) + msg->buf[xfered_len + i] = + ioread8(base + ZXI2C_REG_HRDR); + + xfered_len += xfer_len; + } + + return 1; +} + +static int zxi2c_master_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + u8 tmp; + int ret; + struct zxi2c *i2c = (struct zxi2c *)i2c_get_adapdata(adap); + + ret = viai2c_wait_bus_ready(i2c); + if (ret) + return ret; + + tmp = ioread8(i2c->base + VIAI2C_REG_CR); + tmp &= ~(VIAI2C_CR_RX_END | VIAI2C_CR_TX_END); + + if (num == 1 && msgs->len >= 2 && + (i2c->hrv || msgs->len <= ZXI2C_FIFO_SIZE)) { + /* enable fifo mode */ + iowrite16(ZXI2C_CR_FIFO_MODE | tmp, i2c->base + VIAI2C_REG_CR); + /* clear irq status */ + iowrite8(ZXI2C_IRQ_MASK, i2c->base + VIAI2C_REG_ISR); + /* enable fifo irq */ + iowrite8(VIAI2C_ISR_NACK_ADDR | ZXI2C_IRQ_FIFOEND, + i2c->base + VIAI2C_REG_IMR); + + ret = zxi2c_fifo_xfer(i2c, msgs); + } else { + /* enable byte mode */ + iowrite16(tmp, i2c->base + VIAI2C_REG_CR); + /* clear irq status */ + iowrite8(ZXI2C_IRQ_MASK, i2c->base + VIAI2C_REG_ISR); + /* enable byte irq */ + iowrite8(VIAI2C_ISR_NACK_ADDR | VIAI2C_IMR_BYTE, + i2c->base + VIAI2C_REG_IMR); + + ret = viai2c_xfer(adap, msgs, num); + if (ret < 0) + iowrite16(tmp | VIAI2C_CR_END_MASK, + i2c->base + VIAI2C_REG_CR); + /* make sure the state machine is stopped */ + usleep_range(1, 2); + } + /* dis interrupt */ + iowrite8(0, i2c->base + VIAI2C_REG_IMR); + + return ret; +} + +static u32 zxi2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm zxi2c_algorithm = { + .master_xfer = zxi2c_master_xfer, + .functionality = zxi2c_func, +}; + +static const struct i2c_adapter_quirks zxi2c_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN | I2C_AQ_COMB_WRITE_THEN_READ, +}; + +static const u32 zxi2c_speed_params_table[][3] = { + /* speed, ZXI2C_TCR, ZXI2C_FSTP */ + { I2C_MAX_STANDARD_MODE_FREQ, 0, ZXI2C_GOLD_FSTP_100K }, + { I2C_MAX_FAST_MODE_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_400K }, + { I2C_MAX_FAST_MODE_PLUS_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_1M }, + { I2C_MAX_HIGH_SPEED_MODE_FREQ, VIAI2C_TCR_HS_MODE | VIAI2C_TCR_FAST, + ZXI2C_GOLD_FSTP_3400K }, +}; + +static void zxi2c_set_bus_speed(struct zxi2c *i2c) +{ + iowrite16(i2c->tr, i2c->base + VIAI2C_REG_TR); + iowrite8(ZXI2C_CLK_50M, i2c->base + ZXI2C_REG_CLK); + iowrite16(i2c->mcr, i2c->base + VIAI2C_REG_MCR); +} + +static void zxi2c_get_bus_speed(struct zxi2c *i2c) +{ + u8 i, count; + u8 fstp; + const u32 *params; + u32 acpi_speed = i2c_acpi_find_bus_speed(i2c->dev); + + count = ARRAY_SIZE(zxi2c_speed_params_table); + for (i = 0; i < count; i++) + if (acpi_speed == zxi2c_speed_params_table[i][0]) + break; + /* if not found, use 400k as default */ + i = i < count ? i : 1; + + params = zxi2c_speed_params_table[i]; + fstp = ioread8(i2c->base + VIAI2C_REG_TR); + if (abs(fstp - params[2]) > 0x10) { + /* + * if BIOS setting value far from golden value, + * use golden value and warn user + */ + dev_warn(i2c->dev, "speed:%d, fstp:0x%x, golden:0x%x\n", + params[0], fstp, params[2]); + i2c->tr = params[2] | 0xff00; + } else { + i2c->tr = fstp | 0xff00; + } + + i2c->tcr = params[1]; + i2c->mcr = ioread16(i2c->base + VIAI2C_REG_MCR); + /* for Hs-mode, use 0000 1000 as master code */ + if (params[0] == I2C_MAX_HIGH_SPEED_MODE_FREQ) + i2c->mcr |= ZXI2C_HS_MASTER_CODE; + + dev_info(i2c->dev, "speed mode is %s\n", + i2c_freq_mode_string(params[0])); +} + +static int zxi2c_probe(struct platform_device *pdev) +{ + int error; + struct zxi2c *i2c; + struct pci_dev *pci; + struct i2c_adapter *adap; + + error = viai2c_init(pdev, &i2c); + if (error) + return error; + + zxi2c_get_bus_speed(i2c); + zxi2c_set_bus_speed(i2c); + + i2c->platform = VIAI2C_PLAT_ZHAOXIN; + i2c->hrv = ioread8(i2c->base + ZXI2C_REG_REV); + + adap = &i2c->adapter; + adap->owner = THIS_MODULE; + adap->algo = &zxi2c_algorithm; + adap->retries = 2; + adap->quirks = &zxi2c_quirks; + adap->dev.parent = &pdev->dev; + ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); + pci = to_pci_dev(pdev->dev.parent); + snprintf(adap->name, sizeof(adap->name), "%s-%s-%s", + ZX_I2C_NAME, dev_name(&pci->dev), dev_name(i2c->dev)); + i2c_set_adapdata(adap, i2c); + + return devm_i2c_add_adapter(&pdev->dev, adap); +} + +static int zxi2c_resume(struct device *dev) +{ + struct zxi2c *i2c = dev_get_drvdata(dev); + + iowrite8(ZXI2C_CR_MST_RST, i2c->base + VIAI2C_REG_CR); + zxi2c_set_bus_speed(i2c); + + return 0; +} + +static const struct dev_pm_ops zxi2c_pm = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, zxi2c_resume) +}; + +static const struct acpi_device_id zxi2c_acpi_match[] = { + {"IIC1D17", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, zxi2c_acpi_match); + +static struct platform_driver zxi2c_driver = { + .probe = zxi2c_probe, + .driver = { + .name = ZX_I2C_NAME, + .acpi_match_table = ACPI_PTR(zxi2c_acpi_match), + .pm = &zxi2c_pm, + }, +}; + +module_platform_driver(zxi2c_driver); + +MODULE_AUTHOR("HansHu@zhaoxin.com"); +MODULE_DESCRIPTION("Shanghai Zhaoxin IIC driver"); +MODULE_LICENSE("GPL");