Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2917391pxj; Sun, 23 May 2021 15:36:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJztjO2NopzvsPFsqVSjS/Qc/zFgRm1hutfVxRJUXWKSQi9yEcJRIqkIPHoGRsMpKTLYZwca X-Received: by 2002:a17:906:3b0f:: with SMTP id g15mr19730985ejf.308.1621809415001; Sun, 23 May 2021 15:36:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621809414; cv=none; d=google.com; s=arc-20160816; b=TdPhwknRwLr3cVVSEZD61+HsseRZTTR/A9H58PgxBBq7XyOjYTA0ptEG09ChN/kOZz AVkALfciELbh5QFEMFPuKyGtdcV6qyUYXs0SiA1t6qzEDUvGOt/NHlQd8ZvTesIbCcNQ gUkEOTECpdWn/ujltENedSTVVCzECjFWzPXPHToVHGThZ44D9kL8EU3vv7AIB38fSv4t 3WuB6ig5Eqp/M7a4YpMcrrItGBKs4rvfqseZqogq9bQLqnF+mjbQEn4JM5LU0j/wpf68 ZAoSQ00VRf4jOiGztM+QNfbYzFWYlkdO07A3gCpt6vqZwuRHOSHANCPZMsWBwW5czyhY DXvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=2X9pHkF5aWPdiW7BSlrKumYHJyz+s9wXhroqdIN+ocs=; b=Rnk3k+vAMMX3RvPlktatgPRpkQNI2/EOo9Yp+C0pN+95SD8ujahqd0YKjjlejwmtW3 5o6AJk5wVJ/mFhf9RMsYXGUUYTSOnjQyn/93ZlmRAbJtO8UipmXKSokNSXf7gHsrlvXH K5IIYIV8wbhM2m41M0ThuoB+ZeTge+x2W86CnjgKfdWMumeq3lKdcnrPR1gnYt6cZr4H rMpnr4NVr5y2eB/1k3tZf1RSylSmdWUW454xg+oiI8uS2V3I2e9iAOmZHTJW2xA4989+ CsMg7FSluEJ5O55Vv4H39Y1cDhaeQzQWCdCnK3PKLeGFgkvLOFrmAwcDma9z9/p3goiw 0LLQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@svanheule.net header.s=mail1707 header.b=tMS0KhEe; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=svanheule.net Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p8si12861494edj.611.2021.05.23.15.36.03; Sun, 23 May 2021 15:36:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@svanheule.net header.s=mail1707 header.b=tMS0KhEe; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=svanheule.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232087AbhEWWf7 (ORCPT + 99 others); Sun, 23 May 2021 18:35:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232069AbhEWWfz (ORCPT ); Sun, 23 May 2021 18:35:55 -0400 Received: from polaris.svanheule.net (polaris.svanheule.net [IPv6:2a00:c98:2060:a004:1::200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F0DAC061574 for ; Sun, 23 May 2021 15:34:28 -0700 (PDT) Received: from terra.local.svanheule.net (unknown [IPv6:2a02:a03f:eafb:ee01:bd37:7535:eb00:6fa]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id 8CB68202A54; Mon, 24 May 2021 00:34:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1621809266; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2X9pHkF5aWPdiW7BSlrKumYHJyz+s9wXhroqdIN+ocs=; b=tMS0KhEeMuk9/kBXf8DmZK8AatGSiDaVH2yZQeBLmTN7sb1M4GtXU7Fkvnu4cdUrVIJWt3 fnKBWsqlfQn/Pq36mIRaPtiLLZb36e7w0aOs16fkHn8goHK2eFpLTZb33vVdtp8mK/i2D+ ytCyHbVjDQeI7xvJHEhxObV/QpPuzsswYlKAKKUms3Rrc7O3e+FDkkimm5TXPHk3k23RNi LX7wsNDqJjqp2PoZI/OtKi3iPVmzCx5OsM1yncB39C2LZBPD0L5RYQL/G3L9tseHFqSXm/ Z1jZscv/PUOzBHvTth8x+3gS4yH8IexzwQ/hxnxJY0opTmyWJx0zTTaQs+0TCQ== From: Sander Vanheule To: Pavel Machek , Rob Herring , Lee Jones , Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Michael Walle , Linus Walleij , Bartosz Golaszewski , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org Cc: Andrew Lunn , Andy Shevchenko , linux-kernel@vger.kernel.org, Sander Vanheule Subject: [PATCH v3 1/6] gpio: regmap: Add quirk for output data register Date: Mon, 24 May 2021 00:33:59 +0200 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org GPIO chips may not support setting the output value when a pin is configured as an input, although the current implementation assumes this is always possible. Add support for setting pin direction before value. The order defaults to setting the value first, but this can be reversed by setting the GPIO_REGMAP_QUIRK_SET_DIRECTION_FIRST flag in regmap_config.quirks. Signed-off-by: Sander Vanheule --- drivers/gpio/gpio-regmap.c | 15 +++++++++++++-- include/linux/gpio/regmap.h | 13 +++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 134cedf151a7..95553734e169 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -15,6 +15,7 @@ struct gpio_regmap { struct device *parent; struct regmap *regmap; struct gpio_chip gpio_chip; + unsigned int quirks; int reg_stride; int ngpio_per_reg; @@ -173,9 +174,18 @@ static int gpio_regmap_direction_input(struct gpio_chip *chip, static int gpio_regmap_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - gpio_regmap_set(chip, offset, value); + struct gpio_regmap *gpio = gpiochip_get_data(chip); + int ret; + + if (gpio->quirks & GPIO_REGMAP_QUIRK_SET_DIRECTION_FIRST) { + ret = gpio_regmap_set_direction(chip, offset, true); + gpio_regmap_set(chip, offset, value); + } else { + gpio_regmap_set(chip, offset, value); + ret = gpio_regmap_set_direction(chip, offset, true); + } - return gpio_regmap_set_direction(chip, offset, true); + return ret; } void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data) @@ -227,6 +237,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config gpio->parent = config->parent; gpio->regmap = config->regmap; + gpio->quirks = config->quirks; gpio->ngpio_per_reg = config->ngpio_per_reg; gpio->reg_stride = config->reg_stride; gpio->reg_mask_xlate = config->reg_mask_xlate; diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index 334dd928042b..cb609489903e 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h @@ -12,6 +12,17 @@ struct regmap; #define GPIO_REGMAP_ADDR_ZERO ((unsigned int)(-1)) #define GPIO_REGMAP_ADDR(addr) ((addr) ? : GPIO_REGMAP_ADDR_ZERO) +enum gpio_regmap_quirk { + /* + * For hardware where the pin output value cannot be set while the pin + * is configured as an input. Resolve by setting the direction to + * output first, and the new value second. Because the previous output + * value is used immediately after the direction change, this may result + * in glitches. + */ + GPIO_REGMAP_QUIRK_SET_DIRECTION_FIRST = BIT(0), +}; + /** * struct gpio_regmap_config - Description of a generic regmap gpio_chip. * @parent: The parent device @@ -31,6 +42,7 @@ struct regmap; * @reg_stride: (Optional) May be set if the registers (of the * same type, dat, set, etc) are not consecutive. * @ngpio_per_reg: Number of GPIOs per register + * @quirks: Flags indicating GPIO chip hardware issues * @irq_domain: (Optional) IRQ domain if the controller is * interrupt-capable * @reg_mask_xlate: (Optional) Translates base address and GPIO @@ -73,6 +85,7 @@ struct gpio_regmap_config { unsigned int reg_dir_out_base; int reg_stride; int ngpio_per_reg; + unsigned int quirks; struct irq_domain *irq_domain; int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base, -- 2.31.1