From patchwork Fri Dec 1 13:44:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843493 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFwc4Vcxz9tBR for ; Sat, 2 Dec 2017 00:48:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752880AbdLANrR (ORCPT ); Fri, 1 Dec 2017 08:47:17 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36220 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752716AbdLANpu (ORCPT ); Fri, 1 Dec 2017 08:45:50 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id B3BBD209E1; Fri, 1 Dec 2017 14:45:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 5806F20750; Fri, 1 Dec 2017 14:45:38 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 01/10] pinctrl: move gpio-axp209 to pinctrl Date: Fri, 1 Dec 2017 14:44:42 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org To prepare the driver for the upcoming pinctrl features, move the GPIO driver AXP209 from GPIO to pinctrl subsystem. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard Acked-by: Chen-Yu Tsai --- drivers/gpio/Kconfig | 6 +- drivers/gpio/Makefile | 1 +- drivers/gpio/gpio-axp209.c | 188 +-------------------------------- drivers/pinctrl/Kconfig | 6 +- drivers/pinctrl/Makefile | 1 +- drivers/pinctrl/pinctrl-axp209.c | 188 ++++++++++++++++++++++++++++++++- 6 files changed, 195 insertions(+), 195 deletions(-) delete mode 100644 drivers/gpio/gpio-axp209.c create mode 100644 drivers/pinctrl/pinctrl-axp209.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d6a8e85..395669b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -122,12 +122,6 @@ config GPIO_ATH79 Select this option to enable GPIO driver for Atheros AR71XX/AR724X/AR913X SoC devices. -config GPIO_AXP209 - tristate "X-Powers AXP209 PMIC GPIO Support" - depends on MFD_AXP20X - help - Say yes to enable GPIO support for the AXP209 PMIC - config GPIO_BCM_KONA bool "Broadcom Kona GPIO" depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4bc24fe..bc5dd67 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o -obj-$(CONFIG_GPIO_AXP209) += gpio-axp209.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c deleted file mode 100644 index 4a346b7..0000000 --- a/drivers/gpio/gpio-axp209.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * AXP20x GPIO driver - * - * Copyright (C) 2016 Maxime Ripard - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AXP20X_GPIO_FUNCTIONS 0x7 -#define AXP20X_GPIO_FUNCTION_OUT_LOW 0 -#define AXP20X_GPIO_FUNCTION_OUT_HIGH 1 -#define AXP20X_GPIO_FUNCTION_INPUT 2 - -struct axp20x_gpio { - struct gpio_chip chip; - struct regmap *regmap; -}; - -static int axp20x_gpio_get_reg(unsigned offset) -{ - switch (offset) { - case 0: - return AXP20X_GPIO0_CTRL; - case 1: - return AXP20X_GPIO1_CTRL; - case 2: - return AXP20X_GPIO2_CTRL; - } - - return -EINVAL; -} - -static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset) -{ - struct axp20x_gpio *gpio = gpiochip_get_data(chip); - int reg; - - reg = axp20x_gpio_get_reg(offset); - if (reg < 0) - return reg; - - return regmap_update_bits(gpio->regmap, reg, - AXP20X_GPIO_FUNCTIONS, - AXP20X_GPIO_FUNCTION_INPUT); -} - -static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct axp20x_gpio *gpio = gpiochip_get_data(chip); - unsigned int val; - int ret; - - ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val); - if (ret) - return ret; - - return !!(val & BIT(offset + 4)); -} - -static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) -{ - struct axp20x_gpio *gpio = gpiochip_get_data(chip); - unsigned int val; - int reg, ret; - - reg = axp20x_gpio_get_reg(offset); - if (reg < 0) - return reg; - - ret = regmap_read(gpio->regmap, reg, &val); - if (ret) - return ret; - - /* - * This shouldn't really happen if the pin is in use already, - * or if it's not in use yet, it doesn't matter since we're - * going to change the value soon anyway. Default to output. - */ - if ((val & AXP20X_GPIO_FUNCTIONS) > 2) - return 0; - - /* - * The GPIO directions are the three lowest values. - * 2 is input, 0 and 1 are output - */ - return val & 2; -} - -static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct axp20x_gpio *gpio = gpiochip_get_data(chip); - int reg; - - reg = axp20x_gpio_get_reg(offset); - if (reg < 0) - return reg; - - return regmap_update_bits(gpio->regmap, reg, - AXP20X_GPIO_FUNCTIONS, - value ? AXP20X_GPIO_FUNCTION_OUT_HIGH - : AXP20X_GPIO_FUNCTION_OUT_LOW); -} - -static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, - int value) -{ - axp20x_gpio_output(chip, offset, value); -} - -static int axp20x_gpio_probe(struct platform_device *pdev) -{ - struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); - struct axp20x_gpio *gpio; - int ret; - - if (!of_device_is_available(pdev->dev.of_node)) - return -ENODEV; - - if (!axp20x) { - dev_err(&pdev->dev, "Parent drvdata not set\n"); - return -EINVAL; - } - - gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); - if (!gpio) - return -ENOMEM; - - gpio->chip.base = -1; - gpio->chip.can_sleep = true; - gpio->chip.parent = &pdev->dev; - gpio->chip.label = dev_name(&pdev->dev); - gpio->chip.owner = THIS_MODULE; - gpio->chip.get = axp20x_gpio_get; - gpio->chip.get_direction = axp20x_gpio_get_direction; - gpio->chip.set = axp20x_gpio_set; - gpio->chip.direction_input = axp20x_gpio_input; - gpio->chip.direction_output = axp20x_gpio_output; - gpio->chip.ngpio = 3; - - gpio->regmap = axp20x->regmap; - - ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); - if (ret) { - dev_err(&pdev->dev, "Failed to register GPIO chip\n"); - return ret; - } - - dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n"); - - return 0; -} - -static const struct of_device_id axp20x_gpio_match[] = { - { .compatible = "x-powers,axp209-gpio" }, - { } -}; -MODULE_DEVICE_TABLE(of, axp20x_gpio_match); - -static struct platform_driver axp20x_gpio_driver = { - .probe = axp20x_gpio_probe, - .driver = { - .name = "axp20x-gpio", - .of_match_table = axp20x_gpio_match, - }, -}; - -module_platform_driver(axp20x_gpio_driver); - -MODULE_AUTHOR("Maxime Ripard "); -MODULE_DESCRIPTION("AXP20x PMIC GPIO driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4571cc0..58e8cc8 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -63,6 +63,12 @@ config PINCTRL_AS3722 open drain configuration for the GPIO pins of AS3722 devices. It also supports the GPIO functionality through gpiolib. +config PINCTRL_AXP209 + tristate "X-Powers AXP209 PMIC pinctrl and GPIO Support" + depends on MFD_AXP20X + help + Say yes to enable pinctrl and GPIO support for the AXP209 PMIC + config PINCTRL_BF54x def_bool y if BF54x select PINCTRL_ADI2 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index d0d4844..4777f15 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o +obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c new file mode 100644 index 0000000..4a346b7 --- /dev/null +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -0,0 +1,188 @@ +/* + * AXP20x GPIO driver + * + * Copyright (C) 2016 Maxime Ripard + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AXP20X_GPIO_FUNCTIONS 0x7 +#define AXP20X_GPIO_FUNCTION_OUT_LOW 0 +#define AXP20X_GPIO_FUNCTION_OUT_HIGH 1 +#define AXP20X_GPIO_FUNCTION_INPUT 2 + +struct axp20x_gpio { + struct gpio_chip chip; + struct regmap *regmap; +}; + +static int axp20x_gpio_get_reg(unsigned offset) +{ + switch (offset) { + case 0: + return AXP20X_GPIO0_CTRL; + case 1: + return AXP20X_GPIO1_CTRL; + case 2: + return AXP20X_GPIO2_CTRL; + } + + return -EINVAL; +} + +static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset) +{ + struct axp20x_gpio *gpio = gpiochip_get_data(chip); + int reg; + + reg = axp20x_gpio_get_reg(offset); + if (reg < 0) + return reg; + + return regmap_update_bits(gpio->regmap, reg, + AXP20X_GPIO_FUNCTIONS, + AXP20X_GPIO_FUNCTION_INPUT); +} + +static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct axp20x_gpio *gpio = gpiochip_get_data(chip); + unsigned int val; + int ret; + + ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val); + if (ret) + return ret; + + return !!(val & BIT(offset + 4)); +} + +static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct axp20x_gpio *gpio = gpiochip_get_data(chip); + unsigned int val; + int reg, ret; + + reg = axp20x_gpio_get_reg(offset); + if (reg < 0) + return reg; + + ret = regmap_read(gpio->regmap, reg, &val); + if (ret) + return ret; + + /* + * This shouldn't really happen if the pin is in use already, + * or if it's not in use yet, it doesn't matter since we're + * going to change the value soon anyway. Default to output. + */ + if ((val & AXP20X_GPIO_FUNCTIONS) > 2) + return 0; + + /* + * The GPIO directions are the three lowest values. + * 2 is input, 0 and 1 are output + */ + return val & 2; +} + +static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct axp20x_gpio *gpio = gpiochip_get_data(chip); + int reg; + + reg = axp20x_gpio_get_reg(offset); + if (reg < 0) + return reg; + + return regmap_update_bits(gpio->regmap, reg, + AXP20X_GPIO_FUNCTIONS, + value ? AXP20X_GPIO_FUNCTION_OUT_HIGH + : AXP20X_GPIO_FUNCTION_OUT_LOW); +} + +static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, + int value) +{ + axp20x_gpio_output(chip, offset, value); +} + +static int axp20x_gpio_probe(struct platform_device *pdev) +{ + struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); + struct axp20x_gpio *gpio; + int ret; + + if (!of_device_is_available(pdev->dev.of_node)) + return -ENODEV; + + if (!axp20x) { + dev_err(&pdev->dev, "Parent drvdata not set\n"); + return -EINVAL; + } + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->chip.base = -1; + gpio->chip.can_sleep = true; + gpio->chip.parent = &pdev->dev; + gpio->chip.label = dev_name(&pdev->dev); + gpio->chip.owner = THIS_MODULE; + gpio->chip.get = axp20x_gpio_get; + gpio->chip.get_direction = axp20x_gpio_get_direction; + gpio->chip.set = axp20x_gpio_set; + gpio->chip.direction_input = axp20x_gpio_input; + gpio->chip.direction_output = axp20x_gpio_output; + gpio->chip.ngpio = 3; + + gpio->regmap = axp20x->regmap; + + ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); + if (ret) { + dev_err(&pdev->dev, "Failed to register GPIO chip\n"); + return ret; + } + + dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n"); + + return 0; +} + +static const struct of_device_id axp20x_gpio_match[] = { + { .compatible = "x-powers,axp209-gpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, axp20x_gpio_match); + +static struct platform_driver axp20x_gpio_driver = { + .probe = axp20x_gpio_probe, + .driver = { + .name = "axp20x-gpio", + .of_match_table = axp20x_gpio_match, + }, +}; + +module_platform_driver(axp20x_gpio_driver); + +MODULE_AUTHOR("Maxime Ripard "); +MODULE_DESCRIPTION("AXP20x PMIC GPIO driver"); +MODULE_LICENSE("GPL"); From patchwork Fri Dec 1 13:44:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843495 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFwf16PHz9sNd for ; Sat, 2 Dec 2017 00:48:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753161AbdLANrQ (ORCPT ); Fri, 1 Dec 2017 08:47:16 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36231 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752803AbdLANpv (ORCPT ); Fri, 1 Dec 2017 08:45:51 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 138D1209E6; Fri, 1 Dec 2017 14:45:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id A338620976; Fri, 1 Dec 2017 14:45:38 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 02/10] pinctrl: axp209: add pinctrl features Date: Fri, 1 Dec 2017 14:44:43 +0100 Message-Id: <71c9da94df2a5938cb8c092e40f8e36eec0b01c3.1512135804.git-series.quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The X-Powers AXP209 has 3 GPIOs. GPIO0/1 can each act either as a GPIO, an ADC or a LDO regulator. GPIO2 can only act as a GPIO. This adds the pinctrl features to the driver so GPIO0/1 can be used as ADC or LDO regulator. Signed-off-by: Quentin Schulz --- drivers/pinctrl/pinctrl-axp209.c | 306 +++++++++++++++++++++++++++++--- 1 file changed, 286 insertions(+), 20 deletions(-) diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c index 4a346b7..2dc286f 100644 --- a/drivers/pinctrl/pinctrl-axp209.c +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -1,7 +1,8 @@ /* - * AXP20x GPIO driver + * AXP20x pinctrl and GPIO driver * * Copyright (C) 2016 Maxime Ripard + * Copyright (C) 2017 Quentin Schulz * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -27,9 +31,52 @@ #define AXP20X_GPIO_FUNCTION_OUT_HIGH 1 #define AXP20X_GPIO_FUNCTION_INPUT 2 +#define AXP20X_FUNC_GPIO_OUT 0 +#define AXP20X_FUNC_GPIO_IN 1 +#define AXP20X_FUNC_LDO 2 +#define AXP20X_FUNC_ADC 3 +#define AXP20X_FUNCS_NB 4 + +#define AXP20X_MUX_GPIO_OUT 0 +#define AXP20X_MUX_GPIO_IN BIT(1) +#define AXP20X_MUX_ADC BIT(2) + +struct axp20x_pctrl_desc { + const struct pinctrl_pin_desc *pins; + unsigned int npins; + /* Stores the pins supporting LDO function. Bit offset is pin number. */ + u8 ldo_mask; + /* Stores the pins supporting ADC function. Bit offset is pin number. */ + u8 adc_mask; +}; + +struct axp20x_pinctrl_function { + const char *name; + unsigned int muxval; + const char **groups; + unsigned int ngroups; +}; + struct axp20x_gpio { struct gpio_chip chip; struct regmap *regmap; + struct pinctrl_dev *pctl_dev; + struct device *dev; + const struct axp20x_pctrl_desc *desc; + struct axp20x_pinctrl_function funcs[AXP20X_FUNCS_NB]; +}; + +static const struct pinctrl_pin_desc axp209_pins[] = { + PINCTRL_PIN(0, "GPIO0"), + PINCTRL_PIN(1, "GPIO1"), + PINCTRL_PIN(2, "GPIO2"), +}; + +static const struct axp20x_pctrl_desc axp20x_data = { + .pins = axp209_pins, + .npins = ARRAY_SIZE(axp209_pins), + .ldo_mask = BIT(0) | BIT(1), + .adc_mask = BIT(0) | BIT(1), }; static int axp20x_gpio_get_reg(unsigned offset) @@ -48,16 +95,7 @@ static int axp20x_gpio_get_reg(unsigned offset) static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset) { - struct axp20x_gpio *gpio = gpiochip_get_data(chip); - int reg; - - reg = axp20x_gpio_get_reg(offset); - if (reg < 0) - return reg; - - return regmap_update_bits(gpio->regmap, reg, - AXP20X_GPIO_FUNCTIONS, - AXP20X_GPIO_FUNCTION_INPUT); + return pinctrl_gpio_direction_input(chip->base + offset); } static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -105,29 +143,222 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset, int value) { + chip->set(chip, offset, value); + + return 0; +} + +static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, + int value) +{ struct axp20x_gpio *gpio = gpiochip_get_data(chip); int reg; reg = axp20x_gpio_get_reg(offset); if (reg < 0) + return; + + regmap_update_bits(gpio->regmap, reg, + AXP20X_GPIO_FUNCTIONS, + value ? AXP20X_GPIO_FUNCTION_OUT_HIGH : + AXP20X_GPIO_FUNCTION_OUT_LOW); +} + +static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset, + u8 config) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + int reg; + + reg = axp20x_gpio_get_reg(offset); + if (reg < 0) return reg; - return regmap_update_bits(gpio->regmap, reg, - AXP20X_GPIO_FUNCTIONS, - value ? AXP20X_GPIO_FUNCTION_OUT_HIGH - : AXP20X_GPIO_FUNCTION_OUT_LOW); + return regmap_update_bits(gpio->regmap, reg, AXP20X_GPIO_FUNCTIONS, + config); } -static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, - int value) +static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + return ARRAY_SIZE(gpio->funcs); +} + +static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + return gpio->funcs[selector].name; +} + +static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + *groups = gpio->funcs[selector].groups; + *num_groups = gpio->funcs[selector].ngroups; + + return 0; +} + +static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + unsigned int mask; + + /* Every pin supports GPIO_OUT and GPIO_IN functions */ + if (function <= AXP20X_FUNC_GPIO_IN) + return axp20x_pmx_set(pctldev, group, + gpio->funcs[function].muxval); + + if (function == AXP20X_FUNC_LDO) + mask = gpio->desc->ldo_mask; + else + mask = gpio->desc->adc_mask; + + if (!(BIT(group) & mask)) + return -EINVAL; + + /* + * We let the regulator framework handle the LDO muxing as muxing bits + * are basically also regulators on/off bits. It's better not to enforce + * any state of the regulator when selecting LDO mux so that we don't + * interfere with the regulator driver. + */ + if (function == AXP20X_FUNC_LDO) + return 0; + + return axp20x_pmx_set(pctldev, group, gpio->funcs[function].muxval); +} + +static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset, bool input) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + if (input) + return axp20x_pmx_set(pctldev, offset, + gpio->funcs[AXP20X_FUNC_GPIO_IN].muxval); + + return axp20x_pmx_set(pctldev, offset, + gpio->funcs[AXP20X_FUNC_GPIO_OUT].muxval); +} + +static const struct pinmux_ops axp20x_pmx_ops = { + .get_functions_count = axp20x_pmx_func_cnt, + .get_function_name = axp20x_pmx_func_name, + .get_function_groups = axp20x_pmx_func_groups, + .set_mux = axp20x_pmx_set_mux, + .gpio_set_direction = axp20x_pmx_gpio_set_direction, + .strict = true, +}; + +static int axp20x_groups_cnt(struct pinctrl_dev *pctldev) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + return gpio->desc->npins; +} + +static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, + const unsigned int **pins, unsigned int *num_pins) +{ + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + *pins = (unsigned int *)&gpio->desc->pins[selector]; + *num_pins = 1; + + return 0; +} + +static const char *axp20x_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) { - axp20x_gpio_output(chip, offset, value); + struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + + return gpio->desc->pins[selector].name; +} + +static const struct pinctrl_ops axp20x_pctrl_ops = { + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinconf_generic_dt_free_map, + .get_groups_count = axp20x_groups_cnt, + .get_group_name = axp20x_group_name, + .get_group_pins = axp20x_group_pins, +}; + +static void axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask, + unsigned int mask_len, + struct axp20x_pinctrl_function *func, + const struct pinctrl_pin_desc *pins) +{ + unsigned long int mask_cpy = mask; + const char **group; + unsigned int ngroups = hweight8(mask); + int bit; + + func->ngroups = ngroups; + if (func->ngroups > 0) { + func->groups = devm_kzalloc(dev, ngroups * sizeof(const char *), + GFP_KERNEL); + group = func->groups; + for_each_set_bit(bit, &mask_cpy, mask_len) { + *group = pins[bit].name; + group++; + } + } +} + +static void axp20x_build_funcs_groups(struct platform_device *pdev) +{ + struct axp20x_gpio *gpio = platform_get_drvdata(pdev); + int i, pin; + + gpio->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out"; + gpio->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT; + gpio->funcs[AXP20X_FUNC_GPIO_IN].name = "gpio_in"; + gpio->funcs[AXP20X_FUNC_GPIO_IN].muxval = AXP20X_MUX_GPIO_IN; + gpio->funcs[AXP20X_FUNC_LDO].name = "ldo"; + /* + * Muxval for LDO is useless as we won't use it. + * See comment in axp20x_pmx_set_mux. + */ + gpio->funcs[AXP20X_FUNC_ADC].name = "adc"; + gpio->funcs[AXP20X_FUNC_ADC].muxval = AXP20X_MUX_ADC; + + /* Every pin supports GPIO_OUT and GPIO_IN functions */ + for (i = 0; i <= AXP20X_FUNC_GPIO_IN; i++) { + gpio->funcs[i].ngroups = gpio->desc->npins; + gpio->funcs[i].groups = devm_kzalloc(&pdev->dev, + gpio->desc->npins * sizeof(const char *), + GFP_KERNEL); + for (pin = 0; pin < gpio->desc->npins; pin++) + gpio->funcs[i].groups[pin] = gpio->desc->pins[pin].name; + } + + axp20x_funcs_groups_from_mask(&pdev->dev, gpio->desc->ldo_mask, + gpio->desc->npins, + &gpio->funcs[AXP20X_FUNC_LDO], + gpio->desc->pins); + + axp20x_funcs_groups_from_mask(&pdev->dev, gpio->desc->adc_mask, + gpio->desc->npins, + &gpio->funcs[AXP20X_FUNC_ADC], + gpio->desc->pins); } static int axp20x_gpio_probe(struct platform_device *pdev) { struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct axp20x_gpio *gpio; + struct pinctrl_desc *pctrl_desc; int ret; if (!of_device_is_available(pdev->dev.of_node)) @@ -144,6 +375,8 @@ static int axp20x_gpio_probe(struct platform_device *pdev) gpio->chip.base = -1; gpio->chip.can_sleep = true; + gpio->chip.request = gpiochip_generic_request; + gpio->chip.free = gpiochip_generic_free; gpio->chip.parent = &pdev->dev; gpio->chip.label = dev_name(&pdev->dev); gpio->chip.owner = THIS_MODULE; @@ -154,7 +387,30 @@ static int axp20x_gpio_probe(struct platform_device *pdev) gpio->chip.direction_output = axp20x_gpio_output; gpio->chip.ngpio = 3; + gpio->desc = &axp20x_data; gpio->regmap = axp20x->regmap; + gpio->dev = &pdev->dev; + + platform_set_drvdata(pdev, gpio); + + axp20x_build_funcs_groups(pdev); + + pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL); + if (!pctrl_desc) + return -ENOMEM; + + pctrl_desc->name = dev_name(&pdev->dev); + pctrl_desc->owner = THIS_MODULE; + pctrl_desc->pins = gpio->desc->pins; + pctrl_desc->npins = gpio->desc->npins; + pctrl_desc->pctlops = &axp20x_pctrl_ops; + pctrl_desc->pmxops = &axp20x_pmx_ops; + + gpio->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, gpio); + if (IS_ERR(gpio->pctl_dev)) { + dev_err(&pdev->dev, "couldn't register pinctrl driver\n"); + return PTR_ERR(gpio->pctl_dev); + } ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); if (ret) { @@ -162,7 +418,16 @@ static int axp20x_gpio_probe(struct platform_device *pdev) return ret; } - dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n"); + ret = gpiochip_add_pin_range(&gpio->chip, dev_name(&pdev->dev), + gpio->desc->pins->number, + gpio->desc->pins->number, + gpio->desc->npins); + if (ret) { + dev_err(&pdev->dev, "failed to add pin range\n"); + return ret; + } + + dev_info(&pdev->dev, "AXP209 pinctrl and GPIO driver loaded\n"); return 0; } @@ -184,5 +449,6 @@ static struct platform_driver axp20x_gpio_driver = { module_platform_driver(axp20x_gpio_driver); MODULE_AUTHOR("Maxime Ripard "); -MODULE_DESCRIPTION("AXP20x PMIC GPIO driver"); +MODULE_AUTHOR("Quentin Schulz "); +MODULE_DESCRIPTION("AXP20x PMIC pinctrl and GPIO driver"); MODULE_LICENSE("GPL"); From patchwork Fri Dec 1 13:44:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843494 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFwd3QLPz9tBL for ; Sat, 2 Dec 2017 00:48:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752940AbdLANrR (ORCPT ); Fri, 1 Dec 2017 08:47:17 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36239 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752874AbdLANpv (ORCPT ); Fri, 1 Dec 2017 08:45:51 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 55FF5209E9; Fri, 1 Dec 2017 14:45:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id F405E2097F; Fri, 1 Dec 2017 14:45:38 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 03/10] dt-bindings: gpio: gpio-axp209: add pinctrl features Date: Fri, 1 Dec 2017 14:44:44 +0100 Message-Id: <7fdc42fd2d3572069292ebe1376bb446beb4d8a9.1512135804.git-series.quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The X-Powers AXP209 has 3 GPIOs. GPIO0/1 can each act either as a GPIO, an ADC or a LDO regulator. GPIO2 can only act as a GPIO. This adds the pinctrl features to the driver so GPIO0/1 can be used as ADC or LDO regulator. Signed-off-by: Quentin Schulz Acked-by: Rob Herring --- Documentation/devicetree/bindings/gpio/gpio-axp209.txt | 28 ++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt index a661130..4705020 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt @@ -1,4 +1,4 @@ -AXP209 GPIO controller +AXP209 GPIO & pinctrl controller This driver follows the usual GPIO bindings found in Documentation/devicetree/bindings/gpio/gpio.txt @@ -28,3 +28,29 @@ axp209: pmic@34 { #gpio-cells = <2>; }; }; + +The GPIOs can be muxed to other functions and therefore, must be a subnode of +axp_gpio. + +Example: + +&axp_gpio { + gpio0_adc: gpio0-adc { + pins = "GPIO0"; + function = "adc"; + }; +}; + +&example_node { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_adc>; +}; + +GPIOs and their functions +------------------------- + +GPIO | Functions +------------------------ +GPIO0 | gpio_in, gpio_out, ldo, adc +GPIO1 | gpio_in, gpio_out, ldo, adc +GPIO2 | gpio_in, gpio_out From patchwork Fri Dec 1 13:44:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843490 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFv10DBvz9tBL for ; Sat, 2 Dec 2017 00:47:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753085AbdLANpx (ORCPT ); Fri, 1 Dec 2017 08:45:53 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36248 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752925AbdLANpv (ORCPT ); Fri, 1 Dec 2017 08:45:51 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id B14B3209F8; Fri, 1 Dec 2017 14:45:49 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 4FBB92095A; Fri, 1 Dec 2017 14:45:39 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 04/10] pinctrl: axp209: rename everything from gpio to pctl Date: Fri, 1 Dec 2017 14:44:45 +0100 Message-Id: <8ec986b24e2ae4af183e0753f5258a304de9a121.1512135804.git-series.quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This driver used to do only GPIO features of the GPIOs in X-Powers AXP20X. Now that we have migrated everything to the pinctrl subsystem and added pinctrl features, rename everything related to pinctrl from gpio to pctl to ease the understanding of differences between GPIO and pinctrl features. Signed-off-by: Quentin Schulz --- drivers/pinctrl/pinctrl-axp209.c | 180 ++++++++++++++++---------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c index 2dc286f..6201d2b 100644 --- a/drivers/pinctrl/pinctrl-axp209.c +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -57,7 +57,7 @@ struct axp20x_pinctrl_function { unsigned int ngroups; }; -struct axp20x_gpio { +struct axp20x_pctl { struct gpio_chip chip; struct regmap *regmap; struct pinctrl_dev *pctl_dev; @@ -100,11 +100,11 @@ static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset) static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) { - struct axp20x_gpio *gpio = gpiochip_get_data(chip); + struct axp20x_pctl *pctl = gpiochip_get_data(chip); unsigned int val; int ret; - ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val); + ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val); if (ret) return ret; @@ -113,7 +113,7 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) { - struct axp20x_gpio *gpio = gpiochip_get_data(chip); + struct axp20x_pctl *pctl = gpiochip_get_data(chip); unsigned int val; int reg, ret; @@ -121,7 +121,7 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) if (reg < 0) return reg; - ret = regmap_read(gpio->regmap, reg, &val); + ret = regmap_read(pctl->regmap, reg, &val); if (ret) return ret; @@ -151,14 +151,14 @@ static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset, static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - struct axp20x_gpio *gpio = gpiochip_get_data(chip); + struct axp20x_pctl *pctl = gpiochip_get_data(chip); int reg; reg = axp20x_gpio_get_reg(offset); if (reg < 0) return; - regmap_update_bits(gpio->regmap, reg, + regmap_update_bits(pctl->regmap, reg, AXP20X_GPIO_FUNCTIONS, value ? AXP20X_GPIO_FUNCTION_OUT_HIGH : AXP20X_GPIO_FUNCTION_OUT_LOW); @@ -167,30 +167,30 @@ static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset, static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset, u8 config) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); int reg; reg = axp20x_gpio_get_reg(offset); if (reg < 0) return reg; - return regmap_update_bits(gpio->regmap, reg, AXP20X_GPIO_FUNCTIONS, + return regmap_update_bits(pctl->regmap, reg, AXP20X_GPIO_FUNCTIONS, config); } static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - return ARRAY_SIZE(gpio->funcs); + return ARRAY_SIZE(pctl->funcs); } static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - return gpio->funcs[selector].name; + return pctl->funcs[selector].name; } static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev, @@ -198,10 +198,10 @@ static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev, const char * const **groups, unsigned int *num_groups) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - *groups = gpio->funcs[selector].groups; - *num_groups = gpio->funcs[selector].ngroups; + *groups = pctl->funcs[selector].groups; + *num_groups = pctl->funcs[selector].ngroups; return 0; } @@ -209,18 +209,18 @@ static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev, static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned int function, unsigned int group) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); unsigned int mask; /* Every pin supports GPIO_OUT and GPIO_IN functions */ if (function <= AXP20X_FUNC_GPIO_IN) return axp20x_pmx_set(pctldev, group, - gpio->funcs[function].muxval); + pctl->funcs[function].muxval); if (function == AXP20X_FUNC_LDO) - mask = gpio->desc->ldo_mask; + mask = pctl->desc->ldo_mask; else - mask = gpio->desc->adc_mask; + mask = pctl->desc->adc_mask; if (!(BIT(group) & mask)) return -EINVAL; @@ -234,21 +234,21 @@ static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev, if (function == AXP20X_FUNC_LDO) return 0; - return axp20x_pmx_set(pctldev, group, gpio->funcs[function].muxval); + return axp20x_pmx_set(pctldev, group, pctl->funcs[function].muxval); } static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset, bool input) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); if (input) return axp20x_pmx_set(pctldev, offset, - gpio->funcs[AXP20X_FUNC_GPIO_IN].muxval); + pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval); return axp20x_pmx_set(pctldev, offset, - gpio->funcs[AXP20X_FUNC_GPIO_OUT].muxval); + pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval); } static const struct pinmux_ops axp20x_pmx_ops = { @@ -262,17 +262,17 @@ static const struct pinmux_ops axp20x_pmx_ops = { static int axp20x_groups_cnt(struct pinctrl_dev *pctldev) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - return gpio->desc->npins; + return pctl->desc->npins; } static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, const unsigned int **pins, unsigned int *num_pins) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - *pins = (unsigned int *)&gpio->desc->pins[selector]; + *pins = (unsigned int *)&pctl->desc->pins[selector]; *num_pins = 1; return 0; @@ -281,9 +281,9 @@ static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, static const char *axp20x_group_name(struct pinctrl_dev *pctldev, unsigned int selector) { - struct axp20x_gpio *gpio = pinctrl_dev_get_drvdata(pctldev); + struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); - return gpio->desc->pins[selector].name; + return pctl->desc->pins[selector].name; } static const struct pinctrl_ops axp20x_pctrl_ops = { @@ -318,46 +318,46 @@ static void axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask, static void axp20x_build_funcs_groups(struct platform_device *pdev) { - struct axp20x_gpio *gpio = platform_get_drvdata(pdev); + struct axp20x_pctl *pctl = platform_get_drvdata(pdev); int i, pin; - gpio->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out"; - gpio->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT; - gpio->funcs[AXP20X_FUNC_GPIO_IN].name = "gpio_in"; - gpio->funcs[AXP20X_FUNC_GPIO_IN].muxval = AXP20X_MUX_GPIO_IN; - gpio->funcs[AXP20X_FUNC_LDO].name = "ldo"; + pctl->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out"; + pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT; + pctl->funcs[AXP20X_FUNC_GPIO_IN].name = "gpio_in"; + pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval = AXP20X_MUX_GPIO_IN; + pctl->funcs[AXP20X_FUNC_LDO].name = "ldo"; /* * Muxval for LDO is useless as we won't use it. * See comment in axp20x_pmx_set_mux. */ - gpio->funcs[AXP20X_FUNC_ADC].name = "adc"; - gpio->funcs[AXP20X_FUNC_ADC].muxval = AXP20X_MUX_ADC; + pctl->funcs[AXP20X_FUNC_ADC].name = "adc"; + pctl->funcs[AXP20X_FUNC_ADC].muxval = AXP20X_MUX_ADC; /* Every pin supports GPIO_OUT and GPIO_IN functions */ for (i = 0; i <= AXP20X_FUNC_GPIO_IN; i++) { - gpio->funcs[i].ngroups = gpio->desc->npins; - gpio->funcs[i].groups = devm_kzalloc(&pdev->dev, - gpio->desc->npins * sizeof(const char *), + pctl->funcs[i].ngroups = pctl->desc->npins; + pctl->funcs[i].groups = devm_kzalloc(&pdev->dev, + pctl->desc->npins * sizeof(const char *), GFP_KERNEL); - for (pin = 0; pin < gpio->desc->npins; pin++) - gpio->funcs[i].groups[pin] = gpio->desc->pins[pin].name; + for (pin = 0; pin < pctl->desc->npins; pin++) + pctl->funcs[i].groups[pin] = pctl->desc->pins[pin].name; } - axp20x_funcs_groups_from_mask(&pdev->dev, gpio->desc->ldo_mask, - gpio->desc->npins, - &gpio->funcs[AXP20X_FUNC_LDO], - gpio->desc->pins); + axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->ldo_mask, + pctl->desc->npins, + &pctl->funcs[AXP20X_FUNC_LDO], + pctl->desc->pins); - axp20x_funcs_groups_from_mask(&pdev->dev, gpio->desc->adc_mask, - gpio->desc->npins, - &gpio->funcs[AXP20X_FUNC_ADC], - gpio->desc->pins); + axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->adc_mask, + pctl->desc->npins, + &pctl->funcs[AXP20X_FUNC_ADC], + pctl->desc->pins); } -static int axp20x_gpio_probe(struct platform_device *pdev) +static int axp20x_pctl_probe(struct platform_device *pdev) { struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); - struct axp20x_gpio *gpio; + struct axp20x_pctl *pctl; struct pinctrl_desc *pctrl_desc; int ret; @@ -369,29 +369,29 @@ static int axp20x_gpio_probe(struct platform_device *pdev) return -EINVAL; } - gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); - if (!gpio) + pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); + if (!pctl) return -ENOMEM; - gpio->chip.base = -1; - gpio->chip.can_sleep = true; - gpio->chip.request = gpiochip_generic_request; - gpio->chip.free = gpiochip_generic_free; - gpio->chip.parent = &pdev->dev; - gpio->chip.label = dev_name(&pdev->dev); - gpio->chip.owner = THIS_MODULE; - gpio->chip.get = axp20x_gpio_get; - gpio->chip.get_direction = axp20x_gpio_get_direction; - gpio->chip.set = axp20x_gpio_set; - gpio->chip.direction_input = axp20x_gpio_input; - gpio->chip.direction_output = axp20x_gpio_output; - gpio->chip.ngpio = 3; - - gpio->desc = &axp20x_data; - gpio->regmap = axp20x->regmap; - gpio->dev = &pdev->dev; - - platform_set_drvdata(pdev, gpio); + pctl->chip.base = -1; + pctl->chip.can_sleep = true; + pctl->chip.request = gpiochip_generic_request; + pctl->chip.free = gpiochip_generic_free; + pctl->chip.parent = &pdev->dev; + pctl->chip.label = dev_name(&pdev->dev); + pctl->chip.owner = THIS_MODULE; + pctl->chip.get = axp20x_gpio_get; + pctl->chip.get_direction = axp20x_gpio_get_direction; + pctl->chip.set = axp20x_gpio_set; + pctl->chip.direction_input = axp20x_gpio_input; + pctl->chip.direction_output = axp20x_gpio_output; + pctl->chip.ngpio = 3; + + pctl->desc = &axp20x_data; + pctl->regmap = axp20x->regmap; + pctl->dev = &pdev->dev; + + platform_set_drvdata(pdev, pctl); axp20x_build_funcs_groups(pdev); @@ -401,27 +401,27 @@ static int axp20x_gpio_probe(struct platform_device *pdev) pctrl_desc->name = dev_name(&pdev->dev); pctrl_desc->owner = THIS_MODULE; - pctrl_desc->pins = gpio->desc->pins; - pctrl_desc->npins = gpio->desc->npins; + pctrl_desc->pins = pctl->desc->pins; + pctrl_desc->npins = pctl->desc->npins; pctrl_desc->pctlops = &axp20x_pctrl_ops; pctrl_desc->pmxops = &axp20x_pmx_ops; - gpio->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, gpio); - if (IS_ERR(gpio->pctl_dev)) { + pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl); + if (IS_ERR(pctl->pctl_dev)) { dev_err(&pdev->dev, "couldn't register pinctrl driver\n"); - return PTR_ERR(gpio->pctl_dev); + return PTR_ERR(pctl->pctl_dev); } - ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); + ret = devm_gpiochip_add_data(&pdev->dev, &pctl->chip, pctl); if (ret) { dev_err(&pdev->dev, "Failed to register GPIO chip\n"); return ret; } - ret = gpiochip_add_pin_range(&gpio->chip, dev_name(&pdev->dev), - gpio->desc->pins->number, - gpio->desc->pins->number, - gpio->desc->npins); + ret = gpiochip_add_pin_range(&pctl->chip, dev_name(&pdev->dev), + pctl->desc->pins->number, + pctl->desc->pins->number, + pctl->desc->npins); if (ret) { dev_err(&pdev->dev, "failed to add pin range\n"); return ret; @@ -432,21 +432,21 @@ static int axp20x_gpio_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id axp20x_gpio_match[] = { +static const struct of_device_id axp20x_pctl_match[] = { { .compatible = "x-powers,axp209-gpio" }, { } }; -MODULE_DEVICE_TABLE(of, axp20x_gpio_match); +MODULE_DEVICE_TABLE(of, axp20x_pctl_match); -static struct platform_driver axp20x_gpio_driver = { - .probe = axp20x_gpio_probe, +static struct platform_driver axp20x_pctl_driver = { + .probe = axp20x_pctl_probe, .driver = { .name = "axp20x-gpio", - .of_match_table = axp20x_gpio_match, + .of_match_table = axp20x_pctl_match, }, }; -module_platform_driver(axp20x_gpio_driver); +module_platform_driver(axp20x_pctl_driver); MODULE_AUTHOR("Maxime Ripard "); MODULE_AUTHOR("Quentin Schulz "); From patchwork Fri Dec 1 13:44:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843488 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFtb5GjJz9tBL for ; Sat, 2 Dec 2017 00:46:47 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752925AbdLANpy (ORCPT ); Fri, 1 Dec 2017 08:45:54 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36265 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752919AbdLANpw (ORCPT ); Fri, 1 Dec 2017 08:45:52 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 0478E209F0; Fri, 1 Dec 2017 14:45:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 9CA1920986; Fri, 1 Dec 2017 14:45:39 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 05/10] pinctrl: axp209: add programmable gpio_status_offset Date: Fri, 1 Dec 2017 14:44:46 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org To prepare for patches that will add support for a new PMIC that has a different GPIO input status register, add a gpio_status_offset within axp20x_pctl structure and use it. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard Acked-by: Chen-Yu Tsai --- drivers/pinctrl/pinctrl-axp209.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c index 6201d2b..3fae81f 100644 --- a/drivers/pinctrl/pinctrl-axp209.c +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -48,6 +48,7 @@ struct axp20x_pctrl_desc { u8 ldo_mask; /* Stores the pins supporting ADC function. Bit offset is pin number. */ u8 adc_mask; + u8 gpio_status_offset; }; struct axp20x_pinctrl_function { @@ -77,6 +78,7 @@ static const struct axp20x_pctrl_desc axp20x_data = { .npins = ARRAY_SIZE(axp209_pins), .ldo_mask = BIT(0) | BIT(1), .adc_mask = BIT(0) | BIT(1), + .gpio_status_offset = 4, }; static int axp20x_gpio_get_reg(unsigned offset) @@ -108,7 +110,7 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset) if (ret) return ret; - return !!(val & BIT(offset + 4)); + return !!(val & BIT(offset + pctl->desc->gpio_status_offset)); } static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) From patchwork Fri Dec 1 13:44:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843496 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFwm5wXwz9tBL for ; Sat, 2 Dec 2017 00:48:40 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753011AbdLANrP (ORCPT ); Fri, 1 Dec 2017 08:47:15 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36264 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752935AbdLANpw (ORCPT ); Fri, 1 Dec 2017 08:45:52 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 510FD20C91; Fri, 1 Dec 2017 14:45:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id EB46A20989; Fri, 1 Dec 2017 14:45:39 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 06/10] pinctrl: axp209: add programmable ADC muxing value Date: Fri, 1 Dec 2017 14:44:47 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org To prepare for patches that will add support for a new PMIC that has a different GPIO adc muxing value, add an adc_mux within axp20x_pctl structure and use it. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard --- drivers/pinctrl/pinctrl-axp209.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c index 3fae81f..504e96c 100644 --- a/drivers/pinctrl/pinctrl-axp209.c +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -49,6 +49,7 @@ struct axp20x_pctrl_desc { /* Stores the pins supporting ADC function. Bit offset is pin number. */ u8 adc_mask; u8 gpio_status_offset; + u8 adc_mux; }; struct axp20x_pinctrl_function { @@ -79,6 +80,7 @@ static const struct axp20x_pctrl_desc axp20x_data = { .ldo_mask = BIT(0) | BIT(1), .adc_mask = BIT(0) | BIT(1), .gpio_status_offset = 4, + .adc_mux = AXP20X_MUX_ADC, }; static int axp20x_gpio_get_reg(unsigned offset) @@ -333,7 +335,7 @@ static void axp20x_build_funcs_groups(struct platform_device *pdev) * See comment in axp20x_pmx_set_mux. */ pctl->funcs[AXP20X_FUNC_ADC].name = "adc"; - pctl->funcs[AXP20X_FUNC_ADC].muxval = AXP20X_MUX_ADC; + pctl->funcs[AXP20X_FUNC_ADC].muxval = pctl->desc->adc_mux; /* Every pin supports GPIO_OUT and GPIO_IN functions */ for (i = 0; i <= AXP20X_FUNC_GPIO_IN; i++) { From patchwork Fri Dec 1 13:44:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843491 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFv84s67z9tBR for ; Sat, 2 Dec 2017 00:47:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752966AbdLANrP (ORCPT ); Fri, 1 Dec 2017 08:47:15 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36275 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753027AbdLANpx (ORCPT ); Fri, 1 Dec 2017 08:45:53 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id A3C3C20C8E; Fri, 1 Dec 2017 14:45:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 4443B20999; Fri, 1 Dec 2017 14:45:40 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 07/10] pinctrl: axp209: add support for AXP813 GPIOs Date: Fri, 1 Dec 2017 14:44:48 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The AXP813 has only two GPIOs. GPIO0 can either be used as a GPIO, an LDO regulator or an ADC. GPIO1 can be used either as a GPIO or an LDO regulator. Moreover, the status bit of the GPIOs when in input mode is not offset by 4 unlike the AXP209. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard Acked-by: Rob Herring --- Documentation/devicetree/bindings/gpio/gpio-axp209.txt | 13 +++- drivers/pinctrl/pinctrl-axp209.c | 35 ++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt index 4705020..1bbf7ab 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt @@ -4,7 +4,9 @@ This driver follows the usual GPIO bindings found in Documentation/devicetree/bindings/gpio/gpio.txt Required properties: -- compatible: Should be "x-powers,axp209-gpio" +- compatible: Should be one of: + - "x-powers,axp209-gpio" + - "x-powers,axp813-gpio" - #gpio-cells: Should be two. The first cell is the pin number and the second is the GPIO flags. - gpio-controller: Marks the device node as a GPIO controller. @@ -49,8 +51,17 @@ Example: GPIOs and their functions ------------------------- +axp209 +------ GPIO | Functions ------------------------ GPIO0 | gpio_in, gpio_out, ldo, adc GPIO1 | gpio_in, gpio_out, ldo, adc GPIO2 | gpio_in, gpio_out + +axp813 +------ +GPIO | Functions +------------------------ +GPIO0 | gpio_in, gpio_out, ldo, adc +GPIO1 | gpio_in, gpio_out, ldo diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c index 504e96c..5f1278f 100644 --- a/drivers/pinctrl/pinctrl-axp209.c +++ b/drivers/pinctrl/pinctrl-axp209.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,8 @@ #define AXP20X_MUX_GPIO_IN BIT(1) #define AXP20X_MUX_ADC BIT(2) +#define AXP813_MUX_ADC (BIT(2) | BIT(0)) + struct axp20x_pctrl_desc { const struct pinctrl_pin_desc *pins; unsigned int npins; @@ -74,6 +77,11 @@ static const struct pinctrl_pin_desc axp209_pins[] = { PINCTRL_PIN(2, "GPIO2"), }; +static const struct pinctrl_pin_desc axp813_pins[] = { + PINCTRL_PIN(0, "GPIO0"), + PINCTRL_PIN(1, "GPIO1"), +}; + static const struct axp20x_pctrl_desc axp20x_data = { .pins = axp209_pins, .npins = ARRAY_SIZE(axp209_pins), @@ -83,6 +91,15 @@ static const struct axp20x_pctrl_desc axp20x_data = { .adc_mux = AXP20X_MUX_ADC, }; +static const struct axp20x_pctrl_desc axp813_data = { + .pins = axp813_pins, + .npins = ARRAY_SIZE(axp813_pins), + .ldo_mask = BIT(0) | BIT(1), + .adc_mask = BIT(0), + .gpio_status_offset = 0, + .adc_mux = AXP813_MUX_ADC, +}; + static int axp20x_gpio_get_reg(unsigned offset) { switch (offset) { @@ -358,10 +375,18 @@ static void axp20x_build_funcs_groups(struct platform_device *pdev) pctl->desc->pins); } +static const struct of_device_id axp20x_pctl_match[] = { + { .compatible = "x-powers,axp209-gpio", .data = &axp20x_data, }, + { .compatible = "x-powers,axp813-gpio", .data = &axp813_data, }, + { } +}; +MODULE_DEVICE_TABLE(of, axp20x_pctl_match); + static int axp20x_pctl_probe(struct platform_device *pdev) { struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct axp20x_pctl *pctl; + struct device *dev = &pdev->dev; struct pinctrl_desc *pctrl_desc; int ret; @@ -389,9 +414,9 @@ static int axp20x_pctl_probe(struct platform_device *pdev) pctl->chip.set = axp20x_gpio_set; pctl->chip.direction_input = axp20x_gpio_input; pctl->chip.direction_output = axp20x_gpio_output; - pctl->chip.ngpio = 3; + pctl->chip.ngpio = pctl->desc->npins; - pctl->desc = &axp20x_data; + pctl->desc = (struct axp20x_pctrl_desc *)of_device_get_match_data(dev); pctl->regmap = axp20x->regmap; pctl->dev = &pdev->dev; @@ -436,12 +461,6 @@ static int axp20x_pctl_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id axp20x_pctl_match[] = { - { .compatible = "x-powers,axp209-gpio" }, - { } -}; -MODULE_DEVICE_TABLE(of, axp20x_pctl_match); - static struct platform_driver axp20x_pctl_driver = { .probe = axp20x_pctl_probe, .driver = { From patchwork Fri Dec 1 13:44:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843489 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFts5HX9z9tBX for ; Sat, 2 Dec 2017 00:47:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752877AbdLANqq (ORCPT ); Fri, 1 Dec 2017 08:46:46 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36285 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752781AbdLANpz (ORCPT ); Fri, 1 Dec 2017 08:45:55 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 3A7AA2099A; Fri, 1 Dec 2017 14:45:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 91ACB2099A; Fri, 1 Dec 2017 14:45:40 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 08/10] mfd: axp20x: add pinctrl cell for AXP813 Date: Fri, 1 Dec 2017 14:44:49 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org As GPIO/pinctrl driver now supports AXP813, add a cell for it. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard Acked-by: Linus Walleij --- drivers/mfd/axp20x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 2468b43..d8c92fb 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -878,6 +878,9 @@ static struct mfd_cell axp813_cells[] = { .resources = axp803_pek_resources, }, { .name = "axp20x-regulator", + }, { + .name = "axp20x-gpio", + .of_compatible = "x-powers,axp813-gpio", } }; From patchwork Fri Dec 1 13:44:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843487 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFtZ0HGdz9tBL for ; Sat, 2 Dec 2017 00:46:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752844AbdLANqZ (ORCPT ); Fri, 1 Dec 2017 08:46:25 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36283 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753095AbdLANpz (ORCPT ); Fri, 1 Dec 2017 08:45:55 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 39AB320D66; Fri, 1 Dec 2017 14:45:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id E9CD4209B2; Fri, 1 Dec 2017 14:45:40 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 09/10] ARM: dtsi: axp81x: add GPIO DT node Date: Fri, 1 Dec 2017 14:44:50 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This adds DT node for the GPIO/pinctrl part present in AXP813/AXP818. Signed-off-by: Quentin Schulz Acked-by: Linus Walleij Acked-by: Chen-Yu Tsai --- arch/arm/boot/dts/axp81x.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi index 73b761f..0ef959d 100644 --- a/arch/arm/boot/dts/axp81x.dtsi +++ b/arch/arm/boot/dts/axp81x.dtsi @@ -48,6 +48,12 @@ interrupt-controller; #interrupt-cells = <1>; + axp_gpio: axp-gpio { + compatible = "x-powers,axp813-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <3000>; From patchwork Fri Dec 1 13:44:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 843485 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ypFsl0fyvz9tBL for ; Sat, 2 Dec 2017 00:46:03 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752937AbdLANqB (ORCPT ); Fri, 1 Dec 2017 08:46:01 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:36294 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752916AbdLANp7 (ORCPT ); Fri, 1 Dec 2017 08:45:59 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 37915213DC; Fri, 1 Dec 2017 14:45:57 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 45377209BB; Fri, 1 Dec 2017 14:45:41 +0100 (CET) From: Quentin Schulz To: linus.walleij@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, Quentin Schulz Subject: [PATCH v4 10/10] ARM: dtsi: axp81x: set pinmux for GPIO0/1 when used as LDOs Date: Fri, 1 Dec 2017 14:44:51 +0100 Message-Id: X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org On AXP813/818, GPIO0 and GPIO1 can be used as LDO as (respectively) ldo_io0 and ldo_io1. Let's add the pinctrl properties to the said regulators. Signed-off-by: Quentin Schulz Acked-by: Maxime Ripard Acked-by: Chen-Yu Tsai --- arch/arm/boot/dts/axp81x.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi index 0ef959d..fd55b89 100644 --- a/arch/arm/boot/dts/axp81x.dtsi +++ b/arch/arm/boot/dts/axp81x.dtsi @@ -52,6 +52,16 @@ compatible = "x-powers,axp813-gpio"; gpio-controller; #gpio-cells = <2>; + + gpio0_ldo: gpio0-ldo { + pins = "GPIO0"; + function = "ldo"; + }; + + gpio1_ldo: gpio1-ldo { + pins = "GPIO1"; + function = "ldo"; + }; }; regulators { @@ -119,11 +129,15 @@ }; reg_ldo_io0: ldo-io0 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_ldo>; /* Disable by default to avoid conflicts with GPIO */ status = "disabled"; }; reg_ldo_io1: ldo-io1 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_ldo>; /* Disable by default to avoid conflicts with GPIO */ status = "disabled"; };