From patchwork Tue Sep 13 15:53:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martyn Welch X-Patchwork-Id: 605965 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 322C2C6FA82 for ; Tue, 13 Sep 2022 17:05:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232316AbiIMRFL (ORCPT ); Tue, 13 Sep 2022 13:05:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232010AbiIMREs (ORCPT ); Tue, 13 Sep 2022 13:04:48 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF930101CC; Tue, 13 Sep 2022 08:54:38 -0700 (PDT) Received: from pan.home (unknown [IPv6:2a00:23c6:c311:3401:dd1a:56ef:ffd9:f71c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: martyn) by madras.collabora.co.uk (Postfix) with ESMTPSA id 477ED6601F8A; Tue, 13 Sep 2022 16:54:02 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.co.uk; s=mail; t=1663084442; bh=sdbwrq+7bQ+B1i6ZcK2joAyKTUYFXv+CHRUaPv0/yxA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iLgSG4f6SN7JI9tQ0EOuSosVFUWy+QlyqPJlCWtPeOW5qJeDcQN5fpMFCVJKVpcMR l5gZtlB/LYUC2wfzl/Q8Y/YRrs4rKNtJi0mYktNs+CaSNBTBR3FzgyLtM3BXoTsiQc hkHeVldyZRBr1JdKe3ZsCDz9UlvxXbQjO0FYR4bkNn/L1T40Xlu/mJxw/dHYzRAypz JCXuIKWIihTgo81COGPQQEjuZDELF5Mwytkn0t1BrOCrhY/ih/KPRc4NfP6qotYx8u LNscsegVzYaSXoeMS2Ymf98e23A/qtWNj8UAsQaeX82vM5dRoeLpSffR6lvLcb3oOE 981nPfv5nxaQA== From: Martyn Welch To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski Cc: Martyn Welch , Krzysztof Kozlowski , Krzysztof Kozlowski , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/5] dt-bindings: gpio: pca95xx: add entry for pcal6534 and PI4IOE5V6534Q Date: Tue, 13 Sep 2022 16:53:45 +0100 Message-Id: <20220913155348.38716-2-martyn.welch@collabora.co.uk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220913155348.38716-1-martyn.welch@collabora.co.uk> References: <20220913155348.38716-1-martyn.welch@collabora.co.uk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Martyn Welch The NXP PCAL6534 is a 34-bit I2C I/O expander similar to the PCAL6524. The Diodes PI4IOE5V6534Q is a functionally identical chip provided by Diodes Inc. Signed-off-by: Martyn Welch Reviewed-by: Krzysztof Kozlowski Reviewed-by: Linus Walleij --- Changes in v2: - Enumerate pi4ioe5v6534q as requiring pcal6534 fallback Changes in v3: - Corrected indentation Changes in v4: - Further indentation corrections .../bindings/gpio/gpio-pca95xx.yaml | 98 ++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml index 977b14db09b0..382d04900032 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml @@ -15,52 +15,58 @@ description: |+ properties: compatible: - enum: - - exar,xra1202 - - maxim,max7310 - - maxim,max7312 - - maxim,max7313 - - maxim,max7315 - - maxim,max7319 - - maxim,max7320 - - maxim,max7321 - - maxim,max7322 - - maxim,max7323 - - maxim,max7324 - - maxim,max7325 - - maxim,max7326 - - maxim,max7327 - - nxp,pca6408 - - nxp,pca6416 - - nxp,pca9505 - - nxp,pca9506 - - nxp,pca9534 - - nxp,pca9535 - - nxp,pca9536 - - nxp,pca9537 - - nxp,pca9538 - - nxp,pca9539 - - nxp,pca9554 - - nxp,pca9555 - - nxp,pca9556 - - nxp,pca9557 - - nxp,pca9574 - - nxp,pca9575 - - nxp,pca9698 - - nxp,pcal6416 - - nxp,pcal6524 - - nxp,pcal9535 - - nxp,pcal9554b - - nxp,pcal9555a - - onnn,cat9554 - - onnn,pca9654 - - ti,pca6107 - - ti,pca9536 - - ti,tca6408 - - ti,tca6416 - - ti,tca6424 - - ti,tca9539 - - ti,tca9554 + oneOf: + - items: + - const: diodes,pi4ioe5v6534q + - const: nxp,pcal6534 + - items: + - enum: + - exar,xra1202 + - maxim,max7310 + - maxim,max7312 + - maxim,max7313 + - maxim,max7315 + - maxim,max7319 + - maxim,max7320 + - maxim,max7321 + - maxim,max7322 + - maxim,max7323 + - maxim,max7324 + - maxim,max7325 + - maxim,max7326 + - maxim,max7327 + - nxp,pca6408 + - nxp,pca6416 + - nxp,pca9505 + - nxp,pca9506 + - nxp,pca9534 + - nxp,pca9535 + - nxp,pca9536 + - nxp,pca9537 + - nxp,pca9538 + - nxp,pca9539 + - nxp,pca9554 + - nxp,pca9555 + - nxp,pca9556 + - nxp,pca9557 + - nxp,pca9574 + - nxp,pca9575 + - nxp,pca9698 + - nxp,pcal6416 + - nxp,pcal6524 + - nxp,pcal6534 + - nxp,pcal9535 + - nxp,pcal9554b + - nxp,pcal9555a + - onnn,cat9554 + - onnn,pca9654 + - ti,pca6107 + - ti,pca9536 + - ti,tca6408 + - ti,tca6416 + - ti,tca6424 + - ti,tca9539 + - ti,tca9554 reg: maxItems: 1 From patchwork Tue Sep 13 15:53:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martyn Welch X-Patchwork-Id: 605966 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 39382C6FA8A for ; Tue, 13 Sep 2022 17:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232356AbiIMRES (ORCPT ); Tue, 13 Sep 2022 13:04:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232447AbiIMRDq (ORCPT ); Tue, 13 Sep 2022 13:03:46 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0E2126AD2; Tue, 13 Sep 2022 08:54:09 -0700 (PDT) Received: from pan.home (unknown [IPv6:2a00:23c6:c311:3401:dd1a:56ef:ffd9:f71c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: martyn) by madras.collabora.co.uk (Postfix) with ESMTPSA id 23E5D6601FF3; Tue, 13 Sep 2022 16:54:03 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.co.uk; s=mail; t=1663084443; bh=3e6b22rHkUzjWLLTQerWtZ77OLwILLbLSRqG/UmLEDE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a72dT8sDgdfudkZslg1wJixax9/PZ6cFlqAK5Zheo92WSIUwoZkkvv7n85ECDq3bI bR6l8JBGBneBwE/K8774izYclexqeZxwC7gt4q+nxoAOuSXpUMIL92Z74SMYUJmltj nHp9wauNAK/nsjOW7hmAPMdDcLgW8YozE9ROnWza8zlLTU1hnQ6t1eo5Rw7Bb7DzHe OqRX20e/8Xwp4/BICHFRZaEI80DlouvJwcuFa8ylK48qrRBAuruGWHdbw70mievOxF EgB8Z0zftEXkH6Sp/5Sq36qXCiKVDZkc35VLjBg4a8d3CBnz2NVdVn6dE/xdU+5GEl o9jlQmKkUEDZQ== From: Martyn Welch To: Linus Walleij , Bartosz Golaszewski Cc: Martyn Welch , Andy Shevchenko , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 3/5] gpio: pca953x: Fix pca953x_gpio_set_pull_up_down() Date: Tue, 13 Sep 2022 16:53:46 +0100 Message-Id: <20220913155348.38716-3-martyn.welch@collabora.co.uk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220913155348.38716-1-martyn.welch@collabora.co.uk> References: <20220913155348.38716-1-martyn.welch@collabora.co.uk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Martyn Welch A previous fix, commit dc87f6dd058a ("gpio: pca953x: Fix pca953x_gpio_set_config"), identified that pinconf_to_config_param() needed to be used to isolate the config_param from the pinconf in pca953x_gpio_set_config(). This fix however did not consider that this would also be needed in pca953x_gpio_set_pull_up_down() to which it passes this config. Perform a similar call in pca953x_gpio_set_pull_up_down() to isolate the configuration parameter there as well, rather than passing it from pca953x_gpio_set_config() as the configuration argument may also be needed in pca953x_gpio_set_pull_up_down() at a later date. Signed-off-by: Martyn Welch Acked-by: Linus Walleij Reviewed-by: Andy Shevchenko --- Changes in v2: - Re-order enum before u8 Changes in v3: - None Changes in v4: - None drivers/gpio/gpio-pca953x.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index ecd7d169470b..62367c9d6e99 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -548,6 +548,8 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, unsigned int offset, unsigned long config) { + enum pin_config_param param = pinconf_to_config_param(config); + u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset); u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset); u8 bit = BIT(offset % BANK_SZ); @@ -563,9 +565,9 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, mutex_lock(&chip->i2c_lock); /* Configure pull-up/pull-down */ - if (config == PIN_CONFIG_BIAS_PULL_UP) + if (param == PIN_CONFIG_BIAS_PULL_UP) ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, bit); - else if (config == PIN_CONFIG_BIAS_PULL_DOWN) + else if (param == PIN_CONFIG_BIAS_PULL_DOWN) ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, 0); else ret = 0; @@ -573,7 +575,7 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, goto exit; /* Disable/Enable pull-up/pull-down */ - if (config == PIN_CONFIG_BIAS_DISABLE) + if (param == PIN_CONFIG_BIAS_DISABLE) ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); else ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); From patchwork Tue Sep 13 15:53:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martyn Welch X-Patchwork-Id: 605590 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 37BF5ECAAD8 for ; Tue, 13 Sep 2022 17:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232507AbiIMRKw (ORCPT ); Tue, 13 Sep 2022 13:10:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231834AbiIMRK2 (ORCPT ); Tue, 13 Sep 2022 13:10:28 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F01093513; Tue, 13 Sep 2022 08:59:22 -0700 (PDT) Received: from pan.home (unknown [IPv6:2a00:23c6:c311:3401:dd1a:56ef:ffd9:f71c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: martyn) by madras.collabora.co.uk (Postfix) with ESMTPSA id E7FFB6601FFD; Tue, 13 Sep 2022 16:54:03 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.co.uk; s=mail; t=1663084444; bh=Cf57MQ0s0WfHM3ZV++Oefg0CZSnt/NVUvG5R/Wbna0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Khgx52dmLTLTmBSuJP8BK4IMJHpR0RFyJ/0pKj40ATrJjKXh2Wm25cCq6x8DfA1bn 8Objuoy2QbVAhRwO8E8dk0FUrlpTnBDLW6zOFOEZyNi6reneyldLd4yUkm6h1ZJyJp J+fj0CcOXKWGeqyxmg+0Ubjxot0LgBpvGZYsaNcjrIbaLPhqxyyquqb/+5T2YIg+o5 AE8NW/sQnd4EgNoE081PZxlEwpnC6lVoyVwnB8WFxpfIA7VUtg40uSbJy+I+tmyaqY 0X6ZgqpNJKo8NqtQNYtOWi44SHU7befW6apWQ93smHh70JxTvAUKm6V56DhAFn+/3/ eRCTGmHwmxS/A== From: Martyn Welch To: Linus Walleij , Bartosz Golaszewski Cc: Martyn Welch , Andy Shevchenko , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 4/5] gpio: pca953x: Swap if statements to save later complexity Date: Tue, 13 Sep 2022 16:53:47 +0100 Message-Id: <20220913155348.38716-4-martyn.welch@collabora.co.uk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220913155348.38716-1-martyn.welch@collabora.co.uk> References: <20220913155348.38716-1-martyn.welch@collabora.co.uk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Martyn Welch A later patch in the series adds support for a further chip type that shares some similarity with the PCA953X_TYPE. In order to keep the logic simple, swap over the if and else portions where checks are made against PCA953X_TYPE and instead check for PCA957X_TYPE. Signed-off-by: Martyn Welch Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko --- Changes in v2: - None Changes in v3: - None Changes in v4: - None drivers/gpio/gpio-pca953x.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 62367c9d6e99..1e8f038734e0 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -293,13 +293,13 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg) struct pca953x_chip *chip = dev_get_drvdata(dev); u32 bank; - if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) { - bank = PCA953x_BANK_INPUT | PCA953x_BANK_OUTPUT | - PCA953x_BANK_POLARITY | PCA953x_BANK_CONFIG; - } else { + if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { bank = PCA957x_BANK_INPUT | PCA957x_BANK_OUTPUT | PCA957x_BANK_POLARITY | PCA957x_BANK_CONFIG | PCA957x_BANK_BUSHOLD; + } else { + bank = PCA953x_BANK_INPUT | PCA953x_BANK_OUTPUT | + PCA953x_BANK_POLARITY | PCA953x_BANK_CONFIG; } if (chip->driver_data & PCA_PCAL) { @@ -316,12 +316,12 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg) struct pca953x_chip *chip = dev_get_drvdata(dev); u32 bank; - if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) { - bank = PCA953x_BANK_OUTPUT | PCA953x_BANK_POLARITY | - PCA953x_BANK_CONFIG; - } else { + if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { bank = PCA957x_BANK_OUTPUT | PCA957x_BANK_POLARITY | PCA957x_BANK_CONFIG | PCA957x_BANK_BUSHOLD; + } else { + bank = PCA953x_BANK_OUTPUT | PCA953x_BANK_POLARITY | + PCA953x_BANK_CONFIG; } if (chip->driver_data & PCA_PCAL) @@ -336,10 +336,10 @@ static bool pca953x_volatile_register(struct device *dev, unsigned int reg) struct pca953x_chip *chip = dev_get_drvdata(dev); u32 bank; - if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) - bank = PCA953x_BANK_INPUT; - else + if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) bank = PCA957x_BANK_INPUT; + else + bank = PCA953x_BANK_INPUT; if (chip->driver_data & PCA_PCAL) bank |= PCAL9xxx_BANK_IRQ_STAT; @@ -1070,13 +1070,12 @@ static int pca953x_probe(struct i2c_client *client, /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ - - if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) { - chip->regs = &pca953x_regs; - ret = device_pca95xx_init(chip, invert); - } else { + if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { chip->regs = &pca957x_regs; ret = device_pca957x_init(chip, invert); + } else { + chip->regs = &pca953x_regs; + ret = device_pca95xx_init(chip, invert); } if (ret) goto err_exit; From patchwork Tue Sep 13 15:53:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martyn Welch X-Patchwork-Id: 605591 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 537FDECAAD8 for ; Tue, 13 Sep 2022 17:04:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230048AbiIMREe (ORCPT ); Tue, 13 Sep 2022 13:04:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231305AbiIMRDx (ORCPT ); Tue, 13 Sep 2022 13:03:53 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2ED1C4813; Tue, 13 Sep 2022 08:54:11 -0700 (PDT) Received: from pan.home (unknown [IPv6:2a00:23c6:c311:3401:dd1a:56ef:ffd9:f71c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: martyn) by madras.collabora.co.uk (Postfix) with ESMTPSA id 0254C6601F95; Tue, 13 Sep 2022 16:54:04 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.co.uk; s=mail; t=1663084445; bh=TMj9wyC9epifSEOGvjGKHId/ygyOFjXd9dKUWfS7N2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NnSovjGldwPkLsOVKmFqReU6kmm8g4cgYf9WpTaG/Y7QxXsON4SXm8qL+t3h5hzQ2 wK3W/sPbPfoRLq6FCDYuwF1K+iMPYt/563Thf8L3sQjbckGIW7VZlI1HFHsHSmG3p2 74U4Z6Cb3QJ9iKuAMiGE2rddwLvgsRqcpa+BVfL2rSgLpf5ApRc96ACuInkdssK9/T +Ba3GgpQSsXO0NhD6hhjVTW9wr3Tifw2U2yaFAoYEdS2BM0wQfmp9qNvMdlHaaWSk8 98pAnlybATRhMM1LN7poYImdwlBQVnYgQ7ugJUe9e3T8OZwZTws3Gcrux5dvavcss0 OtAzSYeRYaTOw== From: Martyn Welch To: Linus Walleij , Bartosz Golaszewski Cc: Martyn Welch , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 5/5] gpio: pca953x: Add support for PCAL6534 Date: Tue, 13 Sep 2022 16:53:48 +0100 Message-Id: <20220913155348.38716-5-martyn.welch@collabora.co.uk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220913155348.38716-1-martyn.welch@collabora.co.uk> References: <20220913155348.38716-1-martyn.welch@collabora.co.uk> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Martyn Welch Add support for the NXP PCAL6534. This device is broadly a 34-bit version of the PCAL6524. However, whilst the registers are broadly what you'd expect for a 34-bit version of the PCAL6524, the spacing of the registers has been compacted. This has the unfortunate effect of breaking the bit shift based mechanism that is employed to work out register locations used by the other chips supported by this driver. To accommodate ths, callback functions have been added to allow alterate implementations of pca953x_recalc_addr() and pca953x_check_register() for the PCAL6534. Datasheet: https://www.nxp.com/docs/en/data-sheet/PCAL6534.pdf Datasheet: https://www.diodes.com/assets/Datasheets/PI4IOE5V6534Q.pdf Signed-off-by: Martyn Welch --- Changes in v2: - Removed stray change - Removed pi4ioe5v6534q ID (should use pcal6534) - Added callbacks to allow differing implementations of check_register and recalc_addr to be provided Changes in v3: - Removed spurious newline - Shifted from ">" to ">=" to improve code readbility - Correct comment style - Remove spurious change to pca953x_recalc_addr() - Correct indentation Changes in v4: - None drivers/gpio/gpio-pca953x.c | 136 +++++++++++++++++++++++++++++++----- 1 file changed, 117 insertions(+), 19 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1e8f038734e0..6398a5c888f6 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -66,6 +66,7 @@ #define PCA_LATCH_INT (PCA_PCAL | PCA_INT) #define PCA953X_TYPE BIT(12) #define PCA957X_TYPE BIT(13) +#define PCAL653X_TYPE BIT(14) #define PCA_TYPE_MASK GENMASK(15, 12) #define PCA_CHIP_TYPE(x) ((x) & PCA_TYPE_MASK) @@ -91,6 +92,7 @@ static const struct i2c_device_id pca953x_id[] = { { "pcal6416", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal6524", 24 | PCA953X_TYPE | PCA_LATCH_INT, }, + { "pcal6534", 34 | PCAL653X_TYPE | PCA_LATCH_INT, }, { "pcal9535", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal9554b", 8 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal9555a", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, @@ -211,6 +213,10 @@ struct pca953x_chip { struct regulator *regulator; const struct pca953x_reg_config *regs; + + u8 (*recalc_addr)(struct pca953x_chip *chip, int reg, int off); + bool (*check_reg)(struct pca953x_chip *chip, unsigned int reg, + u32 checkbank); }; static int pca953x_bank_shift(struct pca953x_chip *chip) @@ -288,6 +294,55 @@ static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg, return true; } +/* + * Unfortunately, whilst the PCAL6534 chip (and compatibles) broadly follow the + * same register layout as the PCAL6524, the spacing of the registers has been + * fundamentally altered by compacting them and thus does not obey the same + * rules, including being able to use bit shifting to determine bank. These + * chips hence need special handling here. + */ +static bool pcal6534_check_register(struct pca953x_chip *chip, unsigned int reg, + u32 checkbank) +{ + int bank; + int offset; + + if (reg >= 0x30) { + /* + * Reserved block between 14h and 2Fh does not align on + * expected bank boundaries like other devices. + */ + int temp = reg - 0x30; + + bank = temp / NBANK(chip); + offset = temp - (bank * NBANK(chip)); + bank += 8; + } else if (reg >= 0x54) { + /* + * Handle lack of reserved registers after output port + * configuration register to form a bank. + */ + int temp = reg - 0x54; + + bank = temp / NBANK(chip); + offset = temp - (bank * NBANK(chip)); + bank += 16; + } else { + bank = reg / NBANK(chip); + offset = reg - (bank * NBANK(chip)); + } + + /* Register is not in the matching bank. */ + if (!(BIT(bank) & checkbank)) + return false; + + /* Register is not within allowed range of bank. */ + if (offset >= NBANK(chip)) + return false; + + return true; +} + static bool pca953x_readable_register(struct device *dev, unsigned int reg) { struct pca953x_chip *chip = dev_get_drvdata(dev); @@ -308,7 +363,7 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg) PCAL9xxx_BANK_IRQ_STAT; } - return pca953x_check_register(chip, reg, bank); + return chip->check_reg(chip, reg, bank); } static bool pca953x_writeable_register(struct device *dev, unsigned int reg) @@ -328,7 +383,7 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg) bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN | PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK; - return pca953x_check_register(chip, reg, bank); + return chip->check_reg(chip, reg, bank); } static bool pca953x_volatile_register(struct device *dev, unsigned int reg) @@ -344,7 +399,7 @@ static bool pca953x_volatile_register(struct device *dev, unsigned int reg) if (chip->driver_data & PCA_PCAL) bank |= PCAL9xxx_BANK_IRQ_STAT; - return pca953x_check_register(chip, reg, bank); + return chip->check_reg(chip, reg, bank); } static const struct regmap_config pca953x_i2c_regmap = { @@ -389,9 +444,42 @@ static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off) return regaddr; } +/* + * The PCAL6534 and compatible chips have altered bank alignment that doesn't + * fit within the bit shifting scheme used for other devices. + */ +static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off) +{ + int addr; + int pinctrl; + + addr = (reg & PCAL_GPIO_MASK) * NBANK(chip); + + switch (reg) { + case PCAL953X_OUT_STRENGTH: + case PCAL953X_IN_LATCH: + case PCAL953X_PULL_EN: + case PCAL953X_PULL_SEL: + case PCAL953X_INT_MASK: + case PCAL953X_INT_STAT: + case PCAL953X_OUT_CONF: + pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x20; + break; + case PCAL6524_INT_EDGE: + case PCAL6524_INT_CLR: + case PCAL6524_IN_STATUS: + case PCAL6524_OUT_INDCONF: + case PCAL6524_DEBOUNCE: + pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x1c; + break; + } + + return pinctrl + addr + (off / BANK_SZ); +} + static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { - u8 regaddr = pca953x_recalc_addr(chip, reg, 0); + u8 regaddr = chip->recalc_addr(chip, reg, 0); u8 value[MAX_BANK]; int i, ret; @@ -409,7 +497,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val) { - u8 regaddr = pca953x_recalc_addr(chip, reg, 0); + u8 regaddr = chip->recalc_addr(chip, reg, 0); u8 value[MAX_BANK]; int i, ret; @@ -428,7 +516,7 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long * static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); + u8 dirreg = chip->recalc_addr(chip, chip->regs->direction, off); u8 bit = BIT(off % BANK_SZ); int ret; @@ -442,8 +530,8 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); - u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off); + u8 dirreg = chip->recalc_addr(chip, chip->regs->direction, off); + u8 outreg = chip->recalc_addr(chip, chip->regs->output, off); u8 bit = BIT(off % BANK_SZ); int ret; @@ -463,7 +551,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off); + u8 inreg = chip->recalc_addr(chip, chip->regs->input, off); u8 bit = BIT(off % BANK_SZ); u32 reg_val; int ret; @@ -480,7 +568,7 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off); + u8 outreg = chip->recalc_addr(chip, chip->regs->output, off); u8 bit = BIT(off % BANK_SZ); mutex_lock(&chip->i2c_lock); @@ -491,7 +579,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off); + u8 dirreg = chip->recalc_addr(chip, chip->regs->direction, off); u8 bit = BIT(off % BANK_SZ); u32 reg_val; int ret; @@ -550,8 +638,8 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, { enum pin_config_param param = pinconf_to_config_param(config); - u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset); - u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset); + u8 pull_en_reg = chip->recalc_addr(chip, PCAL953X_PULL_EN, offset); + u8 pull_sel_reg = chip->recalc_addr(chip, PCAL953X_PULL_SEL, offset); u8 bit = BIT(offset % BANK_SZ); int ret; @@ -914,13 +1002,13 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) u8 regaddr; int ret; - regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0); + regaddr = chip->recalc_addr(chip, chip->regs->output, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) goto out; - regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0); + regaddr = chip->recalc_addr(chip, chip->regs->direction, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) @@ -1039,6 +1127,14 @@ static int pca953x_probe(struct i2c_client *client, regmap_config = &pca953x_i2c_regmap; } + if (PCA_CHIP_TYPE(chip->driver_data) == PCAL653X_TYPE) { + chip->recalc_addr = pcal6534_recalc_addr; + chip->check_reg = pcal6534_check_register; + } else { + chip->recalc_addr = pca953x_recalc_addr; + chip->check_reg = pca953x_check_register; + } + chip->regmap = devm_regmap_init_i2c(client, regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); @@ -1133,14 +1229,14 @@ static int pca953x_regcache_sync(struct device *dev) * The ordering between direction and output is important, * sync these registers first and only then sync the rest. */ - regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0); + regaddr = chip->recalc_addr(chip, chip->regs->direction, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) { dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret); return ret; } - regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0); + regaddr = chip->recalc_addr(chip, chip->regs->output, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) { dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret); @@ -1149,7 +1245,7 @@ static int pca953x_regcache_sync(struct device *dev) #ifdef CONFIG_GPIO_PCA953X_IRQ if (chip->driver_data & PCA_PCAL) { - regaddr = pca953x_recalc_addr(chip, PCAL953X_IN_LATCH, 0); + regaddr = chip->recalc_addr(chip, PCAL953X_IN_LATCH, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) { @@ -1158,7 +1254,7 @@ static int pca953x_regcache_sync(struct device *dev) return ret; } - regaddr = pca953x_recalc_addr(chip, PCAL953X_INT_MASK, 0); + regaddr = chip->recalc_addr(chip, PCAL953X_INT_MASK, 0); ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1); if (ret) { @@ -1216,6 +1312,7 @@ static int pca953x_resume(struct device *dev) #endif /* convenience to stop overlong match-table lines */ +#define OF_653X(__nrgpio, __int) ((void *)(__nrgpio | PCAL653X_TYPE | __int)) #define OF_953X(__nrgpio, __int) (void *)(__nrgpio | PCA953X_TYPE | __int) #define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int) @@ -1240,6 +1337,7 @@ static const struct of_device_id pca953x_dt_ids[] = { { .compatible = "nxp,pcal6416", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_LATCH_INT), }, + { .compatible = "nxp,pcal6534", .data = OF_653X(34, PCA_LATCH_INT), }, { .compatible = "nxp,pcal9535", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal9554b", .data = OF_953X( 8, PCA_LATCH_INT), }, { .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_LATCH_INT), },