/*
* Allwinner A1X SoCs pinctrl driver.
*
* Copyright (C) 2012 Maxime Ripard
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "../core.h"
#include "../../gpio/gpiolib.h"
#include "pinctrl-sunxi.h"
static struct irq_chip sunxi_pinctrl_edge_irq_chip;
static struct irq_chip sunxi_pinctrl_level_irq_chip;
static struct sunxi_pinctrl_group *
sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
{
int i;
for (i = 0; i < pctl->ngroups; i++) {
struct sunxi_pinctrl_group *grp = pctl->groups + i;
if (!strcmp(grp->name, group))
return grp;
}
return NULL;
}
static struct sunxi_pinctrl_function *
sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
const char *name)
{
struct sunxi_pinctrl_function *func = pctl->functions;
int i;
for (i = 0; i < pctl->nfunctions; i++) {
if (!func[i].name)
break;
if (!strcmp(func[i].name, name))
return func + i;
}
return NULL;
}
static struct sunxi_desc_function *
sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
const char *pin_name,
const char *func_name)
{
int i;
for (i = 0; i < pctl->desc->npins; i++) {
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
if (!strcmp(pin->pin.name, pin_name)) {
struct sunxi_desc_function *func = pin->functions;
while (func->name) {
if (!strcmp(func->name, func_name))
return func;
func++;
}
}
}
return NULL;
}
static struct sunxi_desc_function *
sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
const u16 pin_num,
const char *func_name)
{
int i;
for (i = 0; i < pctl->desc->npins; i++) {
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
if (pin->pin.number == pin_num) {
struct sunxi_desc_function *func = pin->functions;
while (func->name) {
if (!strcmp(func->name, func_name))
return func;
func++;
}
}
}
return NULL;
}
static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->ngroups;
}
static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
{
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
return pctl->groups[group].name;
}
static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned group,
const unsigned