Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp566109imj; Thu, 7 Feb 2019 08:30:04 -0800 (PST) X-Google-Smtp-Source: AHgI3IZMW5lNicpgRjHkpNM+gVlRyK1OgEhqtmHYStHWQYyJp+6gTgO5fkxQqJk9yEHEofnbH4uk X-Received: by 2002:a63:2109:: with SMTP id h9mr15431250pgh.277.1549557004047; Thu, 07 Feb 2019 08:30:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549557004; cv=none; d=google.com; s=arc-20160816; b=qW//T/pkFiFrUVevyDq5NdmIhs/e0DEcZJj8mvMWlz1f7kQEYY0X17zZ77eST2Z/Kc ELWvL7+vPjBICrKoW6Z6CyUpOrjNtVZKkFczryd+iIPRLXorHYHWuLeWo7YddNgpmwg/ AEhLSXh1gcP5tasF86rz9F4zEQOKcM+5GJ0gvKZzSZO1bu25nNQTE9xVTAyhJcQeHhok fSixF+TEvlBFVoLGzNKc8jjXoJaQ/vOKIRJpcjoxUexcl/j0BRCpuT6pR+xgtsfY/cf0 iELKrBUn32h48ES/DrZeUpfbXNt7XziJpWVYHq17CoKWZRt/9rWeSiGrCuVX5/rXNd/Y gjWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=PfRX2nscCscF0cX7Nntb5//IuE02l6jFi4mixQmWdxQ=; b=W+6lL3LejDAKjE+dcMnqMIUDuQ6tjlfvOSxQO4TlpQ38KiLOacy/1P8jkUkE1bZwxS xdl/ZdxSkY+LUKgmUcxW00YeLK6tVokRjsFcxdgbI3ImbuRhIAHUXrFUWOZWs5gAN6Qm b+crW0BDg8M1R6EbAFSwRAozhIJdUNAEYHmIF3vCQM33a1Lqiatpe/CIyg43ZhHc/GXL XYkLZldLekXxShmGTh4jWB2LB00/XwiOuj6a1rpQjoTHKOQ7VnJFWiKmVbBwNefmFJTO Qz9UxSmXC4oK6SxDe7XnwW6j02sPv8JWIHXRd+qd3tzdcZZknU+as8T0cWAsmEkepaI7 I3gA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si2453342plb.290.2019.02.07.08.29.48; Thu, 07 Feb 2019 08:30:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727078AbfBGQ3U (ORCPT + 99 others); Thu, 7 Feb 2019 11:29:20 -0500 Received: from relay8-d.mail.gandi.net ([217.70.183.201]:39143 "EHLO relay8-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726843AbfBGQ3T (ORCPT ); Thu, 7 Feb 2019 11:29:19 -0500 X-Originating-IP: 90.88.22.177 Received: from localhost (aaubervilliers-681-1-80-177.w90-88.abo.wanadoo.fr [90.88.22.177]) (Authenticated sender: thomas.petazzoni@bootlin.com) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id BD5091BF208; Thu, 7 Feb 2019 16:29:15 +0000 (UTC) From: Thomas Petazzoni To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Mark Rutland , Frank Rowand Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Jan=20Kundr=C3=A1t?= , Thomas Petazzoni Subject: [PATCH v2 5/5] gpio: pca953x: add ->set_config implementation Date: Thu, 7 Feb 2019 17:28:59 +0100 Message-Id: <20190207162859.26252-6-thomas.petazzoni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190207162859.26252-1-thomas.petazzoni@bootlin.com> References: <20190207162859.26252-1-thomas.petazzoni@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This commit adds a minimal implementation of the ->set_config() hook, with support for the PIN_CONFIG_BIAS_PULL_UP and PIN_CONFIG_BIAS_PULL_DOWN configurations. Signed-off-by: Thomas Petazzoni --- drivers/gpio/gpio-pca953x.c | 66 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 83d45f00e4d0..1e5579acd275 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -179,6 +179,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip) #define PCA957x_BANK_OUTPUT BIT(5) #define PCAL9xxx_BANK_IN_LATCH BIT(8 + 2) +#define PCAL9xxx_BANK_PULL_EN BIT(8 + 3) +#define PCAL9xxx_BANK_PULL_SEL BIT(8 + 4) #define PCAL9xxx_BANK_IRQ_MASK BIT(8 + 5) #define PCAL9xxx_BANK_IRQ_STAT BIT(8 + 6) @@ -200,6 +202,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip) * - Extended set, above 0x40, often chip specific. * - PCAL6524/PCAL9555A with custom PCAL IRQ handling: * Input latch register 0x40 + 2 * bank_size RW + * Pull-up/pull-down enable reg 0x40 + 3 * bank_size RW + * Pull-up/pull-down select reg 0x40 + 4 * bank_size RW * Interrupt mask register 0x40 + 5 * bank_size RW * Interrupt status register 0x40 + 6 * bank_size R * @@ -248,7 +252,8 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg) } if (chip->driver_data & PCA_PCAL) { - bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK | + bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN | + PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK | PCAL9xxx_BANK_IRQ_STAT; } @@ -269,7 +274,8 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg) } if (chip->driver_data & PCA_PCAL) - bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK; + bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN | + PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK; return pca953x_check_register(chip, reg, bank); } @@ -474,6 +480,61 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, mutex_unlock(&chip->i2c_lock); } +static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, + unsigned int offset, + unsigned long config) +{ + u8 pull_en_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_EN, offset, + true, false); + u8 pull_sel_reg = pca953x_recalc_addr(chip, PCAL953X_PULL_SEL, offset, + true, false); + u8 bit = BIT(offset % BANK_SZ); + int ret; + + /* + * pull-up/pull-down configuration requires PCAL extended + * registers + */ + if (!(chip->driver_data & PCA_PCAL)) + return -ENOTSUPP; + + mutex_lock(&chip->i2c_lock); + + /* Disable pull-up/pull-down */ + ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); + if (ret) + goto exit; + + /* Configure pull-up/pull-down */ + if (config == PIN_CONFIG_BIAS_PULL_UP) + ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, bit); + else if (config == PIN_CONFIG_BIAS_PULL_DOWN) + ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, 0); + if (ret) + goto exit; + + /* Enable pull-up/pull-down */ + ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); + +exit: + mutex_unlock(&chip->i2c_lock); + return ret; +} + +static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + unsigned long config) +{ + struct pca953x_chip *chip = gpiochip_get_data(gc); + + switch (config) { + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + return pca953x_gpio_set_pull_up_down(chip, offset, config); + default: + return -ENOTSUPP; + } +} + static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) { struct gpio_chip *gc; @@ -486,6 +547,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->set = pca953x_gpio_set_value; gc->get_direction = pca953x_gpio_get_direction; gc->set_multiple = pca953x_gpio_set_multiple; + gc->set_config = pca953x_gpio_set_config; gc->can_sleep = true; gc->base = chip->gpio_start; -- 2.20.1