From patchwork Fri Nov 29 09:22:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biwen Li X-Patchwork-Id: 1202424 X-Patchwork-Delegate: patchwork@peda.user.lysator.liu.se Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47PTZ42ZpZz9sR7 for ; Fri, 29 Nov 2019 20:22:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726651AbfK2JWv (ORCPT ); Fri, 29 Nov 2019 04:22:51 -0500 Received: from inva020.nxp.com ([92.121.34.13]:55190 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725892AbfK2JWv (ORCPT ); Fri, 29 Nov 2019 04:22:51 -0500 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 40F9C1A0407; Fri, 29 Nov 2019 10:22:49 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 81E491A03FE; Fri, 29 Nov 2019 10:22:45 +0100 (CET) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 8DAA2402A7; Fri, 29 Nov 2019 17:22:40 +0800 (SGT) From: Biwen Li To: peda@axentia.se, leoyang.li@nxp.com, robh+dt@kernel.org, mark.rutland@arm.com Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Biwen Li Subject: [v6,1/3] dt-bindings: i2c: support property idle-state Date: Fri, 29 Nov 2019 17:22:20 +0800 Message-Id: <20191129092222.2706-1-biwen.li@nxp.com> X-Mailer: git-send-email 2.17.1 X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org This supports property idle-state Signed-off-by: Biwen Li --- Change in v6: - none Change in v5: - none Change in v4: - none Change in v3: - update subject and description - add some information for property idle-state Change in v2: - update subject and description - add property idle-state Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt index 30ac6a60f041..7abda506b828 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt @@ -25,6 +25,8 @@ Required Properties: Optional Properties: - reset-gpios: Reference to the GPIO connected to the reset input. + - idle-state: if present, overrides i2c-mux-idle-disconnect, + Please refer to Documentation/devicetree/bindings/mux/mux-controller.txt - i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all children in idle state. This is necessary for example, if there are several multiplexers on the bus and the devices behind them use same I2C addresses. From patchwork Fri Nov 29 09:22:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biwen Li X-Patchwork-Id: 1202426 X-Patchwork-Delegate: patchwork@peda.user.lysator.liu.se Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47PTZD0Q1Yz9sRK for ; Fri, 29 Nov 2019 20:23:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726805AbfK2JWw (ORCPT ); Fri, 29 Nov 2019 04:22:52 -0500 Received: from inva021.nxp.com ([92.121.34.21]:41938 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726609AbfK2JWw (ORCPT ); Fri, 29 Nov 2019 04:22:52 -0500 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 5779C200346; Fri, 29 Nov 2019 10:22:50 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 68A292002AE; Fri, 29 Nov 2019 10:22:46 +0100 (CET) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 7E0D0402DB; Fri, 29 Nov 2019 17:22:41 +0800 (SGT) From: Biwen Li To: peda@axentia.se, leoyang.li@nxp.com, robh+dt@kernel.org, mark.rutland@arm.com Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Biwen Li Subject: [v6,2/3] i2c: mux: pca954x: support property idle-state Date: Fri, 29 Nov 2019 17:22:21 +0800 Message-Id: <20191129092222.2706-2-biwen.li@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191129092222.2706-1-biwen.li@nxp.com> References: <20191129092222.2706-1-biwen.li@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org This supports property idle-state,if present, overrides i2c-mux-idle-disconnect. My use cases: - Use the property idle-state to fix an errata on LS2085ARDB and LS2088ARDB. - Errata id: E-00013(board LS2085ARDB and LS2088ARDB revision on Rev.B, Rev.C and Rev.D). - About E-00013: - Description: I2C1 and I2C3 buses are missing pull-up. - Impact: When the PCA954x device is tri-stated, the I2C bus will float. This makes the I2C bus and its associated downstream devices inaccessible. - Hardware fix: Populate resistors R189 and R190 for I2C1 and resistors R228 and R229 for I2C3. - Software fix: Remove the tri-state option from the PCA954x driver(PCA954x always on enable status, specify a channel zero in dts to fix the errata E-00013). Tested-by: Ioana Ciornei Signed-off-by: Biwen Li --- Change in v6: - adjust log Change in v5: - add extra precaution for pca954x_init Change in v4: - rename function pca954x_calculate_chan -> pca954x_regval Change in v3: - update subject and description - add a helper function pca954x_calculate_chan() Change in v2: - update subject and description - add property idle-state drivers/i2c/muxes/i2c-mux-pca954x.c | 69 +++++++++++++++++++---------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index cd8753b29a63..6577ec873f59 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -87,7 +87,7 @@ struct pca954x { u8 last_chan; /* last register value */ /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */ - s8 idle_state; + s32 idle_state; struct i2c_client *client; @@ -237,20 +237,23 @@ static int pca954x_reg_write(struct i2c_adapter *adap, I2C_SMBUS_BYTE, &dummy); } +static u8 pca954x_regval(struct pca954x *data, u8 chan) +{ + /* We make switches look like muxes, not sure how to be smarter. */ + if (data->chip->muxtype == pca954x_ismux) + return chan | data->chip->enable; + else + return 1 << chan; +} + static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) { struct pca954x *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; - const struct chip_desc *chip = data->chip; u8 regval; int ret = 0; - /* we make switches look like muxes, not sure how to be smarter */ - if (chip->muxtype == pca954x_ismux) - regval = chan | chip->enable; - else - regval = 1 << chan; - + regval = pca954x_regval(data, chan); /* Only select the channel if its different from the last channel */ if (data->last_chan != regval) { ret = pca954x_reg_write(muxc->parent, client, regval); @@ -264,7 +267,7 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) { struct pca954x *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; - s8 idle_state; + s32 idle_state; idle_state = READ_ONCE(data->idle_state); if (idle_state >= 0) @@ -410,6 +413,22 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc) i2c_mux_del_adapters(muxc); } +static int pca954x_init(struct i2c_client *client, struct pca954x *data) +{ + int ret; + if (data->idle_state >= 0) { + data->last_chan = pca954x_regval(data, data->idle_state); + } else { + /* Disconnect multiplexer */ + data->last_chan = 0; + } + ret = i2c_smbus_write_byte(client, data->last_chan); + if (ret < 0) + data->last_chan = 0; + + return ret; +} + /* * I2C init/probing/exit functions */ @@ -419,7 +438,6 @@ static int pca954x_probe(struct i2c_client *client, struct i2c_adapter *adap = client->adapter; struct device *dev = &client->dev; struct device_node *np = dev->of_node; - bool idle_disconnect_dt; struct gpio_desc *gpio; struct i2c_mux_core *muxc; struct pca954x *data; @@ -470,23 +488,24 @@ static int pca954x_probe(struct i2c_client *client, } } - /* Write the mux register at addr to verify + data->idle_state = MUX_IDLE_AS_IS; + if (of_property_read_u32(np, "idle-state", &data->idle_state)) { + if (np && of_property_read_bool(np, "i2c-mux-idle-disconnect")) + data->idle_state = MUX_IDLE_DISCONNECT; + } + + /* + * Write the mux register at addr to verify * that the mux is in fact present. This also - * initializes the mux to disconnected state. + * initializes the mux to a channel + * or disconnected state. */ - if (i2c_smbus_write_byte(client, 0) < 0) { + ret = pca954x_init(client, data); + if (ret < 0) { dev_warn(dev, "probe failed\n"); return -ENODEV; } - data->last_chan = 0; /* force the first selection */ - data->idle_state = MUX_IDLE_AS_IS; - - idle_disconnect_dt = np && - of_property_read_bool(np, "i2c-mux-idle-disconnect"); - if (idle_disconnect_dt) - data->idle_state = MUX_IDLE_DISCONNECT; - ret = pca954x_irq_setup(muxc); if (ret) goto fail_cleanup; @@ -538,9 +557,13 @@ static int pca954x_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct i2c_mux_core *muxc = i2c_get_clientdata(client); struct pca954x *data = i2c_mux_priv(muxc); + int ret; - data->last_chan = 0; - return i2c_smbus_write_byte(client, 0); + ret = pca954x_init(client, data); + if (ret < 0) + dev_err(&client->dev, "failed to verify the mux, the mux maybe not present in fact\n"); + + return ret; } #endif From patchwork Fri Nov 29 09:22:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biwen Li X-Patchwork-Id: 1202425 X-Patchwork-Delegate: patchwork@peda.user.lysator.liu.se Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47PTZC4vZ1z9sR7 for ; Fri, 29 Nov 2019 20:22:59 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726832AbfK2JWy (ORCPT ); Fri, 29 Nov 2019 04:22:54 -0500 Received: from inva020.nxp.com ([92.121.34.13]:55230 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725892AbfK2JWw (ORCPT ); Fri, 29 Nov 2019 04:22:52 -0500 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 1A5DE1A03FE; Fri, 29 Nov 2019 10:22:51 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 5B2981A0D2B; Fri, 29 Nov 2019 10:22:47 +0100 (CET) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 675A0402DE; Fri, 29 Nov 2019 17:22:42 +0800 (SGT) From: Biwen Li To: peda@axentia.se, leoyang.li@nxp.com, robh+dt@kernel.org, mark.rutland@arm.com Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Biwen Li Subject: [v6,3/3] arm64: dts: fsl-ls208xa-rdb: fix an errata E-00013 Date: Fri, 29 Nov 2019 17:22:22 +0800 Message-Id: <20191129092222.2706-3-biwen.li@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191129092222.2706-1-biwen.li@nxp.com> References: <20191129092222.2706-1-biwen.li@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Specify a channel zero in idle state to avoid enterring tri-stated state for PCA9547. About E-00013: - Description: I2C1 and I2C3 buses are missing pull-up. - Impact: When the PCA954x device is tri-stated, the I2C bus will float. This makes the I2C bus and its associated downstream devices inaccessible. - Hardware fix: Populate resistors R189 and R190 for I2C1 and resistors R228 and R229 for I2C3. - Software fix: Remove the tri-state option from the PCA954x driver(PCA954x always on enable status, specify a channel zero in dts to fix the errata E-00013). Signed-off-by: Biwen Li --- Change in v6: - none Change in v5: - specify a channel zero when pca9547 in idle state. arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi index 6fd7f63085c9..412f1bc0db5f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi @@ -49,6 +49,7 @@ reg = <0x75>; #address-cells = <1>; #size-cells = <0>; + idle-state = <0>; i2c@1 { #address-cells = <1>; #size-cells = <0>;