From: Gregory CLEMENT <gregory.clement@free-electrons.com> To: Linus Walleij <linus.walleij@linaro.org>, linux-gpio@vger.kernel.org Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory CLEMENT <gregory.clement@free-electrons.com>, Thomas Petazzoni <thomas.petazzoni@free-electrons.com>, linux-arm-kernel@lists.infradead.org, Nadav Haklai <nadavh@marvell.com>, Victor Gu <xigu@marvell.com>, Omri Itach <omrii@marvell.com>, Marcin Wojtas <mw@semihalf.com>, Wilson Ding <dingwei@marvell.com>, Hua Jing <jinghua@marvell.com>, Terry Zhou <bjzhou@marvell.com> Subject: [PATCH 3/6] pinctrl: armada-37xx: Add gpio support Date: Thu, 22 Dec 2016 18:24:58 +0100 [thread overview] Message-ID: <20161222172501.16121-4-gregory.clement@free-electrons.com> (raw) In-Reply-To: <20161222172501.16121-1-gregory.clement@free-electrons.com> GPIO management is pretty simple and is part of the same IP than the pin controller for the Armada 37xx SoCs. This patch adds the GPIO support to the pinctrl-armada-37xx.c file, it also allows sharing common functions between the gpiolib and the pinctrl drivers. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 113 ++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 021bfe793af3..4d9571b49ad1 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -10,6 +10,7 @@ * without any warranty of any kind, whether express or implied. */ +#include <linux/gpio/driver.h> #include <linux/mfd/syscon.h> #include <linux/of.h> #include <linux/of_device.h> @@ -24,6 +25,8 @@ #include "../pinctrl-utils.h" #define OUTPUT_EN 0x0 +#define INPUT_VAL 0x10 +#define OUTPUT_VAL 0x18 #define OUTPUT_CTL 0x20 #define SELECTION 0x30 @@ -60,6 +63,7 @@ struct armada_37xx_pinctrl { struct regmap *regmap; struct armada_37xx_pin_data *data; struct device *dev; + struct gpio_chip gpio_chip; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; struct armada_37xx_pin_group *groups; @@ -297,9 +301,10 @@ static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev, return armada_37xx_pmx_set_by_name(pctldev, name, grp); } -static int armada_37xx_pmx_direction_input(struct armada_37xx_pinctrl *info, - unsigned int offset) +static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) { + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = OUTPUT_EN; unsigned int mask; @@ -312,11 +317,28 @@ static int armada_37xx_pmx_direction_input(struct armada_37xx_pinctrl *info, return regmap_update_bits(info->regmap, reg, mask, 0); } +static int armada_37xx_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = OUTPUT_EN; + unsigned int val, mask; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + + regmap_read(info->regmap, reg, &val); + return (val & mask) == 0; +} -static int armada_37xx_pmx_direction_output(struct armada_37xx_pinctrl *info, - unsigned int offset, int value) +static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) { + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = OUTPUT_EN; unsigned int mask; @@ -329,19 +351,54 @@ static int armada_37xx_pmx_direction_output(struct armada_37xx_pinctrl *info, return regmap_update_bits(info->regmap, reg, mask, mask); } +static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = INPUT_VAL; + unsigned int val, mask; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + + regmap_read(info->regmap, reg, &val); + + return (val & mask) != 0; +} + +static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = OUTPUT_VAL; + unsigned int mask, val; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + val = value ? mask : 0; + + regmap_update_bits(info->regmap, reg, mask, val); +} + static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset, bool input) { struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct gpio_chip *chip = range->gc; dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", offset, range->name, offset, input ? "input" : "output"); if (input) - armada_37xx_pmx_direction_input(info, offset); + armada_37xx_gpio_direction_input(chip, offset); else - armada_37xx_pmx_direction_output(info, offset, 0); + armada_37xx_gpio_direction_output(chip, offset, 0); return 0; } @@ -371,6 +428,39 @@ static const struct pinmux_ops armada_37xx_pmx_ops = { .gpio_set_direction = armada_37xx_pmx_gpio_set_direction, }; +static const struct gpio_chip armada_37xx_gpiolib_chip = { + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .set = armada_37xx_gpio_set, + .get = armada_37xx_gpio_get, + .get_direction = armada_37xx_gpio_get_direction, + .direction_input = armada_37xx_gpio_direction_input, + .direction_output = armada_37xx_gpio_direction_output, + .owner = THIS_MODULE, +}; + +static int armada_37xx_gpiolib_register(struct platform_device *pdev, + struct armada_37xx_pinctrl *info) +{ + struct gpio_chip *gc; + int ret; + + info->gpio_chip = armada_37xx_gpiolib_chip; + + gc = &info->gpio_chip; + gc->ngpio = info->data->nr_pins; + gc->parent = &pdev->dev; + gc->base = -1; + gc->of_node = info->dev->of_node; + gc->label = info->data->name; + + ret = gpiochip_add_data(gc, info); + if (ret) + return ret; + + return 0; +} + static int _add_function(struct armada_37xx_pmx_func *funcs, int *funcsize, const char *name) { @@ -551,7 +641,7 @@ static int armada_37xx_pinctrl_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct regmap *regmap; - int ret; + int ret, pinbase = global_pin; info = devm_kzalloc(dev, sizeof(struct armada_37xx_pinctrl), GFP_KERNEL); @@ -570,10 +660,19 @@ static int armada_37xx_pinctrl_probe(struct platform_device *pdev) match = of_match_node(armada_37xx_pinctrl_of_match, np); info->data = (struct armada_37xx_pin_data *)match->data; + ret = armada_37xx_gpiolib_register(pdev, info); + if (ret) + return ret; + ret = armada_37xx_pinctrl_register(pdev, info); if (ret) return ret; + ret = gpiochip_add_pin_range(&info->gpio_chip, dev_name(dev), 0, + pinbase, info->data->nr_pins); + if (ret) + return ret; + platform_set_drvdata(pdev, info); return 0; -- 2.11.0
WARNING: multiple messages have this Message-ID (diff)
From: gregory.clement@free-electrons.com (Gregory CLEMENT) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 3/6] pinctrl: armada-37xx: Add gpio support Date: Thu, 22 Dec 2016 18:24:58 +0100 [thread overview] Message-ID: <20161222172501.16121-4-gregory.clement@free-electrons.com> (raw) In-Reply-To: <20161222172501.16121-1-gregory.clement@free-electrons.com> GPIO management is pretty simple and is part of the same IP than the pin controller for the Armada 37xx SoCs. This patch adds the GPIO support to the pinctrl-armada-37xx.c file, it also allows sharing common functions between the gpiolib and the pinctrl drivers. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 113 ++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 021bfe793af3..4d9571b49ad1 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -10,6 +10,7 @@ * without any warranty of any kind, whether express or implied. */ +#include <linux/gpio/driver.h> #include <linux/mfd/syscon.h> #include <linux/of.h> #include <linux/of_device.h> @@ -24,6 +25,8 @@ #include "../pinctrl-utils.h" #define OUTPUT_EN 0x0 +#define INPUT_VAL 0x10 +#define OUTPUT_VAL 0x18 #define OUTPUT_CTL 0x20 #define SELECTION 0x30 @@ -60,6 +63,7 @@ struct armada_37xx_pinctrl { struct regmap *regmap; struct armada_37xx_pin_data *data; struct device *dev; + struct gpio_chip gpio_chip; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; struct armada_37xx_pin_group *groups; @@ -297,9 +301,10 @@ static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev, return armada_37xx_pmx_set_by_name(pctldev, name, grp); } -static int armada_37xx_pmx_direction_input(struct armada_37xx_pinctrl *info, - unsigned int offset) +static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) { + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = OUTPUT_EN; unsigned int mask; @@ -312,11 +317,28 @@ static int armada_37xx_pmx_direction_input(struct armada_37xx_pinctrl *info, return regmap_update_bits(info->regmap, reg, mask, 0); } +static int armada_37xx_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = OUTPUT_EN; + unsigned int val, mask; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + + regmap_read(info->regmap, reg, &val); + return (val & mask) == 0; +} -static int armada_37xx_pmx_direction_output(struct armada_37xx_pinctrl *info, - unsigned int offset, int value) +static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) { + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); unsigned int reg = OUTPUT_EN; unsigned int mask; @@ -329,19 +351,54 @@ static int armada_37xx_pmx_direction_output(struct armada_37xx_pinctrl *info, return regmap_update_bits(info->regmap, reg, mask, mask); } +static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = INPUT_VAL; + unsigned int val, mask; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + + regmap_read(info->regmap, reg, &val); + + return (val & mask) != 0; +} + +static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); + unsigned int reg = OUTPUT_VAL; + unsigned int mask, val; + + if (offset >= GPIO_PER_REG) { + offset -= GPIO_PER_REG; + reg += sizeof(u32); + } + mask = BIT(offset); + val = value ? mask : 0; + + regmap_update_bits(info->regmap, reg, mask, val); +} + static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset, bool input) { struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct gpio_chip *chip = range->gc; dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", offset, range->name, offset, input ? "input" : "output"); if (input) - armada_37xx_pmx_direction_input(info, offset); + armada_37xx_gpio_direction_input(chip, offset); else - armada_37xx_pmx_direction_output(info, offset, 0); + armada_37xx_gpio_direction_output(chip, offset, 0); return 0; } @@ -371,6 +428,39 @@ static const struct pinmux_ops armada_37xx_pmx_ops = { .gpio_set_direction = armada_37xx_pmx_gpio_set_direction, }; +static const struct gpio_chip armada_37xx_gpiolib_chip = { + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .set = armada_37xx_gpio_set, + .get = armada_37xx_gpio_get, + .get_direction = armada_37xx_gpio_get_direction, + .direction_input = armada_37xx_gpio_direction_input, + .direction_output = armada_37xx_gpio_direction_output, + .owner = THIS_MODULE, +}; + +static int armada_37xx_gpiolib_register(struct platform_device *pdev, + struct armada_37xx_pinctrl *info) +{ + struct gpio_chip *gc; + int ret; + + info->gpio_chip = armada_37xx_gpiolib_chip; + + gc = &info->gpio_chip; + gc->ngpio = info->data->nr_pins; + gc->parent = &pdev->dev; + gc->base = -1; + gc->of_node = info->dev->of_node; + gc->label = info->data->name; + + ret = gpiochip_add_data(gc, info); + if (ret) + return ret; + + return 0; +} + static int _add_function(struct armada_37xx_pmx_func *funcs, int *funcsize, const char *name) { @@ -551,7 +641,7 @@ static int armada_37xx_pinctrl_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct regmap *regmap; - int ret; + int ret, pinbase = global_pin; info = devm_kzalloc(dev, sizeof(struct armada_37xx_pinctrl), GFP_KERNEL); @@ -570,10 +660,19 @@ static int armada_37xx_pinctrl_probe(struct platform_device *pdev) match = of_match_node(armada_37xx_pinctrl_of_match, np); info->data = (struct armada_37xx_pin_data *)match->data; + ret = armada_37xx_gpiolib_register(pdev, info); + if (ret) + return ret; + ret = armada_37xx_pinctrl_register(pdev, info); if (ret) return ret; + ret = gpiochip_add_pin_range(&info->gpio_chip, dev_name(dev), 0, + pinbase, info->data->nr_pins); + if (ret) + return ret; + platform_set_drvdata(pdev, info); return 0; -- 2.11.0
next prev parent reply other threads:[~2016-12-22 17:25 UTC|newest] Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-12-22 17:24 [PATCH 0/6] Add support for pinctrl/gpio on Armada 37xx Gregory CLEMENT 2016-12-22 17:24 ` Gregory CLEMENT 2016-12-22 17:24 ` [PATCH 1/6] pinctrl: dt-bindings: Add documentation for Armada 37xx pin controllers Gregory CLEMENT 2016-12-22 17:24 ` Gregory CLEMENT 2016-12-30 8:35 ` Linus Walleij 2016-12-30 8:35 ` Linus Walleij 2017-03-22 11:42 ` Gregory CLEMENT 2017-03-22 11:42 ` Gregory CLEMENT 2016-12-22 17:24 ` [PATCH 2/6] pinctrl: armada-37xx: Add pin controller support for Armada 37xx Gregory CLEMENT 2016-12-22 17:24 ` Gregory CLEMENT 2016-12-30 8:44 ` Linus Walleij 2016-12-30 8:44 ` Linus Walleij 2017-03-22 11:47 ` Gregory CLEMENT 2017-03-22 11:47 ` Gregory CLEMENT 2016-12-22 17:24 ` Gregory CLEMENT [this message] 2016-12-22 17:24 ` [PATCH 3/6] pinctrl: armada-37xx: Add gpio support Gregory CLEMENT 2016-12-30 8:51 ` Linus Walleij 2016-12-30 8:51 ` Linus Walleij 2017-03-22 11:54 ` Gregory CLEMENT 2017-03-22 11:54 ` Gregory CLEMENT 2017-03-23 10:28 ` Linus Walleij 2017-03-23 10:28 ` Linus Walleij 2017-03-23 14:47 ` Gregory CLEMENT 2017-03-23 14:47 ` Gregory CLEMENT 2016-12-22 17:24 ` [PATCH 4/6] pinctrl: aramda-37xx: Add irqchip support Gregory CLEMENT 2016-12-22 17:24 ` Gregory CLEMENT 2016-12-30 8:58 ` Linus Walleij 2016-12-30 8:58 ` Linus Walleij 2017-03-22 12:02 ` Gregory CLEMENT 2017-03-22 12:02 ` Gregory CLEMENT 2017-03-23 10:36 ` Linus Walleij 2017-03-23 10:36 ` Linus Walleij 2017-03-23 14:41 ` Gregory CLEMENT 2017-03-23 14:41 ` Gregory CLEMENT 2016-12-22 17:25 ` [PATCH 5/6] ARM64: dts: marvell: Add pinctrl nodes for Armada 3700 Gregory CLEMENT 2016-12-22 17:25 ` Gregory CLEMENT 2016-12-22 17:25 ` [PATCH 6/6] ARM64: dts: marvell: armada37xx: add pinctrl definition Gregory CLEMENT 2016-12-22 17:25 ` Gregory CLEMENT 2016-12-30 9:00 ` Linus Walleij 2016-12-30 9:00 ` Linus Walleij
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20161222172501.16121-4-gregory.clement@free-electrons.com \ --to=gregory.clement@free-electrons.com \ --cc=andrew@lunn.ch \ --cc=bjzhou@marvell.com \ --cc=dingwei@marvell.com \ --cc=jason@lakedaemon.net \ --cc=jinghua@marvell.com \ --cc=linus.walleij@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-gpio@vger.kernel.org \ --cc=mw@semihalf.com \ --cc=nadavh@marvell.com \ --cc=omrii@marvell.com \ --cc=sebastian.hesselbarth@gmail.com \ --cc=thomas.petazzoni@free-electrons.com \ --cc=xigu@marvell.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.