Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3740575imm; Mon, 30 Jul 2018 02:35:44 -0700 (PDT) X-Google-Smtp-Source: AAOMgpeyKKmwP9u3dnPjGzKJVBhy+XqH9wBjVsJxzGdjULdtsiqRq8bpxb91op9vTyo+AXygn5H3 X-Received: by 2002:a65:5907:: with SMTP id f7-v6mr15341636pgu.83.1532943344552; Mon, 30 Jul 2018 02:35:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532943344; cv=none; d=google.com; s=arc-20160816; b=CV03JVY8HMLg7V+sfCz+JM0TtyGPVRyxm9pDwzItqBiF7ZaZZygmb4asFZD7FOxoLZ Tmgf3b65/2VyehcFaZ+20rlT3J7YtH2S6mLDRYxNa/RfvPlwysqkxbKxUrkTUKTehmiT hf1X63z36msA2Tqx833kd9rWD52JYL3wwMYpNMlG6qJp+M9U4z+xY7y6nFvYpN0IoT6m DbEhwbdEFxDq7Yv1MWydmMlUlzARGDbuu7cahqSI7DXBhQ900yPWSovO1C42hzi0n5vq QhVMph5oqo7BUZ8uUNgahRnTlYj1DuXhg5Ypcwbx3HFCoJqCE74poKj15PGKswF9Rqbx TX2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=3+TyT/6qUvPjLXhhsHM0ADWT1TThPl250ch9vw2v8r0=; b=RTkSOIiG2YYoyXbFxVWe42P7fZBqx43A3JzcuWY9mraBflx5JIKuPE0pedc8i/SFmF IbVB/NBdSRr1v/Pm2+agUqZiXohgLYB/R4uwhwUlJpqzDFZSY0Tt1zbet/NJlzzwNQVo QYBaB4QENsMeWJwq6+UBAyV7zyPfAlWcDYvx4DPDmdQsaEfeHVEJBnwMWb3k/5AJnV3w 4vKoRi5hEIH0JyDxB+ocqdllToJ0+sXT3UVhHuGOxOemdSnxg78thrTt11ScK4SIlrF3 A1ckupbgz/Faeu05DZ+OYEJnTyjXwC375CsMAb4rbbaAjlQ2zQU+2sxVRORIu6LrBeCQ SRGg== 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f16-v6si11265228pfd.276.2018.07.30.02.35.29; Mon, 30 Jul 2018 02:35:44 -0700 (PDT) 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727658AbeG3LIj (ORCPT + 99 others); Mon, 30 Jul 2018 07:08:39 -0400 Received: from 212.199.177.27.static.012.net.il ([212.199.177.27]:51571 "EHLO herzl.nuvoton.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726723AbeG3LIj (ORCPT ); Mon, 30 Jul 2018 07:08:39 -0400 Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id w6U94Mwn004898; Mon, 30 Jul 2018 12:04:22 +0300 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 7BB756312A; Mon, 30 Jul 2018 12:34:21 +0300 (IDT) From: Tomer Maimon To: linus.walleij@linaro.org Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, Tomer Maimon Subject: [PATCH v1 1/1] gpio: mmio: add inverted direction get_set io support Date: Mon, 30 Jul 2018 12:34:18 +0300 Message-Id: <20180730093418.124648-2-tmaimon77@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180730093418.124648-1-tmaimon77@gmail.com> References: <20180730093418.124648-1-tmaimon77@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add get_set_inv_dir and get_set_multiple_inv_dir I/O functions to call the data register when the dirction is input and set register when the direction is output. the functions will linked to the I/O get functions if the user set BGPIOF_INVERTED_REG_DIR flag in the bgpio initialization. Signed-off-by: Tomer Maimon --- drivers/gpio/gpio-mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++--- include/linux/gpio/driver.h | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index 7b14d6280e44..46f664459853 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -168,6 +168,40 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, return 0; } +/* get set function when the direction is inverted */ +static int bgpio_get_set_inv_dir(struct gpio_chip *gc, unsigned int gpio) +{ + unsigned long pinmask = bgpio_line2mask(gc, gpio); + + if (gc->bgpio_dir & pinmask) + return !!(gc->read_reg(gc->reg_dat) & pinmask); + else + return !!(gc->read_reg(gc->reg_set) & pinmask); +} + +/* get set multiple function when the direction is inverted */ +static int bgpio_get_set_multiple_inv_dir(struct gpio_chip *gc, + unsigned long *mask, + unsigned long *bits) +{ + unsigned long get_mask = 0; + unsigned long set_mask = 0; + + /* Make sure we first clear any bits that are zero when we read the register */ + *bits &= ~*mask; + + /* Exploit the fact that we know which directions are set */ + set_mask = *mask & ~gc->bgpio_dir; + get_mask = *mask & gc->bgpio_dir; + + if (set_mask) + *bits |= gc->read_reg(gc->reg_set) & set_mask; + if (get_mask) + *bits |= gc->read_reg(gc->reg_dat) & get_mask; + + return 0; +} + static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) { return !!(gc->read_reg(gc->reg_dat) & bgpio_line2mask(gc, gpio)); @@ -525,9 +559,17 @@ static int bgpio_setup_io(struct gpio_chip *gc, if (!(flags & BGPIOF_UNREADABLE_REG_SET) && (flags & BGPIOF_READ_OUTPUT_REG_SET)) { - gc->get = bgpio_get_set; - if (!gc->be_bits) - gc->get_multiple = bgpio_get_set_multiple; + /* if the direction inverted */ + if (flags & BGPIOF_INVERTED_REG_DIR) { + gc->get = bgpio_get_set_inv_dir; + if (!gc->be_bits) + gc->get_multiple = + bgpio_get_set_multiple_inv_dir; + } else { + gc->get = bgpio_get_set; + if (!gc->be_bits) + gc->get_multiple = bgpio_get_set_multiple; + } /* * We deliberately avoid assigning the ->get_multiple() call * for big endian mirrored registers which are ALSO reflecting diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 5382b5183b7e..63570580707c 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -425,6 +425,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */ #define BGPIOF_NO_OUTPUT BIT(5) /* only input */ +#define BGPIOF_INVERTED_REG_DIR BIT(6) /* reg_dir inverted */ #endif -- 2.14.1