2019-06-01 10:08:55 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
/*
|
|
|
|
* Marvell PXA2xx family pin control
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015 Robert Jarzmik
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/bitops.h>
|
|
|
|
#include <linux/io.h>
|
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/of_address.h>
|
|
|
|
#include <linux/module.h>
|
2020-02-03 17:34:55 -08:00
|
|
|
#include <linux/pinctrl/machine.h>
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
#include <linux/pinctrl/pinconf.h>
|
|
|
|
#include <linux/pinctrl/pinconf-generic.h>
|
|
|
|
#include <linux/pinctrl/pinmux.h>
|
|
|
|
#include <linux/pinctrl/pinctrl.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
|
|
|
|
#include "../pinctrl-utils.h"
|
|
|
|
#include "pinctrl-pxa2xx.h"
|
|
|
|
|
|
|
|
static int pxa2xx_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
|
|
|
|
|
|
|
return pctl->ngroups;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned tgroup)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *group = pctl->groups + tgroup;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
|
|
|
return group->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned tgroup,
|
|
|
|
const unsigned **pins,
|
|
|
|
unsigned *num_pins)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *group = pctl->groups + tgroup;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
2024-03-11 16:22:48 +02:00
|
|
|
*pins = group->pins;
|
|
|
|
*num_pins = group->npins;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct pinctrl_ops pxa2xx_pctl_ops = {
|
|
|
|
#ifdef CONFIG_OF
|
|
|
|
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
|
2016-03-31 14:44:42 +03:00
|
|
|
.dt_free_map = pinctrl_utils_free_map,
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
#endif
|
|
|
|
.get_groups_count = pxa2xx_pctrl_get_groups_count,
|
|
|
|
.get_group_name = pxa2xx_pctrl_get_group_name,
|
|
|
|
.get_group_pins = pxa2xx_pctrl_get_group_pins,
|
|
|
|
};
|
|
|
|
|
2015-11-21 19:04:50 +01:00
|
|
|
static struct pxa_desc_function *
|
|
|
|
pxa_desc_by_func_group(struct pxa_pinctrl *pctl, const char *pin_name,
|
|
|
|
const char *func_name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct pxa_desc_function *df;
|
|
|
|
|
|
|
|
for (i = 0; i < pctl->npins; i++) {
|
|
|
|
const struct pxa_desc_pin *pin = pctl->ppins + i;
|
|
|
|
|
|
|
|
if (!strcmp(pin->pin.name, pin_name))
|
|
|
|
for (df = pin->functions; df->name; df++)
|
|
|
|
if (!strcmp(df->name, func_name))
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
|
|
|
struct pinctrl_gpio_range *range,
|
|
|
|
unsigned pin,
|
|
|
|
bool input)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
|
|
|
unsigned long flags;
|
|
|
|
uint32_t val;
|
|
|
|
void __iomem *gpdr;
|
|
|
|
|
|
|
|
gpdr = pctl->base_gpdr[pin / 32];
|
|
|
|
dev_dbg(pctl->dev, "set_direction(pin=%d): dir=%d\n",
|
|
|
|
pin, !input);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&pctl->lock, flags);
|
|
|
|
|
|
|
|
val = readl_relaxed(gpdr);
|
|
|
|
val = (val & ~BIT(pin % 32)) | (input ? 0 : BIT(pin % 32));
|
|
|
|
writel_relaxed(val, gpdr);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&pctl->lock, flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned function)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:08:33 +02:00
|
|
|
struct pinfunction *pf = pctl->functions + function;
|
2015-11-21 19:04:50 +01:00
|
|
|
|
|
|
|
return pf->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_get_functions_count(struct pinctrl_dev *pctldev)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
|
|
|
|
|
|
|
return pctl->nfuncs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned function,
|
|
|
|
const char * const **groups,
|
|
|
|
unsigned * const num_groups)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:08:33 +02:00
|
|
|
struct pinfunction *pf = pctl->functions + function;
|
2015-11-21 19:04:50 +01:00
|
|
|
|
|
|
|
*groups = pf->groups;
|
|
|
|
*num_groups = pf->ngroups;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
|
|
|
|
unsigned tgroup)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *g = pctl->groups + tgroup;
|
|
|
|
unsigned int pin = g->pins[0];
|
2015-11-21 19:04:50 +01:00
|
|
|
struct pxa_desc_function *df;
|
|
|
|
unsigned long flags;
|
|
|
|
void __iomem *gafr, *gpdr;
|
2024-03-11 16:22:48 +02:00
|
|
|
int shift;
|
2015-11-21 19:04:50 +01:00
|
|
|
u32 val;
|
|
|
|
|
2024-03-11 16:22:48 +02:00
|
|
|
df = pxa_desc_by_func_group(pctl, g->name, (pctl->functions + function)->name);
|
2015-11-21 19:04:50 +01:00
|
|
|
if (!df)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
gafr = pctl->base_gafr[pin / 16];
|
|
|
|
gpdr = pctl->base_gpdr[pin / 32];
|
|
|
|
shift = (pin % 16) << 1;
|
|
|
|
dev_dbg(pctl->dev, "set_mux(pin=%d): af=%d dir=%d\n",
|
|
|
|
pin, df->muxval >> 1, df->muxval & 0x1);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&pctl->lock, flags);
|
|
|
|
|
|
|
|
val = readl_relaxed(gafr);
|
|
|
|
val = (val & ~(0x3 << shift)) | ((df->muxval >> 1) << shift);
|
|
|
|
writel_relaxed(val, gafr);
|
|
|
|
|
|
|
|
val = readl_relaxed(gpdr);
|
|
|
|
val = (val & ~BIT(pin % 32)) | ((df->muxval & 1) ? BIT(pin % 32) : 0);
|
|
|
|
writel_relaxed(val, gpdr);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&pctl->lock, flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static const struct pinmux_ops pxa2xx_pinmux_ops = {
|
|
|
|
.get_functions_count = pxa2xx_get_functions_count,
|
|
|
|
.get_function_name = pxa2xx_pmx_get_func_name,
|
|
|
|
.get_function_groups = pxa2xx_pmx_get_func_groups,
|
|
|
|
.set_mux = pxa2xx_pmx_set_mux,
|
|
|
|
.gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
|
|
|
|
};
|
|
|
|
|
2015-11-21 19:04:51 +01:00
|
|
|
static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned group,
|
|
|
|
unsigned long *config)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *g = pctl->groups + group;
|
|
|
|
unsigned int pin = g->pins[0];
|
2015-11-21 19:04:51 +01:00
|
|
|
unsigned long flags;
|
|
|
|
void __iomem *pgsr = pctl->base_pgsr[pin / 32];
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&pctl->lock, flags);
|
|
|
|
val = readl_relaxed(pgsr) & BIT(pin % 32);
|
2021-04-12 17:07:40 +03:00
|
|
|
*config = val ? PIN_CONFIG_MODE_LOW_POWER : 0;
|
2015-11-21 19:04:51 +01:00
|
|
|
spin_unlock_irqrestore(&pctl->lock, flags);
|
|
|
|
|
|
|
|
dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n",
|
|
|
|
pin, !!val);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev,
|
|
|
|
unsigned group,
|
|
|
|
unsigned long *configs,
|
|
|
|
unsigned num_configs)
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *g = pctl->groups + group;
|
|
|
|
unsigned int pin = g->pins[0];
|
2015-11-21 19:04:51 +01:00
|
|
|
unsigned long flags;
|
|
|
|
void __iomem *pgsr = pctl->base_pgsr[pin / 32];
|
|
|
|
int i, is_set = 0;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
for (i = 0; i < num_configs; i++) {
|
|
|
|
switch (pinconf_to_config_param(configs[i])) {
|
2021-04-12 17:07:40 +03:00
|
|
|
case PIN_CONFIG_MODE_LOW_POWER:
|
2015-11-21 19:04:51 +01:00
|
|
|
is_set = pinconf_to_config_argument(configs[i]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dev_dbg(pctl->dev, "set sleep gpio state(pin=%d) %d\n",
|
|
|
|
pin, is_set);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&pctl->lock, flags);
|
|
|
|
val = readl_relaxed(pgsr);
|
|
|
|
val = (val & ~BIT(pin % 32)) | (is_set ? BIT(pin % 32) : 0);
|
|
|
|
writel_relaxed(val, pgsr);
|
|
|
|
spin_unlock_irqrestore(&pctl->lock, flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct pinconf_ops pxa2xx_pconf_ops = {
|
|
|
|
.pin_config_group_get = pxa2xx_pconf_group_get,
|
|
|
|
.pin_config_group_set = pxa2xx_pconf_group_set,
|
|
|
|
.is_generic = true,
|
|
|
|
};
|
|
|
|
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
static struct pinctrl_desc pxa2xx_pinctrl_desc = {
|
2015-11-21 19:04:51 +01:00
|
|
|
.confops = &pxa2xx_pconf_ops,
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
.pctlops = &pxa2xx_pctl_ops,
|
2015-11-21 19:04:50 +01:00
|
|
|
.pmxops = &pxa2xx_pinmux_ops,
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
};
|
|
|
|
|
2024-03-11 16:08:33 +02:00
|
|
|
static const struct pinfunction *pxa2xx_find_function(struct pxa_pinctrl *pctl,
|
|
|
|
const char *fname,
|
|
|
|
const struct pinfunction *functions)
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
{
|
2024-03-11 16:08:33 +02:00
|
|
|
const struct pinfunction *func;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
|
|
|
for (func = functions; func->name; func++)
|
|
|
|
if (!strcmp(fname, func->name))
|
|
|
|
return func;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_build_functions(struct pxa_pinctrl *pctl)
|
|
|
|
{
|
2024-03-11 16:08:33 +02:00
|
|
|
struct pinfunction *functions;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
int i;
|
|
|
|
struct pxa_desc_function *df;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each pin can have at most 6 alternate functions, and 2 gpio functions
|
|
|
|
* which are common to each pin. As there are more than 2 pins without
|
|
|
|
* alternate function, 6 * npins is an absolute high limit of the number
|
|
|
|
* of functions.
|
|
|
|
*/
|
|
|
|
functions = devm_kcalloc(pctl->dev, pctl->npins * 6,
|
|
|
|
sizeof(*functions), GFP_KERNEL);
|
|
|
|
if (!functions)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < pctl->npins; i++)
|
|
|
|
for (df = pctl->ppins[i].functions; df->name; df++)
|
|
|
|
if (!pxa2xx_find_function(pctl, df->name, functions))
|
|
|
|
(functions + pctl->nfuncs++)->name = df->name;
|
2025-02-12 11:55:10 +05:30
|
|
|
pctl->functions = devm_kmemdup_array(pctl->dev, functions, pctl->nfuncs,
|
|
|
|
sizeof(*functions), GFP_KERNEL);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
if (!pctl->functions)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2015-12-12 22:43:05 +01:00
|
|
|
devm_kfree(pctl->dev, functions);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_build_groups(struct pxa_pinctrl *pctl)
|
|
|
|
{
|
|
|
|
int i, j, ngroups;
|
|
|
|
struct pxa_desc_function *df;
|
2024-03-11 16:08:33 +02:00
|
|
|
struct pinfunction *func;
|
|
|
|
const char **gtmp;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
|
|
|
gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp),
|
|
|
|
GFP_KERNEL);
|
|
|
|
if (!gtmp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < pctl->nfuncs; i++) {
|
|
|
|
ngroups = 0;
|
|
|
|
for (j = 0; j < pctl->npins; j++)
|
|
|
|
for (df = pctl->ppins[j].functions; df->name;
|
|
|
|
df++)
|
|
|
|
if (!strcmp(pctl->functions[i].name,
|
|
|
|
df->name))
|
|
|
|
gtmp[ngroups++] = (char *)
|
|
|
|
pctl->ppins[j].pin.name;
|
|
|
|
func = pctl->functions + i;
|
|
|
|
func->ngroups = ngroups;
|
2025-02-12 11:55:10 +05:30
|
|
|
func->groups = devm_kmemdup_array(pctl->dev, gtmp, ngroups,
|
|
|
|
sizeof(*gtmp), GFP_KERNEL);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
if (!func->groups)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2015-12-12 22:43:05 +01:00
|
|
|
devm_kfree(pctl->dev, gtmp);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pxa2xx_build_state(struct pxa_pinctrl *pctl,
|
|
|
|
const struct pxa_desc_pin *ppins, int npins)
|
|
|
|
{
|
|
|
|
struct pinctrl_pin_desc *pins;
|
2024-03-11 16:22:48 +02:00
|
|
|
struct pingroup *group;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
int ret, i;
|
|
|
|
|
|
|
|
pctl->npins = npins;
|
|
|
|
pctl->ppins = ppins;
|
|
|
|
pctl->ngroups = npins;
|
|
|
|
|
|
|
|
pctl->desc.npins = npins;
|
|
|
|
pins = devm_kcalloc(pctl->dev, npins, sizeof(*pins), GFP_KERNEL);
|
|
|
|
if (!pins)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
pctl->desc.pins = pins;
|
|
|
|
for (i = 0; i < npins; i++)
|
|
|
|
pins[i] = ppins[i].pin;
|
|
|
|
|
|
|
|
pctl->groups = devm_kmalloc_array(pctl->dev, pctl->ngroups,
|
|
|
|
sizeof(*pctl->groups), GFP_KERNEL);
|
|
|
|
if (!pctl->groups)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < npins; i++) {
|
|
|
|
group = pctl->groups + i;
|
|
|
|
group->name = ppins[i].pin.name;
|
2024-03-11 16:22:48 +02:00
|
|
|
group->pins = &ppins[i].pin.number;
|
|
|
|
group->npins = 1;
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = pxa2xx_build_functions(pctl);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = pxa2xx_build_groups(pctl);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pxa2xx_pinctrl_init(struct platform_device *pdev,
|
|
|
|
const struct pxa_desc_pin *ppins, int npins,
|
|
|
|
void __iomem *base_gafr[], void __iomem *base_gpdr[],
|
|
|
|
void __iomem *base_pgsr[])
|
|
|
|
{
|
|
|
|
struct pxa_pinctrl *pctl;
|
|
|
|
int ret, i, maxpin = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < npins; i++)
|
|
|
|
maxpin = max_t(int, ppins[i].pin.number, maxpin);
|
|
|
|
|
|
|
|
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
|
|
|
|
if (!pctl)
|
|
|
|
return -ENOMEM;
|
|
|
|
pctl->base_gafr = devm_kcalloc(&pdev->dev, roundup(maxpin, 16),
|
|
|
|
sizeof(*pctl->base_gafr), GFP_KERNEL);
|
|
|
|
pctl->base_gpdr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
|
|
|
|
sizeof(*pctl->base_gpdr), GFP_KERNEL);
|
|
|
|
pctl->base_pgsr = devm_kcalloc(&pdev->dev, roundup(maxpin, 32),
|
|
|
|
sizeof(*pctl->base_pgsr), GFP_KERNEL);
|
|
|
|
if (!pctl->base_gafr || !pctl->base_gpdr || !pctl->base_pgsr)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
platform_set_drvdata(pdev, pctl);
|
|
|
|
spin_lock_init(&pctl->lock);
|
|
|
|
|
|
|
|
pctl->dev = &pdev->dev;
|
|
|
|
pctl->desc = pxa2xx_pinctrl_desc;
|
|
|
|
pctl->desc.name = dev_name(&pdev->dev);
|
|
|
|
pctl->desc.owner = THIS_MODULE;
|
|
|
|
|
|
|
|
for (i = 0; i < roundup(maxpin, 16); i += 16)
|
|
|
|
pctl->base_gafr[i / 16] = base_gafr[i / 16];
|
|
|
|
for (i = 0; i < roundup(maxpin, 32); i += 32) {
|
|
|
|
pctl->base_gpdr[i / 32] = base_gpdr[i / 32];
|
|
|
|
pctl->base_pgsr[i / 32] = base_pgsr[i / 32];
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = pxa2xx_build_state(pctl, ppins, npins);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2016-02-24 14:44:07 +05:30
|
|
|
pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->desc, pctl);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
if (IS_ERR(pctl->pctl_dev)) {
|
|
|
|
dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
|
|
|
|
return PTR_ERR(pctl->pctl_dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
dev_info(&pdev->dev, "initialized pxa2xx pinctrl driver\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-09 09:10:02 +07:00
|
|
|
EXPORT_SYMBOL_GPL(pxa2xx_pinctrl_init);
|
pinctrl: pxa: pxa2xx: add pin control skeleton
Add a pincontrol driver for pxa2xx architecture, encompassing all pxa25x
and pxa27x variants. This is only the pin muxing part of the driver.
One specific consideration is also the memory space (MMIO), which is
intertwined with the GPIO registers. To make things worse, the GPIO
direction register also affect pin muxing, as it chooses the "kind" of
pin, ie. the 4 output functions or 4 input functions.
The mapping between pinctrl notions and PXA Technical Reference Manual
is as follows :
- a pin is obviously a pin
- a group is also a pin, ie. group P101 is the pin 101
- a mux function is an alternate function
(ie. gpio-in, gpio-out, MMCLK, BTRTS, etc ...)
The individual architecture (pxa27x, pxa25x) instantiate a pin control
by providing a table of pins, each pin being provided a list of
PXA_FUNCTION (alternate functions).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-11-21 19:04:49 +01:00
|
|
|
|
2017-11-20 12:58:03 -08:00
|
|
|
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
|
|
|
|
MODULE_DESCRIPTION("Marvell PXA2xx pinctrl driver");
|
|
|
|
MODULE_LICENSE("GPL v2");
|