mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
136
drivers/pinctrl/sh-pfc/Kconfig
Normal file
136
drivers/pinctrl/sh-pfc/Kconfig
Normal file
|
@ -0,0 +1,136 @@
|
|||
#
|
||||
# Renesas SH and SH Mobile PINCTRL drivers
|
||||
#
|
||||
|
||||
if ARCH_SHMOBILE || SUPERH
|
||||
|
||||
config PINCTRL_SH_PFC
|
||||
select GPIO_SH_PFC if ARCH_REQUIRE_GPIOLIB
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
def_bool y
|
||||
help
|
||||
This enables pin control drivers for SH and SH Mobile platforms
|
||||
|
||||
config GPIO_SH_PFC
|
||||
bool "SuperH PFC GPIO support"
|
||||
depends on PINCTRL_SH_PFC && GPIOLIB
|
||||
help
|
||||
This enables support for GPIOs within the SoC's pin function
|
||||
controller.
|
||||
|
||||
config PINCTRL_PFC_R8A73A4
|
||||
def_bool y
|
||||
depends on ARCH_R8A73A4
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_R8A7740
|
||||
def_bool y
|
||||
depends on ARCH_R8A7740
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_R8A7778
|
||||
def_bool y
|
||||
depends on ARCH_R8A7778
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_R8A7779
|
||||
def_bool y
|
||||
depends on ARCH_R8A7779
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_R8A7790
|
||||
def_bool y
|
||||
depends on ARCH_R8A7790
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_R8A7791
|
||||
def_bool y
|
||||
depends on ARCH_R8A7791
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7203
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7203
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7264
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7264
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7269
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7269
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7372
|
||||
def_bool y
|
||||
depends on ARCH_SH7372
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH73A0
|
||||
def_bool y
|
||||
depends on ARCH_SH73A0
|
||||
select PINCTRL_SH_PFC
|
||||
select REGULATOR
|
||||
|
||||
config PINCTRL_PFC_SH7720
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7720
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7722
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7722
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7723
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7723
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7724
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7724
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7734
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7734
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7757
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7757
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7785
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7785
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SH7786
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SH7786
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
config PINCTRL_PFC_SHX3
|
||||
def_bool y
|
||||
depends on CPU_SUBTYPE_SHX3
|
||||
depends on GPIOLIB
|
||||
select PINCTRL_SH_PFC
|
||||
|
||||
endif
|
25
drivers/pinctrl/sh-pfc/Makefile
Normal file
25
drivers/pinctrl/sh-pfc/Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
sh-pfc-objs = core.o pinctrl.o
|
||||
ifeq ($(CONFIG_GPIO_SH_PFC),y)
|
||||
sh-pfc-objs += gpio.o
|
||||
endif
|
||||
obj-$(CONFIG_PINCTRL_SH_PFC) += sh-pfc.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A73A4) += pfc-r8a73a4.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A7740) += pfc-r8a7740.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A7790) += pfc-r8a7790.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_R8A7791) += pfc-r8a7791.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7372) += pfc-sh7372.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH73A0) += pfc-sh73a0.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7720) += pfc-sh7720.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7722) += pfc-sh7722.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7723) += pfc-sh7723.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7724) += pfc-sh7724.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7734) += pfc-sh7734.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7757) += pfc-sh7757.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7785) += pfc-sh7785.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SH7786) += pfc-sh7786.o
|
||||
obj-$(CONFIG_PINCTRL_PFC_SHX3) += pfc-shx3.o
|
672
drivers/pinctrl/sh-pfc/core.c
Normal file
672
drivers/pinctrl/sh-pfc/core.c
Normal file
|
@ -0,0 +1,672 @@
|
|||
/*
|
||||
* SuperH Pin Function Controller support.
|
||||
*
|
||||
* Copyright (C) 2008 Magnus Damm
|
||||
* Copyright (C) 2009 - 2012 Paul Mundt
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define DRV_NAME "sh-pfc"
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static int sh_pfc_map_resources(struct sh_pfc *pfc,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
unsigned int num_windows = 0;
|
||||
unsigned int num_irqs = 0;
|
||||
struct sh_pfc_window *windows;
|
||||
unsigned int *irqs = NULL;
|
||||
struct resource *res;
|
||||
unsigned int i;
|
||||
|
||||
/* Count the MEM and IRQ resources. */
|
||||
for (i = 0; i < pdev->num_resources; ++i) {
|
||||
switch (resource_type(&pdev->resource[i])) {
|
||||
case IORESOURCE_MEM:
|
||||
num_windows++;
|
||||
break;
|
||||
|
||||
case IORESOURCE_IRQ:
|
||||
num_irqs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_windows == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate memory windows and IRQs arrays. */
|
||||
windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
|
||||
GFP_KERNEL);
|
||||
if (windows == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pfc->num_windows = num_windows;
|
||||
pfc->windows = windows;
|
||||
|
||||
if (num_irqs) {
|
||||
irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
|
||||
GFP_KERNEL);
|
||||
if (irqs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pfc->num_irqs = num_irqs;
|
||||
pfc->irqs = irqs;
|
||||
}
|
||||
|
||||
/* Fill them. */
|
||||
for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) {
|
||||
switch (resource_type(res)) {
|
||||
case IORESOURCE_MEM:
|
||||
windows->phys = res->start;
|
||||
windows->size = resource_size(res);
|
||||
windows->virt = devm_ioremap_resource(pfc->dev, res);
|
||||
if (IS_ERR(windows->virt))
|
||||
return -ENOMEM;
|
||||
windows++;
|
||||
break;
|
||||
|
||||
case IORESOURCE_IRQ:
|
||||
*irqs++ = res->start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
|
||||
unsigned long address)
|
||||
{
|
||||
struct sh_pfc_window *window;
|
||||
unsigned int i;
|
||||
|
||||
/* scan through physical windows and convert address */
|
||||
for (i = 0; i < pfc->num_windows; i++) {
|
||||
window = pfc->windows + i;
|
||||
|
||||
if (address < window->phys)
|
||||
continue;
|
||||
|
||||
if (address >= (window->phys + window->size))
|
||||
continue;
|
||||
|
||||
return window->virt + (address - window->phys);
|
||||
}
|
||||
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) {
|
||||
const struct sh_pfc_pin_range *range = &pfc->ranges[i];
|
||||
|
||||
if (pin <= range->end)
|
||||
return pin >= range->start
|
||||
? offset + pin - range->start : -1;
|
||||
|
||||
offset += range->end - range->start + 1;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r)
|
||||
{
|
||||
if (enum_id < r->begin)
|
||||
return 0;
|
||||
|
||||
if (enum_id > r->end)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
|
||||
unsigned long reg_width)
|
||||
{
|
||||
switch (reg_width) {
|
||||
case 8:
|
||||
return ioread8(mapped_reg);
|
||||
case 16:
|
||||
return ioread16(mapped_reg);
|
||||
case 32:
|
||||
return ioread32(mapped_reg);
|
||||
}
|
||||
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
|
||||
unsigned long data)
|
||||
{
|
||||
switch (reg_width) {
|
||||
case 8:
|
||||
iowrite8(data, mapped_reg);
|
||||
return;
|
||||
case 16:
|
||||
iowrite16(data, mapped_reg);
|
||||
return;
|
||||
case 32:
|
||||
iowrite32(data, mapped_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
BUG();
|
||||
}
|
||||
|
||||
static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
|
||||
const struct pinmux_cfg_reg *crp,
|
||||
unsigned long in_pos,
|
||||
void __iomem **mapped_regp,
|
||||
unsigned long *maskp,
|
||||
unsigned long *posp)
|
||||
{
|
||||
unsigned int k;
|
||||
|
||||
*mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
|
||||
|
||||
if (crp->field_width) {
|
||||
*maskp = (1 << crp->field_width) - 1;
|
||||
*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
|
||||
} else {
|
||||
*maskp = (1 << crp->var_field_width[in_pos]) - 1;
|
||||
*posp = crp->reg_width;
|
||||
for (k = 0; k <= in_pos; k++)
|
||||
*posp -= crp->var_field_width[k];
|
||||
}
|
||||
}
|
||||
|
||||
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
|
||||
const struct pinmux_cfg_reg *crp,
|
||||
unsigned long field, unsigned long value)
|
||||
{
|
||||
void __iomem *mapped_reg;
|
||||
unsigned long mask, pos, data;
|
||||
|
||||
sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
|
||||
|
||||
dev_dbg(pfc->dev, "write_reg addr = %lx, value = %ld, field = %ld, "
|
||||
"r_width = %ld, f_width = %ld\n",
|
||||
crp->reg, value, field, crp->reg_width, crp->field_width);
|
||||
|
||||
mask = ~(mask << pos);
|
||||
value = value << pos;
|
||||
|
||||
data = sh_pfc_read_raw_reg(mapped_reg, crp->reg_width);
|
||||
data &= mask;
|
||||
data |= value;
|
||||
|
||||
if (pfc->info->unlock_reg)
|
||||
sh_pfc_write_raw_reg(
|
||||
sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
|
||||
~data);
|
||||
|
||||
sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
|
||||
}
|
||||
|
||||
static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
|
||||
const struct pinmux_cfg_reg **crp, int *fieldp,
|
||||
int *valuep)
|
||||
{
|
||||
const struct pinmux_cfg_reg *config_reg;
|
||||
unsigned long r_width, f_width, curr_width, ncomb;
|
||||
unsigned int k, m, n, pos, bit_pos;
|
||||
|
||||
k = 0;
|
||||
while (1) {
|
||||
config_reg = pfc->info->cfg_regs + k;
|
||||
|
||||
r_width = config_reg->reg_width;
|
||||
f_width = config_reg->field_width;
|
||||
|
||||
if (!r_width)
|
||||
break;
|
||||
|
||||
pos = 0;
|
||||
m = 0;
|
||||
for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
|
||||
if (f_width)
|
||||
curr_width = f_width;
|
||||
else
|
||||
curr_width = config_reg->var_field_width[m];
|
||||
|
||||
ncomb = 1 << curr_width;
|
||||
for (n = 0; n < ncomb; n++) {
|
||||
if (config_reg->enum_ids[pos + n] == enum_id) {
|
||||
*crp = config_reg;
|
||||
*fieldp = m;
|
||||
*valuep = n;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pos += ncomb;
|
||||
m++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
|
||||
u16 *enum_idp)
|
||||
{
|
||||
const u16 *data = pfc->info->gpio_data;
|
||||
unsigned int k;
|
||||
|
||||
if (pos) {
|
||||
*enum_idp = data[pos + 1];
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
for (k = 0; k < pfc->info->gpio_data_size; k++) {
|
||||
if (data[k] == mark) {
|
||||
*enum_idp = data[k + 1];
|
||||
return k + 1;
|
||||
}
|
||||
}
|
||||
|
||||
dev_err(pfc->dev, "cannot locate data/mark enum_id for mark %d\n",
|
||||
mark);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
|
||||
{
|
||||
const struct pinmux_cfg_reg *cr = NULL;
|
||||
u16 enum_id;
|
||||
const struct pinmux_range *range;
|
||||
int in_range, pos, field, value;
|
||||
int ret;
|
||||
|
||||
switch (pinmux_type) {
|
||||
case PINMUX_TYPE_GPIO:
|
||||
case PINMUX_TYPE_FUNCTION:
|
||||
range = NULL;
|
||||
break;
|
||||
|
||||
case PINMUX_TYPE_OUTPUT:
|
||||
range = &pfc->info->output;
|
||||
break;
|
||||
|
||||
case PINMUX_TYPE_INPUT:
|
||||
range = &pfc->info->input;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
enum_id = 0;
|
||||
field = 0;
|
||||
value = 0;
|
||||
|
||||
/* Iterate over all the configuration fields we need to update. */
|
||||
while (1) {
|
||||
pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
|
||||
if (pos < 0)
|
||||
return pos;
|
||||
|
||||
if (!enum_id)
|
||||
break;
|
||||
|
||||
/* Check if the configuration field selects a function. If it
|
||||
* doesn't, skip the field if it's not applicable to the
|
||||
* requested pinmux type.
|
||||
*/
|
||||
in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
|
||||
if (!in_range) {
|
||||
if (pinmux_type == PINMUX_TYPE_FUNCTION) {
|
||||
/* Functions are allowed to modify all
|
||||
* fields.
|
||||
*/
|
||||
in_range = 1;
|
||||
} else if (pinmux_type != PINMUX_TYPE_GPIO) {
|
||||
/* Input/output types can only modify fields
|
||||
* that correspond to their respective ranges.
|
||||
*/
|
||||
in_range = sh_pfc_enum_in_range(enum_id, range);
|
||||
|
||||
/*
|
||||
* special case pass through for fixed
|
||||
* input-only or output-only pins without
|
||||
* function enum register association.
|
||||
*/
|
||||
if (in_range && enum_id == range->force)
|
||||
continue;
|
||||
}
|
||||
/* GPIOs are only allowed to modify function fields. */
|
||||
}
|
||||
|
||||
if (!in_range)
|
||||
continue;
|
||||
|
||||
ret = sh_pfc_get_config_reg(pfc, enum_id, &cr, &field, &value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sh_pfc_write_config_reg(pfc, cr, field, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_init_ranges(struct sh_pfc *pfc)
|
||||
{
|
||||
struct sh_pfc_pin_range *range;
|
||||
unsigned int nr_ranges;
|
||||
unsigned int i;
|
||||
|
||||
if (pfc->info->pins[0].pin == (u16)-1) {
|
||||
/* Pin number -1 denotes that the SoC doesn't report pin numbers
|
||||
* in its pin arrays yet. Consider the pin numbers range as
|
||||
* continuous and allocate a single range.
|
||||
*/
|
||||
pfc->nr_ranges = 1;
|
||||
pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges),
|
||||
GFP_KERNEL);
|
||||
if (pfc->ranges == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pfc->ranges->start = 0;
|
||||
pfc->ranges->end = pfc->info->nr_pins - 1;
|
||||
pfc->nr_gpio_pins = pfc->info->nr_pins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Count, allocate and fill the ranges. The PFC SoC data pins array must
|
||||
* be sorted by pin numbers, and pins without a GPIO port must come
|
||||
* last.
|
||||
*/
|
||||
for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) {
|
||||
if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1)
|
||||
nr_ranges++;
|
||||
}
|
||||
|
||||
pfc->nr_ranges = nr_ranges;
|
||||
pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges,
|
||||
GFP_KERNEL);
|
||||
if (pfc->ranges == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
range = pfc->ranges;
|
||||
range->start = pfc->info->pins[0].pin;
|
||||
|
||||
for (i = 1; i < pfc->info->nr_pins; ++i) {
|
||||
if (pfc->info->pins[i-1].pin == pfc->info->pins[i].pin - 1)
|
||||
continue;
|
||||
|
||||
range->end = pfc->info->pins[i-1].pin;
|
||||
if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
|
||||
pfc->nr_gpio_pins = range->end + 1;
|
||||
|
||||
range++;
|
||||
range->start = pfc->info->pins[i].pin;
|
||||
}
|
||||
|
||||
range->end = pfc->info->pins[i-1].pin;
|
||||
if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
|
||||
pfc->nr_gpio_pins = range->end + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id sh_pfc_of_table[] = {
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a73a4",
|
||||
.data = &r8a73a4_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7740
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a7740",
|
||||
.data = &r8a7740_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7778
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a7778",
|
||||
.data = &r8a7778_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7779
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a7779",
|
||||
.data = &r8a7779_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7790
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a7790",
|
||||
.data = &r8a7790_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7791
|
||||
{
|
||||
.compatible = "renesas,pfc-r8a7791",
|
||||
.data = &r8a7791_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7372
|
||||
{
|
||||
.compatible = "renesas,pfc-sh7372",
|
||||
.data = &sh7372_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH73A0
|
||||
{
|
||||
.compatible = "renesas,pfc-sh73a0",
|
||||
.data = &sh73a0_pinmux_info,
|
||||
},
|
||||
#endif
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sh_pfc_of_table);
|
||||
#endif
|
||||
|
||||
static int sh_pfc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *platid = platform_get_device_id(pdev);
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
#endif
|
||||
const struct sh_pfc_soc_info *info;
|
||||
struct sh_pfc *pfc;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (np)
|
||||
info = of_match_device(sh_pfc_of_table, &pdev->dev)->data;
|
||||
else
|
||||
#endif
|
||||
info = platid ? (const void *)platid->driver_data : NULL;
|
||||
|
||||
if (info == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
|
||||
if (pfc == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pfc->info = info;
|
||||
pfc->dev = &pdev->dev;
|
||||
|
||||
ret = sh_pfc_map_resources(pfc, pdev);
|
||||
if (unlikely(ret < 0))
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&pfc->lock);
|
||||
|
||||
if (info->ops && info->ops->init) {
|
||||
ret = info->ops->init(pfc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pinctrl_provide_dummies();
|
||||
|
||||
ret = sh_pfc_init_ranges(pfc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Initialize pinctrl bindings first
|
||||
*/
|
||||
ret = sh_pfc_register_pinctrl(pfc);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_GPIO_SH_PFC
|
||||
/*
|
||||
* Then the GPIO chip
|
||||
*/
|
||||
ret = sh_pfc_register_gpiochip(pfc);
|
||||
if (unlikely(ret != 0)) {
|
||||
/*
|
||||
* If the GPIO chip fails to come up we still leave the
|
||||
* PFC state as it is, given that there are already
|
||||
* extant users of it that have succeeded by this point.
|
||||
*/
|
||||
dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_set_drvdata(pdev, pfc);
|
||||
|
||||
dev_info(pfc->dev, "%s support registered\n", info->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sh_pfc *pfc = platform_get_drvdata(pdev);
|
||||
|
||||
#ifdef CONFIG_GPIO_SH_PFC
|
||||
sh_pfc_unregister_gpiochip(pfc);
|
||||
#endif
|
||||
sh_pfc_unregister_pinctrl(pfc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id sh_pfc_id_table[] = {
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
|
||||
{ "pfc-r8a73a4", (kernel_ulong_t)&r8a73a4_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7740
|
||||
{ "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7778
|
||||
{ "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7779
|
||||
{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7790
|
||||
{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_R8A7791
|
||||
{ "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7203
|
||||
{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7264
|
||||
{ "pfc-sh7264", (kernel_ulong_t)&sh7264_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7269
|
||||
{ "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7372
|
||||
{ "pfc-sh7372", (kernel_ulong_t)&sh7372_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH73A0
|
||||
{ "pfc-sh73a0", (kernel_ulong_t)&sh73a0_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7720
|
||||
{ "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7722
|
||||
{ "pfc-sh7722", (kernel_ulong_t)&sh7722_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7723
|
||||
{ "pfc-sh7723", (kernel_ulong_t)&sh7723_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7724
|
||||
{ "pfc-sh7724", (kernel_ulong_t)&sh7724_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7734
|
||||
{ "pfc-sh7734", (kernel_ulong_t)&sh7734_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7757
|
||||
{ "pfc-sh7757", (kernel_ulong_t)&sh7757_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7785
|
||||
{ "pfc-sh7785", (kernel_ulong_t)&sh7785_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SH7786
|
||||
{ "pfc-sh7786", (kernel_ulong_t)&sh7786_pinmux_info },
|
||||
#endif
|
||||
#ifdef CONFIG_PINCTRL_PFC_SHX3
|
||||
{ "pfc-shx3", (kernel_ulong_t)&shx3_pinmux_info },
|
||||
#endif
|
||||
{ "sh-pfc", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, sh_pfc_id_table);
|
||||
|
||||
static struct platform_driver sh_pfc_driver = {
|
||||
.probe = sh_pfc_probe,
|
||||
.remove = sh_pfc_remove,
|
||||
.id_table = sh_pfc_id_table,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(sh_pfc_of_table),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sh_pfc_init(void)
|
||||
{
|
||||
return platform_driver_register(&sh_pfc_driver);
|
||||
}
|
||||
postcore_initcall(sh_pfc_init);
|
||||
|
||||
static void __exit sh_pfc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sh_pfc_driver);
|
||||
}
|
||||
module_exit(sh_pfc_exit);
|
||||
|
||||
MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart");
|
||||
MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller");
|
||||
MODULE_LICENSE("GPL v2");
|
89
drivers/pinctrl/sh-pfc/core.h
Normal file
89
drivers/pinctrl/sh-pfc/core.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* SuperH Pin Function Controller support.
|
||||
*
|
||||
* Copyright (C) 2012 Renesas Solutions Corp.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#ifndef __SH_PFC_CORE_H__
|
||||
#define __SH_PFC_CORE_H__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "sh_pfc.h"
|
||||
|
||||
struct sh_pfc_window {
|
||||
phys_addr_t phys;
|
||||
void __iomem *virt;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
struct sh_pfc_chip;
|
||||
struct sh_pfc_pinctrl;
|
||||
|
||||
struct sh_pfc_pin_range {
|
||||
u16 start;
|
||||
u16 end;
|
||||
};
|
||||
|
||||
struct sh_pfc {
|
||||
struct device *dev;
|
||||
const struct sh_pfc_soc_info *info;
|
||||
spinlock_t lock;
|
||||
|
||||
unsigned int num_windows;
|
||||
struct sh_pfc_window *windows;
|
||||
unsigned int num_irqs;
|
||||
unsigned int *irqs;
|
||||
|
||||
struct sh_pfc_pin_range *ranges;
|
||||
unsigned int nr_ranges;
|
||||
|
||||
unsigned int nr_gpio_pins;
|
||||
|
||||
struct sh_pfc_chip *gpio;
|
||||
struct sh_pfc_chip *func;
|
||||
|
||||
struct sh_pfc_pinctrl *pinctrl;
|
||||
};
|
||||
|
||||
int sh_pfc_register_gpiochip(struct sh_pfc *pfc);
|
||||
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc);
|
||||
|
||||
int sh_pfc_register_pinctrl(struct sh_pfc *pfc);
|
||||
int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc);
|
||||
|
||||
unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
|
||||
unsigned long reg_width);
|
||||
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
|
||||
unsigned long data);
|
||||
|
||||
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
|
||||
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
|
||||
|
||||
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info r8a7791_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7203_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7264_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7269_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7372_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh73a0_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7720_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7722_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7723_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7724_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7734_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7757_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7785_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info sh7786_pinmux_info;
|
||||
extern const struct sh_pfc_soc_info shx3_pinmux_info;
|
||||
|
||||
#endif /* __SH_PFC_CORE_H__ */
|
416
drivers/pinctrl/sh-pfc/gpio.c
Normal file
416
drivers/pinctrl/sh-pfc/gpio.c
Normal file
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* SuperH Pin Function Controller GPIO driver.
|
||||
*
|
||||
* Copyright (C) 2008 Magnus Damm
|
||||
* Copyright (C) 2009 - 2012 Paul Mundt
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
struct sh_pfc_gpio_data_reg {
|
||||
const struct pinmux_data_reg *info;
|
||||
unsigned long shadow;
|
||||
};
|
||||
|
||||
struct sh_pfc_gpio_pin {
|
||||
u8 dbit;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
struct sh_pfc_chip {
|
||||
struct sh_pfc *pfc;
|
||||
struct gpio_chip gpio_chip;
|
||||
|
||||
struct sh_pfc_window *mem;
|
||||
struct sh_pfc_gpio_data_reg *regs;
|
||||
struct sh_pfc_gpio_pin *pins;
|
||||
};
|
||||
|
||||
static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc)
|
||||
{
|
||||
return container_of(gc, struct sh_pfc_chip, gpio_chip);
|
||||
}
|
||||
|
||||
static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc)
|
||||
{
|
||||
return gpio_to_pfc_chip(gc)->pfc;
|
||||
}
|
||||
|
||||
static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int offset,
|
||||
struct sh_pfc_gpio_data_reg **reg,
|
||||
unsigned int *bit)
|
||||
{
|
||||
int idx = sh_pfc_get_pin_index(chip->pfc, offset);
|
||||
struct sh_pfc_gpio_pin *gpio_pin = &chip->pins[idx];
|
||||
|
||||
*reg = &chip->regs[gpio_pin->dreg];
|
||||
*bit = gpio_pin->dbit;
|
||||
}
|
||||
|
||||
static unsigned long gpio_read_data_reg(struct sh_pfc_chip *chip,
|
||||
const struct pinmux_data_reg *dreg)
|
||||
{
|
||||
void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt;
|
||||
|
||||
return sh_pfc_read_raw_reg(mem, dreg->reg_width);
|
||||
}
|
||||
|
||||
static void gpio_write_data_reg(struct sh_pfc_chip *chip,
|
||||
const struct pinmux_data_reg *dreg,
|
||||
unsigned long value)
|
||||
{
|
||||
void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt;
|
||||
|
||||
sh_pfc_write_raw_reg(mem, dreg->reg_width, value);
|
||||
}
|
||||
|
||||
static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned idx)
|
||||
{
|
||||
struct sh_pfc *pfc = chip->pfc;
|
||||
struct sh_pfc_gpio_pin *gpio_pin = &chip->pins[idx];
|
||||
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
|
||||
const struct pinmux_data_reg *dreg;
|
||||
unsigned int bit;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0, dreg = pfc->info->data_regs; dreg->reg; ++i, ++dreg) {
|
||||
for (bit = 0; bit < dreg->reg_width; bit++) {
|
||||
if (dreg->enum_ids[bit] == pin->enum_id) {
|
||||
gpio_pin->dreg = i;
|
||||
gpio_pin->dbit = bit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BUG();
|
||||
}
|
||||
|
||||
static int gpio_setup_data_regs(struct sh_pfc_chip *chip)
|
||||
{
|
||||
struct sh_pfc *pfc = chip->pfc;
|
||||
const struct pinmux_data_reg *dreg;
|
||||
unsigned int i;
|
||||
|
||||
/* Count the number of data registers, allocate memory and initialize
|
||||
* them.
|
||||
*/
|
||||
for (i = 0; pfc->info->data_regs[i].reg_width; ++i)
|
||||
;
|
||||
|
||||
chip->regs = devm_kzalloc(pfc->dev, i * sizeof(*chip->regs),
|
||||
GFP_KERNEL);
|
||||
if (chip->regs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) {
|
||||
chip->regs[i].info = dreg;
|
||||
chip->regs[i].shadow = gpio_read_data_reg(chip, dreg);
|
||||
}
|
||||
|
||||
for (i = 0; i < pfc->info->nr_pins; i++) {
|
||||
if (pfc->info->pins[i].enum_id == 0)
|
||||
continue;
|
||||
|
||||
gpio_setup_data_reg(chip, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Pin GPIOs
|
||||
*/
|
||||
|
||||
static int gpio_pin_request(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sh_pfc *pfc = gpio_to_pfc(gc);
|
||||
int idx = sh_pfc_get_pin_index(pfc, offset);
|
||||
|
||||
if (idx < 0 || pfc->info->pins[idx].enum_id == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return pinctrl_request_gpio(offset);
|
||||
}
|
||||
|
||||
static void gpio_pin_free(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
return pinctrl_free_gpio(offset);
|
||||
}
|
||||
|
||||
static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
struct sh_pfc_gpio_data_reg *reg;
|
||||
unsigned long pos;
|
||||
unsigned int bit;
|
||||
|
||||
gpio_get_data_reg(chip, offset, ®, &bit);
|
||||
|
||||
pos = reg->info->reg_width - (bit + 1);
|
||||
|
||||
if (value)
|
||||
set_bit(pos, ®->shadow);
|
||||
else
|
||||
clear_bit(pos, ®->shadow);
|
||||
|
||||
gpio_write_data_reg(chip, reg->info, reg->shadow);
|
||||
}
|
||||
|
||||
static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(offset);
|
||||
}
|
||||
|
||||
static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
gpio_pin_set_value(gpio_to_pfc_chip(gc), offset, value);
|
||||
|
||||
return pinctrl_gpio_direction_output(offset);
|
||||
}
|
||||
|
||||
static int gpio_pin_get(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc);
|
||||
struct sh_pfc_gpio_data_reg *reg;
|
||||
unsigned long pos;
|
||||
unsigned int bit;
|
||||
|
||||
gpio_get_data_reg(chip, offset, ®, &bit);
|
||||
|
||||
pos = reg->info->reg_width - (bit + 1);
|
||||
|
||||
return (gpio_read_data_reg(chip, reg->info) >> pos) & 1;
|
||||
}
|
||||
|
||||
static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value)
|
||||
{
|
||||
gpio_pin_set_value(gpio_to_pfc_chip(gc), offset, value);
|
||||
}
|
||||
|
||||
static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sh_pfc *pfc = gpio_to_pfc(gc);
|
||||
unsigned int i, k;
|
||||
|
||||
for (i = 0; i < pfc->info->gpio_irq_size; i++) {
|
||||
const short *gpios = pfc->info->gpio_irq[i].gpios;
|
||||
|
||||
for (k = 0; gpios[k] >= 0; k++) {
|
||||
if (gpios[k] == offset)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
|
||||
found:
|
||||
if (pfc->num_irqs)
|
||||
return pfc->irqs[i];
|
||||
else
|
||||
return pfc->info->gpio_irq[i].irq;
|
||||
}
|
||||
|
||||
static int gpio_pin_setup(struct sh_pfc_chip *chip)
|
||||
{
|
||||
struct sh_pfc *pfc = chip->pfc;
|
||||
struct gpio_chip *gc = &chip->gpio_chip;
|
||||
int ret;
|
||||
|
||||
chip->pins = devm_kzalloc(pfc->dev, pfc->info->nr_pins *
|
||||
sizeof(*chip->pins), GFP_KERNEL);
|
||||
if (chip->pins == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gpio_setup_data_regs(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
gc->request = gpio_pin_request;
|
||||
gc->free = gpio_pin_free;
|
||||
gc->direction_input = gpio_pin_direction_input;
|
||||
gc->get = gpio_pin_get;
|
||||
gc->direction_output = gpio_pin_direction_output;
|
||||
gc->set = gpio_pin_set;
|
||||
gc->to_irq = gpio_pin_to_irq;
|
||||
|
||||
gc->label = pfc->info->name;
|
||||
gc->dev = pfc->dev;
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->base = 0;
|
||||
gc->ngpio = pfc->nr_gpio_pins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Function GPIOs
|
||||
*/
|
||||
|
||||
static int gpio_function_request(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
static bool __print_once;
|
||||
struct sh_pfc *pfc = gpio_to_pfc(gc);
|
||||
unsigned int mark = pfc->info->func_gpios[offset].enum_id;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!__print_once) {
|
||||
dev_notice(pfc->dev,
|
||||
"Use of GPIO API for function requests is deprecated."
|
||||
" Convert to pinctrl\n");
|
||||
__print_once = true;
|
||||
}
|
||||
|
||||
if (mark == 0)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
ret = sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION);
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gpio_function_free(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
}
|
||||
|
||||
static int gpio_function_setup(struct sh_pfc_chip *chip)
|
||||
{
|
||||
struct sh_pfc *pfc = chip->pfc;
|
||||
struct gpio_chip *gc = &chip->gpio_chip;
|
||||
|
||||
gc->request = gpio_function_request;
|
||||
gc->free = gpio_function_free;
|
||||
|
||||
gc->label = pfc->info->name;
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->base = pfc->nr_gpio_pins;
|
||||
gc->ngpio = pfc->info->nr_func_gpios;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Register/unregister
|
||||
*/
|
||||
|
||||
static struct sh_pfc_chip *
|
||||
sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
|
||||
struct sh_pfc_window *mem)
|
||||
{
|
||||
struct sh_pfc_chip *chip;
|
||||
int ret;
|
||||
|
||||
chip = devm_kzalloc(pfc->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (unlikely(!chip))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
chip->mem = mem;
|
||||
chip->pfc = pfc;
|
||||
|
||||
ret = setup(chip);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = gpiochip_add(&chip->gpio_chip);
|
||||
if (unlikely(ret < 0))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
dev_info(pfc->dev, "%s handling gpio %u -> %u\n",
|
||||
chip->gpio_chip.label, chip->gpio_chip.base,
|
||||
chip->gpio_chip.base + chip->gpio_chip.ngpio - 1);
|
||||
|
||||
return chip;
|
||||
}
|
||||
|
||||
int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
|
||||
{
|
||||
struct sh_pfc_chip *chip;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (pfc->info->data_regs == NULL)
|
||||
return 0;
|
||||
|
||||
/* Find the memory window that contain the GPIO registers. Boards that
|
||||
* register a separate GPIO device will not supply a memory resource
|
||||
* that covers the data registers. In that case don't try to handle
|
||||
* GPIOs.
|
||||
*/
|
||||
for (i = 0; i < pfc->num_windows; ++i) {
|
||||
struct sh_pfc_window *window = &pfc->windows[i];
|
||||
|
||||
if (pfc->info->data_regs[0].reg >= window->phys &&
|
||||
pfc->info->data_regs[0].reg < window->phys + window->size)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == pfc->num_windows)
|
||||
return 0;
|
||||
|
||||
/* If we have IRQ resources make sure their number is correct. */
|
||||
if (pfc->num_irqs && pfc->num_irqs != pfc->info->gpio_irq_size) {
|
||||
dev_err(pfc->dev, "invalid number of IRQ resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Register the real GPIOs chip. */
|
||||
chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->windows[i]);
|
||||
if (IS_ERR(chip))
|
||||
return PTR_ERR(chip);
|
||||
|
||||
pfc->gpio = chip;
|
||||
|
||||
/* Register the GPIO to pin mappings. As pins with GPIO ports must come
|
||||
* first in the ranges, skip the pins without GPIO ports by stopping at
|
||||
* the first range that contains such a pin.
|
||||
*/
|
||||
for (i = 0; i < pfc->nr_ranges; ++i) {
|
||||
const struct sh_pfc_pin_range *range = &pfc->ranges[i];
|
||||
|
||||
if (range->start >= pfc->nr_gpio_pins)
|
||||
break;
|
||||
|
||||
ret = gpiochip_add_pin_range(&chip->gpio_chip,
|
||||
dev_name(pfc->dev),
|
||||
range->start, range->start,
|
||||
range->end - range->start + 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Register the function GPIOs chip. */
|
||||
if (pfc->info->nr_func_gpios == 0)
|
||||
return 0;
|
||||
|
||||
chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL);
|
||||
if (IS_ERR(chip))
|
||||
return PTR_ERR(chip);
|
||||
|
||||
pfc->func = chip;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
|
||||
{
|
||||
gpiochip_remove(&pfc->gpio->gpio_chip);
|
||||
gpiochip_remove(&pfc->func->gpio_chip);
|
||||
|
||||
return 0;
|
||||
}
|
2749
drivers/pinctrl/sh-pfc/pfc-r8a73a4.c
Normal file
2749
drivers/pinctrl/sh-pfc/pfc-r8a73a4.c
Normal file
File diff suppressed because it is too large
Load diff
3786
drivers/pinctrl/sh-pfc/pfc-r8a7740.c
Normal file
3786
drivers/pinctrl/sh-pfc/pfc-r8a7740.c
Normal file
File diff suppressed because it is too large
Load diff
2928
drivers/pinctrl/sh-pfc/pfc-r8a7778.c
Normal file
2928
drivers/pinctrl/sh-pfc/pfc-r8a7778.c
Normal file
File diff suppressed because it is too large
Load diff
3873
drivers/pinctrl/sh-pfc/pfc-r8a7779.c
Normal file
3873
drivers/pinctrl/sh-pfc/pfc-r8a7779.c
Normal file
File diff suppressed because it is too large
Load diff
5502
drivers/pinctrl/sh-pfc/pfc-r8a7790.c
Normal file
5502
drivers/pinctrl/sh-pfc/pfc-r8a7790.c
Normal file
File diff suppressed because it is too large
Load diff
6188
drivers/pinctrl/sh-pfc/pfc-r8a7791.c
Normal file
6188
drivers/pinctrl/sh-pfc/pfc-r8a7791.c
Normal file
File diff suppressed because it is too large
Load diff
1592
drivers/pinctrl/sh-pfc/pfc-sh7203.c
Normal file
1592
drivers/pinctrl/sh-pfc/pfc-sh7203.c
Normal file
File diff suppressed because it is too large
Load diff
2131
drivers/pinctrl/sh-pfc/pfc-sh7264.c
Normal file
2131
drivers/pinctrl/sh-pfc/pfc-sh7264.c
Normal file
File diff suppressed because it is too large
Load diff
2835
drivers/pinctrl/sh-pfc/pfc-sh7269.c
Normal file
2835
drivers/pinctrl/sh-pfc/pfc-sh7269.c
Normal file
File diff suppressed because it is too large
Load diff
2645
drivers/pinctrl/sh-pfc/pfc-sh7372.c
Normal file
2645
drivers/pinctrl/sh-pfc/pfc-sh7372.c
Normal file
File diff suppressed because it is too large
Load diff
3877
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
Normal file
3877
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
Normal file
File diff suppressed because it is too large
Load diff
1206
drivers/pinctrl/sh-pfc/pfc-sh7720.c
Normal file
1206
drivers/pinctrl/sh-pfc/pfc-sh7720.c
Normal file
File diff suppressed because it is too large
Load diff
1746
drivers/pinctrl/sh-pfc/pfc-sh7722.c
Normal file
1746
drivers/pinctrl/sh-pfc/pfc-sh7722.c
Normal file
File diff suppressed because it is too large
Load diff
1898
drivers/pinctrl/sh-pfc/pfc-sh7723.c
Normal file
1898
drivers/pinctrl/sh-pfc/pfc-sh7723.c
Normal file
File diff suppressed because it is too large
Load diff
2180
drivers/pinctrl/sh-pfc/pfc-sh7724.c
Normal file
2180
drivers/pinctrl/sh-pfc/pfc-sh7724.c
Normal file
File diff suppressed because it is too large
Load diff
2450
drivers/pinctrl/sh-pfc/pfc-sh7734.c
Normal file
2450
drivers/pinctrl/sh-pfc/pfc-sh7734.c
Normal file
File diff suppressed because it is too large
Load diff
2243
drivers/pinctrl/sh-pfc/pfc-sh7757.c
Normal file
2243
drivers/pinctrl/sh-pfc/pfc-sh7757.c
Normal file
File diff suppressed because it is too large
Load diff
1274
drivers/pinctrl/sh-pfc/pfc-sh7785.c
Normal file
1274
drivers/pinctrl/sh-pfc/pfc-sh7785.c
Normal file
File diff suppressed because it is too large
Load diff
818
drivers/pinctrl/sh-pfc/pfc-sh7786.c
Normal file
818
drivers/pinctrl/sh-pfc/pfc-sh7786.c
Normal file
|
@ -0,0 +1,818 @@
|
|||
/*
|
||||
* SH7786 Pinmux
|
||||
*
|
||||
* Copyright (C) 2008, 2009 Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
|
||||
*
|
||||
* Based on SH7785 pinmux
|
||||
*
|
||||
* Copyright (C) 2008 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <cpu/sh7786.h>
|
||||
|
||||
#include "sh_pfc.h"
|
||||
|
||||
enum {
|
||||
PINMUX_RESERVED = 0,
|
||||
|
||||
PINMUX_DATA_BEGIN,
|
||||
PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
|
||||
PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
|
||||
PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
|
||||
PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
|
||||
PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
|
||||
PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
|
||||
PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
|
||||
PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
|
||||
PE7_DATA, PE6_DATA,
|
||||
PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
|
||||
PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
|
||||
PG7_DATA, PG6_DATA, PG5_DATA,
|
||||
PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
|
||||
PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
|
||||
PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
|
||||
PJ3_DATA, PJ2_DATA, PJ1_DATA,
|
||||
PINMUX_DATA_END,
|
||||
|
||||
PINMUX_INPUT_BEGIN,
|
||||
PA7_IN, PA6_IN, PA5_IN, PA4_IN,
|
||||
PA3_IN, PA2_IN, PA1_IN, PA0_IN,
|
||||
PB7_IN, PB6_IN, PB5_IN, PB4_IN,
|
||||
PB3_IN, PB2_IN, PB1_IN, PB0_IN,
|
||||
PC7_IN, PC6_IN, PC5_IN, PC4_IN,
|
||||
PC3_IN, PC2_IN, PC1_IN, PC0_IN,
|
||||
PD7_IN, PD6_IN, PD5_IN, PD4_IN,
|
||||
PD3_IN, PD2_IN, PD1_IN, PD0_IN,
|
||||
PE7_IN, PE6_IN,
|
||||
PF7_IN, PF6_IN, PF5_IN, PF4_IN,
|
||||
PF3_IN, PF2_IN, PF1_IN, PF0_IN,
|
||||
PG7_IN, PG6_IN, PG5_IN,
|
||||
PH7_IN, PH6_IN, PH5_IN, PH4_IN,
|
||||
PH3_IN, PH2_IN, PH1_IN, PH0_IN,
|
||||
PJ7_IN, PJ6_IN, PJ5_IN, PJ4_IN,
|
||||
PJ3_IN, PJ2_IN, PJ1_IN,
|
||||
PINMUX_INPUT_END,
|
||||
|
||||
PINMUX_OUTPUT_BEGIN,
|
||||
PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
|
||||
PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
|
||||
PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
|
||||
PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
|
||||
PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
|
||||
PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
|
||||
PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
|
||||
PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
|
||||
PE7_OUT, PE6_OUT,
|
||||
PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
|
||||
PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
|
||||
PG7_OUT, PG6_OUT, PG5_OUT,
|
||||
PH7_OUT, PH6_OUT, PH5_OUT, PH4_OUT,
|
||||
PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
|
||||
PJ7_OUT, PJ6_OUT, PJ5_OUT, PJ4_OUT,
|
||||
PJ3_OUT, PJ2_OUT, PJ1_OUT,
|
||||
PINMUX_OUTPUT_END,
|
||||
|
||||
PINMUX_FUNCTION_BEGIN,
|
||||
PA7_FN, PA6_FN, PA5_FN, PA4_FN,
|
||||
PA3_FN, PA2_FN, PA1_FN, PA0_FN,
|
||||
PB7_FN, PB6_FN, PB5_FN, PB4_FN,
|
||||
PB3_FN, PB2_FN, PB1_FN, PB0_FN,
|
||||
PC7_FN, PC6_FN, PC5_FN, PC4_FN,
|
||||
PC3_FN, PC2_FN, PC1_FN, PC0_FN,
|
||||
PD7_FN, PD6_FN, PD5_FN, PD4_FN,
|
||||
PD3_FN, PD2_FN, PD1_FN, PD0_FN,
|
||||
PE7_FN, PE6_FN,
|
||||
PF7_FN, PF6_FN, PF5_FN, PF4_FN,
|
||||
PF3_FN, PF2_FN, PF1_FN, PF0_FN,
|
||||
PG7_FN, PG6_FN, PG5_FN,
|
||||
PH7_FN, PH6_FN, PH5_FN, PH4_FN,
|
||||
PH3_FN, PH2_FN, PH1_FN, PH0_FN,
|
||||
PJ7_FN, PJ6_FN, PJ5_FN, PJ4_FN,
|
||||
PJ3_FN, PJ2_FN, PJ1_FN,
|
||||
P1MSEL14_0, P1MSEL14_1,
|
||||
P1MSEL13_0, P1MSEL13_1,
|
||||
P1MSEL12_0, P1MSEL12_1,
|
||||
P1MSEL11_0, P1MSEL11_1,
|
||||
P1MSEL10_0, P1MSEL10_1,
|
||||
P1MSEL9_0, P1MSEL9_1,
|
||||
P1MSEL8_0, P1MSEL8_1,
|
||||
P1MSEL7_0, P1MSEL7_1,
|
||||
P1MSEL6_0, P1MSEL6_1,
|
||||
P1MSEL5_0, P1MSEL5_1,
|
||||
P1MSEL4_0, P1MSEL4_1,
|
||||
P1MSEL3_0, P1MSEL3_1,
|
||||
P1MSEL2_0, P1MSEL2_1,
|
||||
P1MSEL1_0, P1MSEL1_1,
|
||||
P1MSEL0_0, P1MSEL0_1,
|
||||
|
||||
P2MSEL15_0, P2MSEL15_1,
|
||||
P2MSEL14_0, P2MSEL14_1,
|
||||
P2MSEL13_0, P2MSEL13_1,
|
||||
P2MSEL12_0, P2MSEL12_1,
|
||||
P2MSEL11_0, P2MSEL11_1,
|
||||
P2MSEL10_0, P2MSEL10_1,
|
||||
P2MSEL9_0, P2MSEL9_1,
|
||||
P2MSEL8_0, P2MSEL8_1,
|
||||
P2MSEL7_0, P2MSEL7_1,
|
||||
P2MSEL6_0, P2MSEL6_1,
|
||||
P2MSEL5_0, P2MSEL5_1,
|
||||
P2MSEL4_0, P2MSEL4_1,
|
||||
P2MSEL3_0, P2MSEL3_1,
|
||||
P2MSEL2_0, P2MSEL2_1,
|
||||
P2MSEL1_0, P2MSEL1_1,
|
||||
P2MSEL0_0, P2MSEL0_1,
|
||||
PINMUX_FUNCTION_END,
|
||||
|
||||
PINMUX_MARK_BEGIN,
|
||||
DCLKIN_MARK, DCLKOUT_MARK, ODDF_MARK,
|
||||
VSYNC_MARK, HSYNC_MARK, CDE_MARK, DISP_MARK,
|
||||
DR0_MARK, DR1_MARK, DR2_MARK, DR3_MARK, DR4_MARK, DR5_MARK,
|
||||
DG0_MARK, DG1_MARK, DG2_MARK, DG3_MARK, DG4_MARK, DG5_MARK,
|
||||
DB0_MARK, DB1_MARK, DB2_MARK, DB3_MARK, DB4_MARK, DB5_MARK,
|
||||
ETH_MAGIC_MARK, ETH_LINK_MARK, ETH_TX_ER_MARK, ETH_TX_EN_MARK,
|
||||
ETH_MDIO_MARK, ETH_RX_CLK_MARK, ETH_MDC_MARK, ETH_COL_MARK,
|
||||
ETH_TX_CLK_MARK, ETH_CRS_MARK, ETH_RX_DV_MARK, ETH_RX_ER_MARK,
|
||||
ETH_TXD3_MARK, ETH_TXD2_MARK, ETH_TXD1_MARK, ETH_TXD0_MARK,
|
||||
ETH_RXD3_MARK, ETH_RXD2_MARK, ETH_RXD1_MARK, ETH_RXD0_MARK,
|
||||
HSPI_CLK_MARK, HSPI_CS_MARK, HSPI_RX_MARK, HSPI_TX_MARK,
|
||||
SCIF0_CTS_MARK, SCIF0_RTS_MARK,
|
||||
SCIF0_SCK_MARK, SCIF0_RXD_MARK, SCIF0_TXD_MARK,
|
||||
SCIF1_SCK_MARK, SCIF1_RXD_MARK, SCIF1_TXD_MARK,
|
||||
SCIF3_SCK_MARK, SCIF3_RXD_MARK, SCIF3_TXD_MARK,
|
||||
SCIF4_SCK_MARK, SCIF4_RXD_MARK, SCIF4_TXD_MARK,
|
||||
SCIF5_SCK_MARK, SCIF5_RXD_MARK, SCIF5_TXD_MARK,
|
||||
BREQ_MARK, IOIS16_MARK, CE2B_MARK, CE2A_MARK, BACK_MARK,
|
||||
FALE_MARK, FRB_MARK, FSTATUS_MARK,
|
||||
FSE_MARK, FCLE_MARK,
|
||||
DACK0_MARK, DACK1_MARK, DACK2_MARK, DACK3_MARK,
|
||||
DREQ0_MARK, DREQ1_MARK, DREQ2_MARK, DREQ3_MARK,
|
||||
DRAK0_MARK, DRAK1_MARK, DRAK2_MARK, DRAK3_MARK,
|
||||
USB_OVC1_MARK, USB_OVC0_MARK,
|
||||
USB_PENC1_MARK, USB_PENC0_MARK,
|
||||
HAC_RES_MARK,
|
||||
HAC1_SDOUT_MARK, HAC1_SDIN_MARK, HAC1_SYNC_MARK, HAC1_BITCLK_MARK,
|
||||
HAC0_SDOUT_MARK, HAC0_SDIN_MARK, HAC0_SYNC_MARK, HAC0_BITCLK_MARK,
|
||||
SSI0_SDATA_MARK, SSI0_SCK_MARK, SSI0_WS_MARK, SSI0_CLK_MARK,
|
||||
SSI1_SDATA_MARK, SSI1_SCK_MARK, SSI1_WS_MARK, SSI1_CLK_MARK,
|
||||
SSI2_SDATA_MARK, SSI2_SCK_MARK, SSI2_WS_MARK,
|
||||
SSI3_SDATA_MARK, SSI3_SCK_MARK, SSI3_WS_MARK,
|
||||
SDIF1CMD_MARK, SDIF1CD_MARK, SDIF1WP_MARK, SDIF1CLK_MARK,
|
||||
SDIF1D3_MARK, SDIF1D2_MARK, SDIF1D1_MARK, SDIF1D0_MARK,
|
||||
SDIF0CMD_MARK, SDIF0CD_MARK, SDIF0WP_MARK, SDIF0CLK_MARK,
|
||||
SDIF0D3_MARK, SDIF0D2_MARK, SDIF0D1_MARK, SDIF0D0_MARK,
|
||||
TCLK_MARK,
|
||||
IRL7_MARK, IRL6_MARK, IRL5_MARK, IRL4_MARK,
|
||||
PINMUX_MARK_END,
|
||||
};
|
||||
|
||||
static const u16 pinmux_data[] = {
|
||||
/* PA GPIO */
|
||||
PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT),
|
||||
PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT),
|
||||
PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT),
|
||||
PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT),
|
||||
PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT),
|
||||
PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT),
|
||||
PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT),
|
||||
PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT),
|
||||
|
||||
/* PB GPIO */
|
||||
PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT),
|
||||
PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT),
|
||||
PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT),
|
||||
PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT),
|
||||
PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT),
|
||||
PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT),
|
||||
PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT),
|
||||
PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT),
|
||||
|
||||
/* PC GPIO */
|
||||
PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT),
|
||||
PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT),
|
||||
PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT),
|
||||
PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT),
|
||||
PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT),
|
||||
PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT),
|
||||
PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT),
|
||||
PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT),
|
||||
|
||||
/* PD GPIO */
|
||||
PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT),
|
||||
PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT),
|
||||
PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT),
|
||||
PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT),
|
||||
PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT),
|
||||
PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT),
|
||||
PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT),
|
||||
PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT),
|
||||
|
||||
/* PE GPIO */
|
||||
PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT),
|
||||
PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT),
|
||||
|
||||
/* PF GPIO */
|
||||
PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT),
|
||||
PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT),
|
||||
PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT),
|
||||
PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT),
|
||||
PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT),
|
||||
PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT),
|
||||
PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT),
|
||||
PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT),
|
||||
|
||||
/* PG GPIO */
|
||||
PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT),
|
||||
PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT),
|
||||
PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT),
|
||||
|
||||
/* PH GPIO */
|
||||
PINMUX_DATA(PH7_DATA, PH7_IN, PH7_OUT),
|
||||
PINMUX_DATA(PH6_DATA, PH6_IN, PH6_OUT),
|
||||
PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT),
|
||||
PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT),
|
||||
PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT),
|
||||
PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT),
|
||||
PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT),
|
||||
PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT),
|
||||
|
||||
/* PJ GPIO */
|
||||
PINMUX_DATA(PJ7_DATA, PJ7_IN, PJ7_OUT),
|
||||
PINMUX_DATA(PJ6_DATA, PJ6_IN, PJ6_OUT),
|
||||
PINMUX_DATA(PJ5_DATA, PJ5_IN, PJ5_OUT),
|
||||
PINMUX_DATA(PJ4_DATA, PJ4_IN, PJ4_OUT),
|
||||
PINMUX_DATA(PJ3_DATA, PJ3_IN, PJ3_OUT),
|
||||
PINMUX_DATA(PJ2_DATA, PJ2_IN, PJ2_OUT),
|
||||
PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT),
|
||||
|
||||
/* PA FN */
|
||||
PINMUX_DATA(CDE_MARK, P1MSEL2_0, PA7_FN),
|
||||
PINMUX_DATA(DISP_MARK, P1MSEL2_0, PA6_FN),
|
||||
PINMUX_DATA(DR5_MARK, P1MSEL2_0, PA5_FN),
|
||||
PINMUX_DATA(DR4_MARK, P1MSEL2_0, PA4_FN),
|
||||
PINMUX_DATA(DR3_MARK, P1MSEL2_0, PA3_FN),
|
||||
PINMUX_DATA(DR2_MARK, P1MSEL2_0, PA2_FN),
|
||||
PINMUX_DATA(DR1_MARK, P1MSEL2_0, PA1_FN),
|
||||
PINMUX_DATA(DR0_MARK, P1MSEL2_0, PA0_FN),
|
||||
PINMUX_DATA(ETH_MAGIC_MARK, P1MSEL2_1, PA7_FN),
|
||||
PINMUX_DATA(ETH_LINK_MARK, P1MSEL2_1, PA6_FN),
|
||||
PINMUX_DATA(ETH_TX_ER_MARK, P1MSEL2_1, PA5_FN),
|
||||
PINMUX_DATA(ETH_TX_EN_MARK, P1MSEL2_1, PA4_FN),
|
||||
PINMUX_DATA(ETH_TXD3_MARK, P1MSEL2_1, PA3_FN),
|
||||
PINMUX_DATA(ETH_TXD2_MARK, P1MSEL2_1, PA2_FN),
|
||||
PINMUX_DATA(ETH_TXD1_MARK, P1MSEL2_1, PA1_FN),
|
||||
PINMUX_DATA(ETH_TXD0_MARK, P1MSEL2_1, PA0_FN),
|
||||
|
||||
/* PB FN */
|
||||
PINMUX_DATA(VSYNC_MARK, P1MSEL3_0, PB7_FN),
|
||||
PINMUX_DATA(ODDF_MARK, P1MSEL3_0, PB6_FN),
|
||||
PINMUX_DATA(DG5_MARK, P1MSEL2_0, PB5_FN),
|
||||
PINMUX_DATA(DG4_MARK, P1MSEL2_0, PB4_FN),
|
||||
PINMUX_DATA(DG3_MARK, P1MSEL2_0, PB3_FN),
|
||||
PINMUX_DATA(DG2_MARK, P1MSEL2_0, PB2_FN),
|
||||
PINMUX_DATA(DG1_MARK, P1MSEL2_0, PB1_FN),
|
||||
PINMUX_DATA(DG0_MARK, P1MSEL2_0, PB0_FN),
|
||||
PINMUX_DATA(HSPI_CLK_MARK, P1MSEL3_1, PB7_FN),
|
||||
PINMUX_DATA(HSPI_CS_MARK, P1MSEL3_1, PB6_FN),
|
||||
PINMUX_DATA(ETH_MDIO_MARK, P1MSEL2_1, PB5_FN),
|
||||
PINMUX_DATA(ETH_RX_CLK_MARK, P1MSEL2_1, PB4_FN),
|
||||
PINMUX_DATA(ETH_MDC_MARK, P1MSEL2_1, PB3_FN),
|
||||
PINMUX_DATA(ETH_COL_MARK, P1MSEL2_1, PB2_FN),
|
||||
PINMUX_DATA(ETH_TX_CLK_MARK, P1MSEL2_1, PB1_FN),
|
||||
PINMUX_DATA(ETH_CRS_MARK, P1MSEL2_1, PB0_FN),
|
||||
|
||||
/* PC FN */
|
||||
PINMUX_DATA(DCLKIN_MARK, P1MSEL3_0, PC7_FN),
|
||||
PINMUX_DATA(HSYNC_MARK, P1MSEL3_0, PC6_FN),
|
||||
PINMUX_DATA(DB5_MARK, P1MSEL2_0, PC5_FN),
|
||||
PINMUX_DATA(DB4_MARK, P1MSEL2_0, PC4_FN),
|
||||
PINMUX_DATA(DB3_MARK, P1MSEL2_0, PC3_FN),
|
||||
PINMUX_DATA(DB2_MARK, P1MSEL2_0, PC2_FN),
|
||||
PINMUX_DATA(DB1_MARK, P1MSEL2_0, PC1_FN),
|
||||
PINMUX_DATA(DB0_MARK, P1MSEL2_0, PC0_FN),
|
||||
|
||||
PINMUX_DATA(HSPI_RX_MARK, P1MSEL3_1, PC7_FN),
|
||||
PINMUX_DATA(HSPI_TX_MARK, P1MSEL3_1, PC6_FN),
|
||||
PINMUX_DATA(ETH_RXD3_MARK, P1MSEL2_1, PC5_FN),
|
||||
PINMUX_DATA(ETH_RXD2_MARK, P1MSEL2_1, PC4_FN),
|
||||
PINMUX_DATA(ETH_RXD1_MARK, P1MSEL2_1, PC3_FN),
|
||||
PINMUX_DATA(ETH_RXD0_MARK, P1MSEL2_1, PC2_FN),
|
||||
PINMUX_DATA(ETH_RX_DV_MARK, P1MSEL2_1, PC1_FN),
|
||||
PINMUX_DATA(ETH_RX_ER_MARK, P1MSEL2_1, PC0_FN),
|
||||
|
||||
/* PD FN */
|
||||
PINMUX_DATA(DCLKOUT_MARK, PD7_FN),
|
||||
PINMUX_DATA(SCIF1_SCK_MARK, PD6_FN),
|
||||
PINMUX_DATA(SCIF1_RXD_MARK, PD5_FN),
|
||||
PINMUX_DATA(SCIF1_TXD_MARK, PD4_FN),
|
||||
PINMUX_DATA(DACK1_MARK, P1MSEL13_1, P1MSEL12_0, PD3_FN),
|
||||
PINMUX_DATA(BACK_MARK, P1MSEL13_0, P1MSEL12_1, PD3_FN),
|
||||
PINMUX_DATA(FALE_MARK, P1MSEL13_0, P1MSEL12_0, PD3_FN),
|
||||
PINMUX_DATA(DACK0_MARK, P1MSEL14_1, PD2_FN),
|
||||
PINMUX_DATA(FCLE_MARK, P1MSEL14_0, PD2_FN),
|
||||
PINMUX_DATA(DREQ1_MARK, P1MSEL10_0, P1MSEL9_1, PD1_FN),
|
||||
PINMUX_DATA(BREQ_MARK, P1MSEL10_1, P1MSEL9_0, PD1_FN),
|
||||
PINMUX_DATA(USB_OVC1_MARK, P1MSEL10_0, P1MSEL9_0, PD1_FN),
|
||||
PINMUX_DATA(DREQ0_MARK, P1MSEL11_1, PD0_FN),
|
||||
PINMUX_DATA(USB_OVC0_MARK, P1MSEL11_0, PD0_FN),
|
||||
|
||||
/* PE FN */
|
||||
PINMUX_DATA(USB_PENC1_MARK, PE7_FN),
|
||||
PINMUX_DATA(USB_PENC0_MARK, PE6_FN),
|
||||
|
||||
/* PF FN */
|
||||
PINMUX_DATA(HAC1_SDOUT_MARK, P2MSEL15_0, P2MSEL14_0, PF7_FN),
|
||||
PINMUX_DATA(HAC1_SDIN_MARK, P2MSEL15_0, P2MSEL14_0, PF6_FN),
|
||||
PINMUX_DATA(HAC1_SYNC_MARK, P2MSEL15_0, P2MSEL14_0, PF5_FN),
|
||||
PINMUX_DATA(HAC1_BITCLK_MARK, P2MSEL15_0, P2MSEL14_0, PF4_FN),
|
||||
PINMUX_DATA(HAC0_SDOUT_MARK, P2MSEL13_0, P2MSEL12_0, PF3_FN),
|
||||
PINMUX_DATA(HAC0_SDIN_MARK, P2MSEL13_0, P2MSEL12_0, PF2_FN),
|
||||
PINMUX_DATA(HAC0_SYNC_MARK, P2MSEL13_0, P2MSEL12_0, PF1_FN),
|
||||
PINMUX_DATA(HAC0_BITCLK_MARK, P2MSEL13_0, P2MSEL12_0, PF0_FN),
|
||||
PINMUX_DATA(SSI1_SDATA_MARK, P2MSEL15_0, P2MSEL14_1, PF7_FN),
|
||||
PINMUX_DATA(SSI1_SCK_MARK, P2MSEL15_0, P2MSEL14_1, PF6_FN),
|
||||
PINMUX_DATA(SSI1_WS_MARK, P2MSEL15_0, P2MSEL14_1, PF5_FN),
|
||||
PINMUX_DATA(SSI1_CLK_MARK, P2MSEL15_0, P2MSEL14_1, PF4_FN),
|
||||
PINMUX_DATA(SSI0_SDATA_MARK, P2MSEL13_0, P2MSEL12_1, PF3_FN),
|
||||
PINMUX_DATA(SSI0_SCK_MARK, P2MSEL13_0, P2MSEL12_1, PF2_FN),
|
||||
PINMUX_DATA(SSI0_WS_MARK, P2MSEL13_0, P2MSEL12_1, PF1_FN),
|
||||
PINMUX_DATA(SSI0_CLK_MARK, P2MSEL13_0, P2MSEL12_1, PF0_FN),
|
||||
PINMUX_DATA(SDIF1CMD_MARK, P2MSEL15_1, P2MSEL14_0, PF7_FN),
|
||||
PINMUX_DATA(SDIF1CD_MARK, P2MSEL15_1, P2MSEL14_0, PF6_FN),
|
||||
PINMUX_DATA(SDIF1WP_MARK, P2MSEL15_1, P2MSEL14_0, PF5_FN),
|
||||
PINMUX_DATA(SDIF1CLK_MARK, P2MSEL15_1, P2MSEL14_0, PF4_FN),
|
||||
PINMUX_DATA(SDIF1D3_MARK, P2MSEL13_1, P2MSEL12_0, PF3_FN),
|
||||
PINMUX_DATA(SDIF1D2_MARK, P2MSEL13_1, P2MSEL12_0, PF2_FN),
|
||||
PINMUX_DATA(SDIF1D1_MARK, P2MSEL13_1, P2MSEL12_0, PF1_FN),
|
||||
PINMUX_DATA(SDIF1D0_MARK, P2MSEL13_1, P2MSEL12_0, PF0_FN),
|
||||
|
||||
/* PG FN */
|
||||
PINMUX_DATA(SCIF3_SCK_MARK, P1MSEL8_0, PG7_FN),
|
||||
PINMUX_DATA(SSI2_SDATA_MARK, P1MSEL8_1, PG7_FN),
|
||||
PINMUX_DATA(SCIF3_RXD_MARK, P1MSEL7_0, P1MSEL6_0, PG6_FN),
|
||||
PINMUX_DATA(SSI2_SCK_MARK, P1MSEL7_1, P1MSEL6_0, PG6_FN),
|
||||
PINMUX_DATA(TCLK_MARK, P1MSEL7_0, P1MSEL6_1, PG6_FN),
|
||||
PINMUX_DATA(SCIF3_TXD_MARK, P1MSEL5_0, P1MSEL4_0, PG5_FN),
|
||||
PINMUX_DATA(SSI2_WS_MARK, P1MSEL5_1, P1MSEL4_0, PG5_FN),
|
||||
PINMUX_DATA(HAC_RES_MARK, P1MSEL5_0, P1MSEL4_1, PG5_FN),
|
||||
|
||||
/* PH FN */
|
||||
PINMUX_DATA(DACK3_MARK, P2MSEL4_0, PH7_FN),
|
||||
PINMUX_DATA(SDIF0CMD_MARK, P2MSEL4_1, PH7_FN),
|
||||
PINMUX_DATA(DACK2_MARK, P2MSEL4_0, PH6_FN),
|
||||
PINMUX_DATA(SDIF0CD_MARK, P2MSEL4_1, PH6_FN),
|
||||
PINMUX_DATA(DREQ3_MARK, P2MSEL4_0, PH5_FN),
|
||||
PINMUX_DATA(SDIF0WP_MARK, P2MSEL4_1, PH5_FN),
|
||||
PINMUX_DATA(DREQ2_MARK, P2MSEL3_0, P2MSEL2_1, PH4_FN),
|
||||
PINMUX_DATA(SDIF0CLK_MARK, P2MSEL3_1, P2MSEL2_0, PH4_FN),
|
||||
PINMUX_DATA(SCIF0_CTS_MARK, P2MSEL3_0, P2MSEL2_0, PH4_FN),
|
||||
PINMUX_DATA(SDIF0D3_MARK, P2MSEL1_1, P2MSEL0_0, PH3_FN),
|
||||
PINMUX_DATA(SCIF0_RTS_MARK, P2MSEL1_0, P2MSEL0_0, PH3_FN),
|
||||
PINMUX_DATA(IRL7_MARK, P2MSEL1_0, P2MSEL0_1, PH3_FN),
|
||||
PINMUX_DATA(SDIF0D2_MARK, P2MSEL1_1, P2MSEL0_0, PH2_FN),
|
||||
PINMUX_DATA(SCIF0_SCK_MARK, P2MSEL1_0, P2MSEL0_0, PH2_FN),
|
||||
PINMUX_DATA(IRL6_MARK, P2MSEL1_0, P2MSEL0_1, PH2_FN),
|
||||
PINMUX_DATA(SDIF0D1_MARK, P2MSEL1_1, P2MSEL0_0, PH1_FN),
|
||||
PINMUX_DATA(SCIF0_RXD_MARK, P2MSEL1_0, P2MSEL0_0, PH1_FN),
|
||||
PINMUX_DATA(IRL5_MARK, P2MSEL1_0, P2MSEL0_1, PH1_FN),
|
||||
PINMUX_DATA(SDIF0D0_MARK, P2MSEL1_1, P2MSEL0_0, PH0_FN),
|
||||
PINMUX_DATA(SCIF0_TXD_MARK, P2MSEL1_0, P2MSEL0_0, PH0_FN),
|
||||
PINMUX_DATA(IRL4_MARK, P2MSEL1_0, P2MSEL0_1, PH0_FN),
|
||||
|
||||
/* PJ FN */
|
||||
PINMUX_DATA(SCIF5_SCK_MARK, P2MSEL11_1, PJ7_FN),
|
||||
PINMUX_DATA(FRB_MARK, P2MSEL11_0, PJ7_FN),
|
||||
PINMUX_DATA(SCIF5_RXD_MARK, P2MSEL10_0, PJ6_FN),
|
||||
PINMUX_DATA(IOIS16_MARK, P2MSEL10_1, PJ6_FN),
|
||||
PINMUX_DATA(SCIF5_TXD_MARK, P2MSEL10_0, PJ5_FN),
|
||||
PINMUX_DATA(CE2B_MARK, P2MSEL10_1, PJ5_FN),
|
||||
PINMUX_DATA(DRAK3_MARK, P2MSEL7_0, PJ4_FN),
|
||||
PINMUX_DATA(CE2A_MARK, P2MSEL7_1, PJ4_FN),
|
||||
PINMUX_DATA(SCIF4_SCK_MARK, P2MSEL9_0, P2MSEL8_0, PJ3_FN),
|
||||
PINMUX_DATA(DRAK2_MARK, P2MSEL9_0, P2MSEL8_1, PJ3_FN),
|
||||
PINMUX_DATA(SSI3_WS_MARK, P2MSEL9_1, P2MSEL8_0, PJ3_FN),
|
||||
PINMUX_DATA(SCIF4_RXD_MARK, P2MSEL6_1, P2MSEL5_0, PJ2_FN),
|
||||
PINMUX_DATA(DRAK1_MARK, P2MSEL6_0, P2MSEL5_1, PJ2_FN),
|
||||
PINMUX_DATA(FSTATUS_MARK, P2MSEL6_0, P2MSEL5_0, PJ2_FN),
|
||||
PINMUX_DATA(SSI3_SDATA_MARK, P2MSEL6_1, P2MSEL5_1, PJ2_FN),
|
||||
PINMUX_DATA(SCIF4_TXD_MARK, P2MSEL6_1, P2MSEL5_0, PJ1_FN),
|
||||
PINMUX_DATA(DRAK0_MARK, P2MSEL6_0, P2MSEL5_1, PJ1_FN),
|
||||
PINMUX_DATA(FSE_MARK, P2MSEL6_0, P2MSEL5_0, PJ1_FN),
|
||||
PINMUX_DATA(SSI3_SCK_MARK, P2MSEL6_1, P2MSEL5_1, PJ1_FN),
|
||||
};
|
||||
|
||||
static const struct sh_pfc_pin pinmux_pins[] = {
|
||||
/* PA */
|
||||
PINMUX_GPIO(PA7),
|
||||
PINMUX_GPIO(PA6),
|
||||
PINMUX_GPIO(PA5),
|
||||
PINMUX_GPIO(PA4),
|
||||
PINMUX_GPIO(PA3),
|
||||
PINMUX_GPIO(PA2),
|
||||
PINMUX_GPIO(PA1),
|
||||
PINMUX_GPIO(PA0),
|
||||
|
||||
/* PB */
|
||||
PINMUX_GPIO(PB7),
|
||||
PINMUX_GPIO(PB6),
|
||||
PINMUX_GPIO(PB5),
|
||||
PINMUX_GPIO(PB4),
|
||||
PINMUX_GPIO(PB3),
|
||||
PINMUX_GPIO(PB2),
|
||||
PINMUX_GPIO(PB1),
|
||||
PINMUX_GPIO(PB0),
|
||||
|
||||
/* PC */
|
||||
PINMUX_GPIO(PC7),
|
||||
PINMUX_GPIO(PC6),
|
||||
PINMUX_GPIO(PC5),
|
||||
PINMUX_GPIO(PC4),
|
||||
PINMUX_GPIO(PC3),
|
||||
PINMUX_GPIO(PC2),
|
||||
PINMUX_GPIO(PC1),
|
||||
PINMUX_GPIO(PC0),
|
||||
|
||||
/* PD */
|
||||
PINMUX_GPIO(PD7),
|
||||
PINMUX_GPIO(PD6),
|
||||
PINMUX_GPIO(PD5),
|
||||
PINMUX_GPIO(PD4),
|
||||
PINMUX_GPIO(PD3),
|
||||
PINMUX_GPIO(PD2),
|
||||
PINMUX_GPIO(PD1),
|
||||
PINMUX_GPIO(PD0),
|
||||
|
||||
/* PE */
|
||||
PINMUX_GPIO(PE7),
|
||||
PINMUX_GPIO(PE6),
|
||||
|
||||
/* PF */
|
||||
PINMUX_GPIO(PF7),
|
||||
PINMUX_GPIO(PF6),
|
||||
PINMUX_GPIO(PF5),
|
||||
PINMUX_GPIO(PF4),
|
||||
PINMUX_GPIO(PF3),
|
||||
PINMUX_GPIO(PF2),
|
||||
PINMUX_GPIO(PF1),
|
||||
PINMUX_GPIO(PF0),
|
||||
|
||||
/* PG */
|
||||
PINMUX_GPIO(PG7),
|
||||
PINMUX_GPIO(PG6),
|
||||
PINMUX_GPIO(PG5),
|
||||
|
||||
/* PH */
|
||||
PINMUX_GPIO(PH7),
|
||||
PINMUX_GPIO(PH6),
|
||||
PINMUX_GPIO(PH5),
|
||||
PINMUX_GPIO(PH4),
|
||||
PINMUX_GPIO(PH3),
|
||||
PINMUX_GPIO(PH2),
|
||||
PINMUX_GPIO(PH1),
|
||||
PINMUX_GPIO(PH0),
|
||||
|
||||
/* PJ */
|
||||
PINMUX_GPIO(PJ7),
|
||||
PINMUX_GPIO(PJ6),
|
||||
PINMUX_GPIO(PJ5),
|
||||
PINMUX_GPIO(PJ4),
|
||||
PINMUX_GPIO(PJ3),
|
||||
PINMUX_GPIO(PJ2),
|
||||
PINMUX_GPIO(PJ1),
|
||||
};
|
||||
|
||||
#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins)
|
||||
|
||||
static const struct pinmux_func pinmux_func_gpios[] = {
|
||||
/* FN */
|
||||
GPIO_FN(CDE),
|
||||
GPIO_FN(ETH_MAGIC),
|
||||
GPIO_FN(DISP),
|
||||
GPIO_FN(ETH_LINK),
|
||||
GPIO_FN(DR5),
|
||||
GPIO_FN(ETH_TX_ER),
|
||||
GPIO_FN(DR4),
|
||||
GPIO_FN(ETH_TX_EN),
|
||||
GPIO_FN(DR3),
|
||||
GPIO_FN(ETH_TXD3),
|
||||
GPIO_FN(DR2),
|
||||
GPIO_FN(ETH_TXD2),
|
||||
GPIO_FN(DR1),
|
||||
GPIO_FN(ETH_TXD1),
|
||||
GPIO_FN(DR0),
|
||||
GPIO_FN(ETH_TXD0),
|
||||
GPIO_FN(VSYNC),
|
||||
GPIO_FN(HSPI_CLK),
|
||||
GPIO_FN(ODDF),
|
||||
GPIO_FN(HSPI_CS),
|
||||
GPIO_FN(DG5),
|
||||
GPIO_FN(ETH_MDIO),
|
||||
GPIO_FN(DG4),
|
||||
GPIO_FN(ETH_RX_CLK),
|
||||
GPIO_FN(DG3),
|
||||
GPIO_FN(ETH_MDC),
|
||||
GPIO_FN(DG2),
|
||||
GPIO_FN(ETH_COL),
|
||||
GPIO_FN(DG1),
|
||||
GPIO_FN(ETH_TX_CLK),
|
||||
GPIO_FN(DG0),
|
||||
GPIO_FN(ETH_CRS),
|
||||
GPIO_FN(DCLKIN),
|
||||
GPIO_FN(HSPI_RX),
|
||||
GPIO_FN(HSYNC),
|
||||
GPIO_FN(HSPI_TX),
|
||||
GPIO_FN(DB5),
|
||||
GPIO_FN(ETH_RXD3),
|
||||
GPIO_FN(DB4),
|
||||
GPIO_FN(ETH_RXD2),
|
||||
GPIO_FN(DB3),
|
||||
GPIO_FN(ETH_RXD1),
|
||||
GPIO_FN(DB2),
|
||||
GPIO_FN(ETH_RXD0),
|
||||
GPIO_FN(DB1),
|
||||
GPIO_FN(ETH_RX_DV),
|
||||
GPIO_FN(DB0),
|
||||
GPIO_FN(ETH_RX_ER),
|
||||
GPIO_FN(DCLKOUT),
|
||||
GPIO_FN(SCIF1_SCK),
|
||||
GPIO_FN(SCIF1_RXD),
|
||||
GPIO_FN(SCIF1_TXD),
|
||||
GPIO_FN(DACK1),
|
||||
GPIO_FN(BACK),
|
||||
GPIO_FN(FALE),
|
||||
GPIO_FN(DACK0),
|
||||
GPIO_FN(FCLE),
|
||||
GPIO_FN(DREQ1),
|
||||
GPIO_FN(BREQ),
|
||||
GPIO_FN(USB_OVC1),
|
||||
GPIO_FN(DREQ0),
|
||||
GPIO_FN(USB_OVC0),
|
||||
GPIO_FN(USB_PENC1),
|
||||
GPIO_FN(USB_PENC0),
|
||||
GPIO_FN(HAC1_SDOUT),
|
||||
GPIO_FN(SSI1_SDATA),
|
||||
GPIO_FN(SDIF1CMD),
|
||||
GPIO_FN(HAC1_SDIN),
|
||||
GPIO_FN(SSI1_SCK),
|
||||
GPIO_FN(SDIF1CD),
|
||||
GPIO_FN(HAC1_SYNC),
|
||||
GPIO_FN(SSI1_WS),
|
||||
GPIO_FN(SDIF1WP),
|
||||
GPIO_FN(HAC1_BITCLK),
|
||||
GPIO_FN(SSI1_CLK),
|
||||
GPIO_FN(SDIF1CLK),
|
||||
GPIO_FN(HAC0_SDOUT),
|
||||
GPIO_FN(SSI0_SDATA),
|
||||
GPIO_FN(SDIF1D3),
|
||||
GPIO_FN(HAC0_SDIN),
|
||||
GPIO_FN(SSI0_SCK),
|
||||
GPIO_FN(SDIF1D2),
|
||||
GPIO_FN(HAC0_SYNC),
|
||||
GPIO_FN(SSI0_WS),
|
||||
GPIO_FN(SDIF1D1),
|
||||
GPIO_FN(HAC0_BITCLK),
|
||||
GPIO_FN(SSI0_CLK),
|
||||
GPIO_FN(SDIF1D0),
|
||||
GPIO_FN(SCIF3_SCK),
|
||||
GPIO_FN(SSI2_SDATA),
|
||||
GPIO_FN(SCIF3_RXD),
|
||||
GPIO_FN(TCLK),
|
||||
GPIO_FN(SSI2_SCK),
|
||||
GPIO_FN(SCIF3_TXD),
|
||||
GPIO_FN(HAC_RES),
|
||||
GPIO_FN(SSI2_WS),
|
||||
GPIO_FN(DACK3),
|
||||
GPIO_FN(SDIF0CMD),
|
||||
GPIO_FN(DACK2),
|
||||
GPIO_FN(SDIF0CD),
|
||||
GPIO_FN(DREQ3),
|
||||
GPIO_FN(SDIF0WP),
|
||||
GPIO_FN(SCIF0_CTS),
|
||||
GPIO_FN(DREQ2),
|
||||
GPIO_FN(SDIF0CLK),
|
||||
GPIO_FN(SCIF0_RTS),
|
||||
GPIO_FN(IRL7),
|
||||
GPIO_FN(SDIF0D3),
|
||||
GPIO_FN(SCIF0_SCK),
|
||||
GPIO_FN(IRL6),
|
||||
GPIO_FN(SDIF0D2),
|
||||
GPIO_FN(SCIF0_RXD),
|
||||
GPIO_FN(IRL5),
|
||||
GPIO_FN(SDIF0D1),
|
||||
GPIO_FN(SCIF0_TXD),
|
||||
GPIO_FN(IRL4),
|
||||
GPIO_FN(SDIF0D0),
|
||||
GPIO_FN(SCIF5_SCK),
|
||||
GPIO_FN(FRB),
|
||||
GPIO_FN(SCIF5_RXD),
|
||||
GPIO_FN(IOIS16),
|
||||
GPIO_FN(SCIF5_TXD),
|
||||
GPIO_FN(CE2B),
|
||||
GPIO_FN(DRAK3),
|
||||
GPIO_FN(CE2A),
|
||||
GPIO_FN(SCIF4_SCK),
|
||||
GPIO_FN(DRAK2),
|
||||
GPIO_FN(SSI3_WS),
|
||||
GPIO_FN(SCIF4_RXD),
|
||||
GPIO_FN(DRAK1),
|
||||
GPIO_FN(SSI3_SDATA),
|
||||
GPIO_FN(FSTATUS),
|
||||
GPIO_FN(SCIF4_TXD),
|
||||
GPIO_FN(DRAK0),
|
||||
GPIO_FN(SSI3_SCK),
|
||||
GPIO_FN(FSE),
|
||||
};
|
||||
|
||||
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
|
||||
{ PINMUX_CFG_REG("PACR", 0xffcc0000, 16, 2) {
|
||||
PA7_FN, PA7_OUT, PA7_IN, 0,
|
||||
PA6_FN, PA6_OUT, PA6_IN, 0,
|
||||
PA5_FN, PA5_OUT, PA5_IN, 0,
|
||||
PA4_FN, PA4_OUT, PA4_IN, 0,
|
||||
PA3_FN, PA3_OUT, PA3_IN, 0,
|
||||
PA2_FN, PA2_OUT, PA2_IN, 0,
|
||||
PA1_FN, PA1_OUT, PA1_IN, 0,
|
||||
PA0_FN, PA0_OUT, PA0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PBCR", 0xffcc0002, 16, 2) {
|
||||
PB7_FN, PB7_OUT, PB7_IN, 0,
|
||||
PB6_FN, PB6_OUT, PB6_IN, 0,
|
||||
PB5_FN, PB5_OUT, PB5_IN, 0,
|
||||
PB4_FN, PB4_OUT, PB4_IN, 0,
|
||||
PB3_FN, PB3_OUT, PB3_IN, 0,
|
||||
PB2_FN, PB2_OUT, PB2_IN, 0,
|
||||
PB1_FN, PB1_OUT, PB1_IN, 0,
|
||||
PB0_FN, PB0_OUT, PB0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PCCR", 0xffcc0004, 16, 2) {
|
||||
PC7_FN, PC7_OUT, PC7_IN, 0,
|
||||
PC6_FN, PC6_OUT, PC6_IN, 0,
|
||||
PC5_FN, PC5_OUT, PC5_IN, 0,
|
||||
PC4_FN, PC4_OUT, PC4_IN, 0,
|
||||
PC3_FN, PC3_OUT, PC3_IN, 0,
|
||||
PC2_FN, PC2_OUT, PC2_IN, 0,
|
||||
PC1_FN, PC1_OUT, PC1_IN, 0,
|
||||
PC0_FN, PC0_OUT, PC0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PDCR", 0xffcc0006, 16, 2) {
|
||||
PD7_FN, PD7_OUT, PD7_IN, 0,
|
||||
PD6_FN, PD6_OUT, PD6_IN, 0,
|
||||
PD5_FN, PD5_OUT, PD5_IN, 0,
|
||||
PD4_FN, PD4_OUT, PD4_IN, 0,
|
||||
PD3_FN, PD3_OUT, PD3_IN, 0,
|
||||
PD2_FN, PD2_OUT, PD2_IN, 0,
|
||||
PD1_FN, PD1_OUT, PD1_IN, 0,
|
||||
PD0_FN, PD0_OUT, PD0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PECR", 0xffcc0008, 16, 2) {
|
||||
PE7_FN, PE7_OUT, PE7_IN, 0,
|
||||
PE6_FN, PE6_OUT, PE6_IN, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0, }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PFCR", 0xffcc000a, 16, 2) {
|
||||
PF7_FN, PF7_OUT, PF7_IN, 0,
|
||||
PF6_FN, PF6_OUT, PF6_IN, 0,
|
||||
PF5_FN, PF5_OUT, PF5_IN, 0,
|
||||
PF4_FN, PF4_OUT, PF4_IN, 0,
|
||||
PF3_FN, PF3_OUT, PF3_IN, 0,
|
||||
PF2_FN, PF2_OUT, PF2_IN, 0,
|
||||
PF1_FN, PF1_OUT, PF1_IN, 0,
|
||||
PF0_FN, PF0_OUT, PF0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PGCR", 0xffcc000c, 16, 2) {
|
||||
PG7_FN, PG7_OUT, PG7_IN, 0,
|
||||
PG6_FN, PG6_OUT, PG6_IN, 0,
|
||||
PG5_FN, PG5_OUT, PG5_IN, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0, }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PHCR", 0xffcc000e, 16, 2) {
|
||||
PH7_FN, PH7_OUT, PH7_IN, 0,
|
||||
PH6_FN, PH6_OUT, PH6_IN, 0,
|
||||
PH5_FN, PH5_OUT, PH5_IN, 0,
|
||||
PH4_FN, PH4_OUT, PH4_IN, 0,
|
||||
PH3_FN, PH3_OUT, PH3_IN, 0,
|
||||
PH2_FN, PH2_OUT, PH2_IN, 0,
|
||||
PH1_FN, PH1_OUT, PH1_IN, 0,
|
||||
PH0_FN, PH0_OUT, PH0_IN, 0 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("PJCR", 0xffcc0010, 16, 2) {
|
||||
PJ7_FN, PJ7_OUT, PJ7_IN, 0,
|
||||
PJ6_FN, PJ6_OUT, PJ6_IN, 0,
|
||||
PJ5_FN, PJ5_OUT, PJ5_IN, 0,
|
||||
PJ4_FN, PJ4_OUT, PJ4_IN, 0,
|
||||
PJ3_FN, PJ3_OUT, PJ3_IN, 0,
|
||||
PJ2_FN, PJ2_OUT, PJ2_IN, 0,
|
||||
PJ1_FN, PJ1_OUT, PJ1_IN, 0,
|
||||
0, 0, 0, 0, }
|
||||
},
|
||||
{ PINMUX_CFG_REG("P1MSELR", 0xffcc0080, 16, 1) {
|
||||
0, 0,
|
||||
P1MSEL14_0, P1MSEL14_1,
|
||||
P1MSEL13_0, P1MSEL13_1,
|
||||
P1MSEL12_0, P1MSEL12_1,
|
||||
P1MSEL11_0, P1MSEL11_1,
|
||||
P1MSEL10_0, P1MSEL10_1,
|
||||
P1MSEL9_0, P1MSEL9_1,
|
||||
P1MSEL8_0, P1MSEL8_1,
|
||||
P1MSEL7_0, P1MSEL7_1,
|
||||
P1MSEL6_0, P1MSEL6_1,
|
||||
P1MSEL5_0, P1MSEL5_1,
|
||||
P1MSEL4_0, P1MSEL4_1,
|
||||
P1MSEL3_0, P1MSEL3_1,
|
||||
P1MSEL2_0, P1MSEL2_1,
|
||||
P1MSEL1_0, P1MSEL1_1,
|
||||
P1MSEL0_0, P1MSEL0_1 }
|
||||
},
|
||||
{ PINMUX_CFG_REG("P2MSELR", 0xffcc0082, 16, 1) {
|
||||
P2MSEL15_0, P2MSEL15_1,
|
||||
P2MSEL14_0, P2MSEL14_1,
|
||||
P2MSEL13_0, P2MSEL13_1,
|
||||
P2MSEL12_0, P2MSEL12_1,
|
||||
P2MSEL11_0, P2MSEL11_1,
|
||||
P2MSEL10_0, P2MSEL10_1,
|
||||
P2MSEL9_0, P2MSEL9_1,
|
||||
P2MSEL8_0, P2MSEL8_1,
|
||||
P2MSEL7_0, P2MSEL7_1,
|
||||
P2MSEL6_0, P2MSEL6_1,
|
||||
P2MSEL5_0, P2MSEL5_1,
|
||||
P2MSEL4_0, P2MSEL4_1,
|
||||
P2MSEL3_0, P2MSEL3_1,
|
||||
P2MSEL2_0, P2MSEL2_1,
|
||||
P2MSEL1_0, P2MSEL1_1,
|
||||
P2MSEL0_0, P2MSEL0_1 }
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct pinmux_data_reg pinmux_data_regs[] = {
|
||||
{ PINMUX_DATA_REG("PADR", 0xffcc0020, 8) {
|
||||
PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
|
||||
PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PBDR", 0xffcc0022, 8) {
|
||||
PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
|
||||
PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PCDR", 0xffcc0024, 8) {
|
||||
PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
|
||||
PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PDDR", 0xffcc0026, 8) {
|
||||
PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
|
||||
PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PEDR", 0xffcc0028, 8) {
|
||||
PE7_DATA, PE6_DATA,
|
||||
0, 0, 0, 0, 0, 0 }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PFDR", 0xffcc002a, 8) {
|
||||
PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
|
||||
PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PGDR", 0xffcc002c, 8) {
|
||||
PG7_DATA, PG6_DATA, PG5_DATA, 0,
|
||||
0, 0, 0, 0 }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PHDR", 0xffcc002e, 8) {
|
||||
PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
|
||||
PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA }
|
||||
},
|
||||
{ PINMUX_DATA_REG("PJDR", 0xffcc0030, 8) {
|
||||
PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
|
||||
PJ3_DATA, PJ2_DATA, PJ1_DATA, 0 }
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
const struct sh_pfc_soc_info sh7786_pinmux_info = {
|
||||
.name = "sh7786_pfc",
|
||||
.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
|
||||
.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
|
||||
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
||||
|
||||
.pins = pinmux_pins,
|
||||
.nr_pins = ARRAY_SIZE(pinmux_pins),
|
||||
.func_gpios = pinmux_func_gpios,
|
||||
.nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios),
|
||||
|
||||
.cfg_regs = pinmux_config_regs,
|
||||
.data_regs = pinmux_data_regs,
|
||||
|
||||
.gpio_data = pinmux_data,
|
||||
.gpio_data_size = ARRAY_SIZE(pinmux_data),
|
||||
};
|
561
drivers/pinctrl/sh-pfc/pfc-shx3.c
Normal file
561
drivers/pinctrl/sh-pfc/pfc-shx3.c
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*
|
||||
* SH-X3 prototype CPU pinmux
|
||||
*
|
||||
* Copyright (C) 2010 Paul Mundt
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <cpu/shx3.h>
|
||||
|
||||
#include "sh_pfc.h"
|
||||
|
||||
enum {
|
||||
PINMUX_RESERVED = 0,
|
||||
|
||||
PINMUX_DATA_BEGIN,
|
||||
PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
|
||||
PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
|
||||
PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
|
||||
PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
|
||||
PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
|
||||
PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
|
||||
PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
|
||||
PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
|
||||
PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
|
||||
PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
|
||||
PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
|
||||
PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
|
||||
PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
|
||||
PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
|
||||
|
||||
PH5_DATA, PH4_DATA,
|
||||
PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
|
||||
PINMUX_DATA_END,
|
||||
|
||||
PINMUX_INPUT_BEGIN,
|
||||
PA7_IN, PA6_IN, PA5_IN, PA4_IN,
|
||||
PA3_IN, PA2_IN, PA1_IN, PA0_IN,
|
||||
PB7_IN, PB6_IN, PB5_IN, PB4_IN,
|
||||
PB3_IN, PB2_IN, PB1_IN, PB0_IN,
|
||||
PC7_IN, PC6_IN, PC5_IN, PC4_IN,
|
||||
PC3_IN, PC2_IN, PC1_IN, PC0_IN,
|
||||
PD7_IN, PD6_IN, PD5_IN, PD4_IN,
|
||||
PD3_IN, PD2_IN, PD1_IN, PD0_IN,
|
||||
PE7_IN, PE6_IN, PE5_IN, PE4_IN,
|
||||
PE3_IN, PE2_IN, PE1_IN, PE0_IN,
|
||||
PF7_IN, PF6_IN, PF5_IN, PF4_IN,
|
||||
PF3_IN, PF2_IN, PF1_IN, PF0_IN,
|
||||
PG7_IN, PG6_IN, PG5_IN, PG4_IN,
|
||||
PG3_IN, PG2_IN, PG1_IN, PG0_IN,
|
||||
|
||||
PH5_IN, PH4_IN,
|
||||
PH3_IN, PH2_IN, PH1_IN, PH0_IN,
|
||||
PINMUX_INPUT_END,
|
||||
|
||||
PINMUX_OUTPUT_BEGIN,
|
||||
PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
|
||||
PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
|
||||
PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
|
||||
PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
|
||||
PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
|
||||
PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
|
||||
PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
|
||||
PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
|
||||
PE7_OUT, PE6_OUT, PE5_OUT, PE4_OUT,
|
||||
PE3_OUT, PE2_OUT, PE1_OUT, PE0_OUT,
|
||||
PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
|
||||
PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
|
||||
PG7_OUT, PG6_OUT, PG5_OUT, PG4_OUT,
|
||||
PG3_OUT, PG2_OUT, PG1_OUT, PG0_OUT,
|
||||
|
||||
PH5_OUT, PH4_OUT,
|
||||
PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
|
||||
PINMUX_OUTPUT_END,
|
||||
|
||||
PINMUX_FUNCTION_BEGIN,
|
||||
PA7_FN, PA6_FN, PA5_FN, PA4_FN,
|
||||
PA3_FN, PA2_FN, PA1_FN, PA0_FN,
|
||||
PB7_FN, PB6_FN, PB5_FN, PB4_FN,
|
||||
PB3_FN, PB2_FN, PB1_FN, PB0_FN,
|
||||
PC7_FN, PC6_FN, PC5_FN, PC4_FN,
|
||||
PC3_FN, PC2_FN, PC1_FN, PC0_FN,
|
||||
PD7_FN, PD6_FN, PD5_FN, PD4_FN,
|
||||
PD3_FN, PD2_FN, PD1_FN, PD0_FN,
|
||||
PE7_FN, PE6_FN, PE5_FN, PE4_FN,
|
||||
PE3_FN, PE2_FN, PE1_FN, PE0_FN,
|
||||
PF7_FN, PF6_FN, PF5_FN, PF4_FN,
|
||||
PF3_FN, PF2_FN, PF1_FN, PF0_FN,
|
||||
PG7_FN, PG6_FN, PG5_FN, PG4_FN,
|
||||
PG3_FN, PG2_FN, PG1_FN, PG0_FN,
|
||||
|
||||
PH5_FN, PH4_FN,
|
||||
PH3_FN, PH2_FN, PH1_FN, PH0_FN,
|
||||
PINMUX_FUNCTION_END,
|
||||
|
||||
PINMUX_MARK_BEGIN,
|
||||
|
||||
D31_MARK, D30_MARK, D29_MARK, D28_MARK, D27_MARK, D26_MARK,
|
||||
D25_MARK, D24_MARK, D23_MARK, D22_MARK, D21_MARK, D20_MARK,
|
||||
D19_MARK, D18_MARK, D17_MARK, D16_MARK,
|
||||
|
||||
BACK_MARK, BREQ_MARK,
|
||||
WE3_MARK, WE2_MARK,
|
||||
CS6_MARK, CS5_MARK, CS4_MARK,
|
||||
CLKOUTENB_MARK,
|
||||
|
||||
DACK3_MARK, DACK2_MARK, DACK1_MARK, DACK0_MARK,
|
||||
DREQ3_MARK, DREQ2_MARK, DREQ1_MARK, DREQ0_MARK,
|
||||
|
||||
IRQ3_MARK, IRQ2_MARK, IRQ1_MARK, IRQ0_MARK,
|
||||
|
||||
DRAK3_MARK, DRAK2_MARK, DRAK1_MARK, DRAK0_MARK,
|
||||
|
||||
SCK3_MARK, SCK2_MARK, SCK1_MARK, SCK0_MARK,
|
||||
IRL3_MARK, IRL2_MARK, IRL1_MARK, IRL0_MARK,
|
||||
TXD3_MARK, TXD2_MARK, TXD1_MARK, TXD0_MARK,
|
||||
RXD3_MARK, RXD2_MARK, RXD1_MARK, RXD0_MARK,
|
||||
|
||||
CE2B_MARK, CE2A_MARK, IOIS16_MARK,
|
||||
STATUS1_MARK, STATUS0_MARK,
|
||||
|
||||
IRQOUT_MARK,
|
||||
|
||||
PINMUX_MARK_END,
|
||||
};
|
||||
|
||||
static const u16 pinmux_data[] = {
|
||||
/* PA GPIO */
|
||||
PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT),
|
||||
PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT),
|
||||
PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT),
|
||||
PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT),
|
||||
PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT),
|
||||
PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT),
|
||||
PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT),
|
||||
PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT),
|
||||
|
||||
/* PB GPIO */
|
||||
PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT),
|
||||
PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT),
|
||||
PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT),
|
||||
PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT),
|
||||
PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT),
|
||||
PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT),
|
||||
PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT),
|
||||
PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT),
|
||||
|
||||
/* PC GPIO */
|
||||
PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT),
|
||||
PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT),
|
||||
PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT),
|
||||
PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT),
|
||||
PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT),
|
||||
PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT),
|
||||
PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT),
|
||||
PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT),
|
||||
|
||||
/* PD GPIO */
|
||||
PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT),
|
||||
PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT),
|
||||
PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT),
|
||||
PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT),
|
||||
PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT),
|
||||
PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT),
|
||||
PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT),
|
||||
PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT),
|
||||
|
||||
/* PE GPIO */
|
||||
PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT),
|
||||
PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT),
|
||||
PINMUX_DATA(PE5_DATA, PE5_IN, PE5_OUT),
|
||||
PINMUX_DATA(PE4_DATA, PE4_IN, PE4_OUT),
|
||||
PINMUX_DATA(PE3_DATA, PE3_IN, PE3_OUT),
|
||||
PINMUX_DATA(PE2_DATA, PE2_IN, PE2_OUT),
|
||||
PINMUX_DATA(PE1_DATA, PE1_IN, PE1_OUT),
|
||||
PINMUX_DATA(PE0_DATA, PE0_IN, PE0_OUT),
|
||||
|
||||
/* PF GPIO */
|
||||
PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT),
|
||||
PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT),
|
||||
PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT),
|
||||
PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT),
|
||||
PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT),
|
||||
PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT),
|
||||
PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT),
|
||||
PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT),
|
||||
|
||||
/* PG GPIO */
|
||||
PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT),
|
||||
PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT),
|
||||
PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT),
|
||||
PINMUX_DATA(PG4_DATA, PG4_IN, PG4_OUT),
|
||||
PINMUX_DATA(PG3_DATA, PG3_IN, PG3_OUT),
|
||||
PINMUX_DATA(PG2_DATA, PG2_IN, PG2_OUT),
|
||||
PINMUX_DATA(PG1_DATA, PG1_IN, PG1_OUT),
|
||||
PINMUX_DATA(PG0_DATA, PG0_IN, PG0_OUT),
|
||||
|
||||
/* PH GPIO */
|
||||
PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT),
|
||||
PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT),
|
||||
PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT),
|
||||
PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT),
|
||||
PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT),
|
||||
PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT),
|
||||
|
||||
/* PA FN */
|
||||
PINMUX_DATA(D31_MARK, PA7_FN),
|
||||
PINMUX_DATA(D30_MARK, PA6_FN),
|
||||
PINMUX_DATA(D29_MARK, PA5_FN),
|
||||
PINMUX_DATA(D28_MARK, PA4_FN),
|
||||
PINMUX_DATA(D27_MARK, PA3_FN),
|
||||
PINMUX_DATA(D26_MARK, PA2_FN),
|
||||
PINMUX_DATA(D25_MARK, PA1_FN),
|
||||
PINMUX_DATA(D24_MARK, PA0_FN),
|
||||
|
||||
/* PB FN */
|
||||
PINMUX_DATA(D23_MARK, PB7_FN),
|
||||
PINMUX_DATA(D22_MARK, PB6_FN),
|
||||
PINMUX_DATA(D21_MARK, PB5_FN),
|
||||
PINMUX_DATA(D20_MARK, PB4_FN),
|
||||
PINMUX_DATA(D19_MARK, PB3_FN),
|
||||
PINMUX_DATA(D18_MARK, PB2_FN),
|
||||
PINMUX_DATA(D17_MARK, PB1_FN),
|
||||
PINMUX_DATA(D16_MARK, PB0_FN),
|
||||
|
||||
/* PC FN */
|
||||
PINMUX_DATA(BACK_MARK, PC7_FN),
|
||||
PINMUX_DATA(BREQ_MARK, PC6_FN),
|
||||
PINMUX_DATA(WE3_MARK, PC5_FN),
|
||||
PINMUX_DATA(WE2_MARK, PC4_FN),
|
||||
PINMUX_DATA(CS6_MARK, PC3_FN),
|
||||
PINMUX_DATA(CS5_MARK, PC2_FN),
|
||||
PINMUX_DATA(CS4_MARK, PC1_FN),
|
||||
PINMUX_DATA(CLKOUTENB_MARK, PC0_FN),
|
||||
|
||||
/* PD FN */
|
||||
PINMUX_DATA(DACK3_MARK, PD7_FN),
|
||||
PINMUX_DATA(DACK2_MARK, PD6_FN),
|
||||
PINMUX_DATA(DACK1_MARK, PD5_FN),
|
||||
PINMUX_DATA(DACK0_MARK, PD4_FN),
|
||||
PINMUX_DATA(DREQ3_MARK, PD3_FN),
|
||||
PINMUX_DATA(DREQ2_MARK, PD2_FN),
|
||||
PINMUX_DATA(DREQ1_MARK, PD1_FN),
|
||||
PINMUX_DATA(DREQ0_MARK, PD0_FN),
|
||||
|
||||
/* PE FN */
|
||||
PINMUX_DATA(IRQ3_MARK, PE7_FN),
|
||||
PINMUX_DATA(IRQ2_MARK, PE6_FN),
|
||||
PINMUX_DATA(IRQ1_MARK, PE5_FN),
|
||||
PINMUX_DATA(IRQ0_MARK, PE4_FN),
|
||||
PINMUX_DATA(DRAK3_MARK, PE3_FN),
|
||||
PINMUX_DATA(DRAK2_MARK, PE2_FN),
|
||||
PINMUX_DATA(DRAK1_MARK, PE1_FN),
|
||||
PINMUX_DATA(DRAK0_MARK, PE0_FN),
|
||||
|
||||
/* PF FN */
|
||||
PINMUX_DATA(SCK3_MARK, PF7_FN),
|
||||
PINMUX_DATA(SCK2_MARK, PF6_FN),
|
||||
PINMUX_DATA(SCK1_MARK, PF5_FN),
|
||||
PINMUX_DATA(SCK0_MARK, PF4_FN),
|
||||
PINMUX_DATA(IRL3_MARK, PF3_FN),
|
||||
PINMUX_DATA(IRL2_MARK, PF2_FN),
|
||||
PINMUX_DATA(IRL1_MARK, PF1_FN),
|
||||
PINMUX_DATA(IRL0_MARK, PF0_FN),
|
||||
|
||||
/* PG FN */
|
||||
PINMUX_DATA(TXD3_MARK, PG7_FN),
|
||||
PINMUX_DATA(TXD2_MARK, PG6_FN),
|
||||
PINMUX_DATA(TXD1_MARK, PG5_FN),
|
||||
PINMUX_DATA(TXD0_MARK, PG4_FN),
|
||||
PINMUX_DATA(RXD3_MARK, PG3_FN),
|
||||
PINMUX_DATA(RXD2_MARK, PG2_FN),
|
||||
PINMUX_DATA(RXD1_MARK, PG1_FN),
|
||||
PINMUX_DATA(RXD0_MARK, PG0_FN),
|
||||
|
||||
/* PH FN */
|
||||
PINMUX_DATA(CE2B_MARK, PH5_FN),
|
||||
PINMUX_DATA(CE2A_MARK, PH4_FN),
|
||||
PINMUX_DATA(IOIS16_MARK, PH3_FN),
|
||||
PINMUX_DATA(STATUS1_MARK, PH2_FN),
|
||||
PINMUX_DATA(STATUS0_MARK, PH1_FN),
|
||||
PINMUX_DATA(IRQOUT_MARK, PH0_FN),
|
||||
};
|
||||
|
||||
static const struct sh_pfc_pin pinmux_pins[] = {
|
||||
/* PA */
|
||||
PINMUX_GPIO(PA7),
|
||||
PINMUX_GPIO(PA6),
|
||||
PINMUX_GPIO(PA5),
|
||||
PINMUX_GPIO(PA4),
|
||||
PINMUX_GPIO(PA3),
|
||||
PINMUX_GPIO(PA2),
|
||||
PINMUX_GPIO(PA1),
|
||||
PINMUX_GPIO(PA0),
|
||||
|
||||
/* PB */
|
||||
PINMUX_GPIO(PB7),
|
||||
PINMUX_GPIO(PB6),
|
||||
PINMUX_GPIO(PB5),
|
||||
PINMUX_GPIO(PB4),
|
||||
PINMUX_GPIO(PB3),
|
||||
PINMUX_GPIO(PB2),
|
||||
PINMUX_GPIO(PB1),
|
||||
PINMUX_GPIO(PB0),
|
||||
|
||||
/* PC */
|
||||
PINMUX_GPIO(PC7),
|
||||
PINMUX_GPIO(PC6),
|
||||
PINMUX_GPIO(PC5),
|
||||
PINMUX_GPIO(PC4),
|
||||
PINMUX_GPIO(PC3),
|
||||
PINMUX_GPIO(PC2),
|
||||
PINMUX_GPIO(PC1),
|
||||
PINMUX_GPIO(PC0),
|
||||
|
||||
/* PD */
|
||||
PINMUX_GPIO(PD7),
|
||||
PINMUX_GPIO(PD6),
|
||||
PINMUX_GPIO(PD5),
|
||||
PINMUX_GPIO(PD4),
|
||||
PINMUX_GPIO(PD3),
|
||||
PINMUX_GPIO(PD2),
|
||||
PINMUX_GPIO(PD1),
|
||||
PINMUX_GPIO(PD0),
|
||||
|
||||
/* PE */
|
||||
PINMUX_GPIO(PE7),
|
||||
PINMUX_GPIO(PE6),
|
||||
PINMUX_GPIO(PE5),
|
||||
PINMUX_GPIO(PE4),
|
||||
PINMUX_GPIO(PE3),
|
||||
PINMUX_GPIO(PE2),
|
||||
PINMUX_GPIO(PE1),
|
||||
PINMUX_GPIO(PE0),
|
||||
|
||||
/* PF */
|
||||
PINMUX_GPIO(PF7),
|
||||
PINMUX_GPIO(PF6),
|
||||
PINMUX_GPIO(PF5),
|
||||
PINMUX_GPIO(PF4),
|
||||
PINMUX_GPIO(PF3),
|
||||
PINMUX_GPIO(PF2),
|
||||
PINMUX_GPIO(PF1),
|
||||
PINMUX_GPIO(PF0),
|
||||
|
||||
/* PG */
|
||||
PINMUX_GPIO(PG7),
|
||||
PINMUX_GPIO(PG6),
|
||||
PINMUX_GPIO(PG5),
|
||||
PINMUX_GPIO(PG4),
|
||||
PINMUX_GPIO(PG3),
|
||||
PINMUX_GPIO(PG2),
|
||||
PINMUX_GPIO(PG1),
|
||||
PINMUX_GPIO(PG0),
|
||||
|
||||
/* PH */
|
||||
PINMUX_GPIO(PH5),
|
||||
PINMUX_GPIO(PH4),
|
||||
PINMUX_GPIO(PH3),
|
||||
PINMUX_GPIO(PH2),
|
||||
PINMUX_GPIO(PH1),
|
||||
PINMUX_GPIO(PH0),
|
||||
};
|
||||
|
||||
#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins)
|
||||
|
||||
static const struct pinmux_func pinmux_func_gpios[] = {
|
||||
/* FN */
|
||||
GPIO_FN(D31),
|
||||
GPIO_FN(D30),
|
||||
GPIO_FN(D29),
|
||||
GPIO_FN(D28),
|
||||
GPIO_FN(D27),
|
||||
GPIO_FN(D26),
|
||||
GPIO_FN(D25),
|
||||
GPIO_FN(D24),
|
||||
GPIO_FN(D23),
|
||||
GPIO_FN(D22),
|
||||
GPIO_FN(D21),
|
||||
GPIO_FN(D20),
|
||||
GPIO_FN(D19),
|
||||
GPIO_FN(D18),
|
||||
GPIO_FN(D17),
|
||||
GPIO_FN(D16),
|
||||
GPIO_FN(BACK),
|
||||
GPIO_FN(BREQ),
|
||||
GPIO_FN(WE3),
|
||||
GPIO_FN(WE2),
|
||||
GPIO_FN(CS6),
|
||||
GPIO_FN(CS5),
|
||||
GPIO_FN(CS4),
|
||||
GPIO_FN(CLKOUTENB),
|
||||
GPIO_FN(DACK3),
|
||||
GPIO_FN(DACK2),
|
||||
GPIO_FN(DACK1),
|
||||
GPIO_FN(DACK0),
|
||||
GPIO_FN(DREQ3),
|
||||
GPIO_FN(DREQ2),
|
||||
GPIO_FN(DREQ1),
|
||||
GPIO_FN(DREQ0),
|
||||
GPIO_FN(IRQ3),
|
||||
GPIO_FN(IRQ2),
|
||||
GPIO_FN(IRQ1),
|
||||
GPIO_FN(IRQ0),
|
||||
GPIO_FN(DRAK3),
|
||||
GPIO_FN(DRAK2),
|
||||
GPIO_FN(DRAK1),
|
||||
GPIO_FN(DRAK0),
|
||||
GPIO_FN(SCK3),
|
||||
GPIO_FN(SCK2),
|
||||
GPIO_FN(SCK1),
|
||||
GPIO_FN(SCK0),
|
||||
GPIO_FN(IRL3),
|
||||
GPIO_FN(IRL2),
|
||||
GPIO_FN(IRL1),
|
||||
GPIO_FN(IRL0),
|
||||
GPIO_FN(TXD3),
|
||||
GPIO_FN(TXD2),
|
||||
GPIO_FN(TXD1),
|
||||
GPIO_FN(TXD0),
|
||||
GPIO_FN(RXD3),
|
||||
GPIO_FN(RXD2),
|
||||
GPIO_FN(RXD1),
|
||||
GPIO_FN(RXD0),
|
||||
GPIO_FN(CE2B),
|
||||
GPIO_FN(CE2A),
|
||||
GPIO_FN(IOIS16),
|
||||
GPIO_FN(STATUS1),
|
||||
GPIO_FN(STATUS0),
|
||||
GPIO_FN(IRQOUT),
|
||||
};
|
||||
|
||||
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
|
||||
{ PINMUX_CFG_REG("PABCR", 0xffc70000, 32, 2) {
|
||||
PA7_FN, PA7_OUT, PA7_IN, 0,
|
||||
PA6_FN, PA6_OUT, PA6_IN, 0,
|
||||
PA5_FN, PA5_OUT, PA5_IN, 0,
|
||||
PA4_FN, PA4_OUT, PA4_IN, 0,
|
||||
PA3_FN, PA3_OUT, PA3_IN, 0,
|
||||
PA2_FN, PA2_OUT, PA2_IN, 0,
|
||||
PA1_FN, PA1_OUT, PA1_IN, 0,
|
||||
PA0_FN, PA0_OUT, PA0_IN, 0,
|
||||
PB7_FN, PB7_OUT, PB7_IN, 0,
|
||||
PB6_FN, PB6_OUT, PB6_IN, 0,
|
||||
PB5_FN, PB5_OUT, PB5_IN, 0,
|
||||
PB4_FN, PB4_OUT, PB4_IN, 0,
|
||||
PB3_FN, PB3_OUT, PB3_IN, 0,
|
||||
PB2_FN, PB2_OUT, PB2_IN, 0,
|
||||
PB1_FN, PB1_OUT, PB1_IN, 0,
|
||||
PB0_FN, PB0_OUT, PB0_IN, 0, },
|
||||
},
|
||||
{ PINMUX_CFG_REG("PCDCR", 0xffc70004, 32, 2) {
|
||||
PC7_FN, PC7_OUT, PC7_IN, 0,
|
||||
PC6_FN, PC6_OUT, PC6_IN, 0,
|
||||
PC5_FN, PC5_OUT, PC5_IN, 0,
|
||||
PC4_FN, PC4_OUT, PC4_IN, 0,
|
||||
PC3_FN, PC3_OUT, PC3_IN, 0,
|
||||
PC2_FN, PC2_OUT, PC2_IN, 0,
|
||||
PC1_FN, PC1_OUT, PC1_IN, 0,
|
||||
PC0_FN, PC0_OUT, PC0_IN, 0,
|
||||
PD7_FN, PD7_OUT, PD7_IN, 0,
|
||||
PD6_FN, PD6_OUT, PD6_IN, 0,
|
||||
PD5_FN, PD5_OUT, PD5_IN, 0,
|
||||
PD4_FN, PD4_OUT, PD4_IN, 0,
|
||||
PD3_FN, PD3_OUT, PD3_IN, 0,
|
||||
PD2_FN, PD2_OUT, PD2_IN, 0,
|
||||
PD1_FN, PD1_OUT, PD1_IN, 0,
|
||||
PD0_FN, PD0_OUT, PD0_IN, 0, },
|
||||
},
|
||||
{ PINMUX_CFG_REG("PEFCR", 0xffc70008, 32, 2) {
|
||||
PE7_FN, PE7_OUT, PE7_IN, 0,
|
||||
PE6_FN, PE6_OUT, PE6_IN, 0,
|
||||
PE5_FN, PE5_OUT, PE5_IN, 0,
|
||||
PE4_FN, PE4_OUT, PE4_IN, 0,
|
||||
PE3_FN, PE3_OUT, PE3_IN, 0,
|
||||
PE2_FN, PE2_OUT, PE2_IN, 0,
|
||||
PE1_FN, PE1_OUT, PE1_IN, 0,
|
||||
PE0_FN, PE0_OUT, PE0_IN, 0,
|
||||
PF7_FN, PF7_OUT, PF7_IN, 0,
|
||||
PF6_FN, PF6_OUT, PF6_IN, 0,
|
||||
PF5_FN, PF5_OUT, PF5_IN, 0,
|
||||
PF4_FN, PF4_OUT, PF4_IN, 0,
|
||||
PF3_FN, PF3_OUT, PF3_IN, 0,
|
||||
PF2_FN, PF2_OUT, PF2_IN, 0,
|
||||
PF1_FN, PF1_OUT, PF1_IN, 0,
|
||||
PF0_FN, PF0_OUT, PF0_IN, 0, },
|
||||
},
|
||||
{ PINMUX_CFG_REG("PGHCR", 0xffc7000c, 32, 2) {
|
||||
PG7_FN, PG7_OUT, PG7_IN, 0,
|
||||
PG6_FN, PG6_OUT, PG6_IN, 0,
|
||||
PG5_FN, PG5_OUT, PG5_IN, 0,
|
||||
PG4_FN, PG4_OUT, PG4_IN, 0,
|
||||
PG3_FN, PG3_OUT, PG3_IN, 0,
|
||||
PG2_FN, PG2_OUT, PG2_IN, 0,
|
||||
PG1_FN, PG1_OUT, PG1_IN, 0,
|
||||
PG0_FN, PG0_OUT, PG0_IN, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
PH5_FN, PH5_OUT, PH5_IN, 0,
|
||||
PH4_FN, PH4_OUT, PH4_IN, 0,
|
||||
PH3_FN, PH3_OUT, PH3_IN, 0,
|
||||
PH2_FN, PH2_OUT, PH2_IN, 0,
|
||||
PH1_FN, PH1_OUT, PH1_IN, 0,
|
||||
PH0_FN, PH0_OUT, PH0_IN, 0, },
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct pinmux_data_reg pinmux_data_regs[] = {
|
||||
{ PINMUX_DATA_REG("PABDR", 0xffc70010, 32) {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
|
||||
PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
|
||||
PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA, },
|
||||
},
|
||||
{ PINMUX_DATA_REG("PCDDR", 0xffc70014, 32) {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
|
||||
PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
|
||||
PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA, },
|
||||
},
|
||||
{ PINMUX_DATA_REG("PEFDR", 0xffc70018, 32) {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
|
||||
PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
|
||||
PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA, },
|
||||
},
|
||||
{ PINMUX_DATA_REG("PGHDR", 0xffc7001c, 32) {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
|
||||
PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, PH5_DATA, PH4_DATA,
|
||||
PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA, },
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
const struct sh_pfc_soc_info shx3_pinmux_info = {
|
||||
.name = "shx3_pfc",
|
||||
.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
|
||||
.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
|
||||
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
|
||||
.pins = pinmux_pins,
|
||||
.nr_pins = ARRAY_SIZE(pinmux_pins),
|
||||
.func_gpios = pinmux_func_gpios,
|
||||
.nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios),
|
||||
.gpio_data = pinmux_data,
|
||||
.gpio_data_size = ARRAY_SIZE(pinmux_data),
|
||||
.cfg_regs = pinmux_config_regs,
|
||||
.data_regs = pinmux_data_regs,
|
||||
};
|
642
drivers/pinctrl/sh-pfc/pinctrl.c
Normal file
642
drivers/pinctrl/sh-pfc/pinctrl.c
Normal file
|
@ -0,0 +1,642 @@
|
|||
/*
|
||||
* SuperH Pin Function Controller pinmux support.
|
||||
*
|
||||
* Copyright (C) 2012 Paul Mundt
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define DRV_NAME "sh-pfc"
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "../core.h"
|
||||
#include "../pinconf.h"
|
||||
|
||||
struct sh_pfc_pin_config {
|
||||
u32 type;
|
||||
};
|
||||
|
||||
struct sh_pfc_pinctrl {
|
||||
struct pinctrl_dev *pctl;
|
||||
struct pinctrl_desc pctl_desc;
|
||||
|
||||
struct sh_pfc *pfc;
|
||||
|
||||
struct pinctrl_pin_desc *pins;
|
||||
struct sh_pfc_pin_config *configs;
|
||||
};
|
||||
|
||||
static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pmx->pfc->info->nr_groups;
|
||||
}
|
||||
|
||||
static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pmx->pfc->info->groups[selector].name;
|
||||
}
|
||||
|
||||
static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
const unsigned **pins, unsigned *num_pins)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = pmx->pfc->info->groups[selector].pins;
|
||||
*num_pins = pmx->pfc->info->groups[selector].nr_pins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
unsigned offset)
|
||||
{
|
||||
seq_printf(s, "%s", DRV_NAME);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int sh_pfc_map_add_config(struct pinctrl_map *map,
|
||||
const char *group_or_pin,
|
||||
enum pinctrl_map_type type,
|
||||
unsigned long *configs,
|
||||
unsigned int num_configs)
|
||||
{
|
||||
unsigned long *cfgs;
|
||||
|
||||
cfgs = kmemdup(configs, num_configs * sizeof(*cfgs),
|
||||
GFP_KERNEL);
|
||||
if (cfgs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
map->type = type;
|
||||
map->data.configs.group_or_pin = group_or_pin;
|
||||
map->data.configs.configs = cfgs;
|
||||
map->data.configs.num_configs = num_configs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned int *num_maps, unsigned int *index)
|
||||
{
|
||||
struct pinctrl_map *maps = *map;
|
||||
unsigned int nmaps = *num_maps;
|
||||
unsigned int idx = *index;
|
||||
unsigned int num_configs;
|
||||
const char *function = NULL;
|
||||
unsigned long *configs;
|
||||
struct property *prop;
|
||||
unsigned int num_groups;
|
||||
unsigned int num_pins;
|
||||
const char *group;
|
||||
const char *pin;
|
||||
int ret;
|
||||
|
||||
/* Parse the function and configuration properties. At least a function
|
||||
* or one configuration must be specified.
|
||||
*/
|
||||
ret = of_property_read_string(np, "renesas,function", &function);
|
||||
if (ret < 0 && ret != -EINVAL) {
|
||||
dev_err(dev, "Invalid function in DT\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pinconf_generic_parse_dt_config(np, &configs, &num_configs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!function && num_configs == 0) {
|
||||
dev_err(dev,
|
||||
"DT node must contain at least a function or config\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Count the number of pins and groups and reallocate mappings. */
|
||||
ret = of_property_count_strings(np, "renesas,pins");
|
||||
if (ret == -EINVAL) {
|
||||
num_pins = 0;
|
||||
} else if (ret < 0) {
|
||||
dev_err(dev, "Invalid pins list in DT\n");
|
||||
goto done;
|
||||
} else {
|
||||
num_pins = ret;
|
||||
}
|
||||
|
||||
ret = of_property_count_strings(np, "renesas,groups");
|
||||
if (ret == -EINVAL) {
|
||||
num_groups = 0;
|
||||
} else if (ret < 0) {
|
||||
dev_err(dev, "Invalid pin groups list in DT\n");
|
||||
goto done;
|
||||
} else {
|
||||
num_groups = ret;
|
||||
}
|
||||
|
||||
if (!num_pins && !num_groups) {
|
||||
dev_err(dev, "No pin or group provided in DT node\n");
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (function)
|
||||
nmaps += num_groups;
|
||||
if (configs)
|
||||
nmaps += num_pins + num_groups;
|
||||
|
||||
maps = krealloc(maps, sizeof(*maps) * nmaps, GFP_KERNEL);
|
||||
if (maps == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*map = maps;
|
||||
*num_maps = nmaps;
|
||||
|
||||
/* Iterate over pins and groups and create the mappings. */
|
||||
of_property_for_each_string(np, "renesas,groups", prop, group) {
|
||||
if (function) {
|
||||
maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
maps[idx].data.mux.group = group;
|
||||
maps[idx].data.mux.function = function;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (configs) {
|
||||
ret = sh_pfc_map_add_config(&maps[idx], group,
|
||||
PIN_MAP_TYPE_CONFIGS_GROUP,
|
||||
configs, num_configs);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!configs) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
of_property_for_each_string(np, "renesas,pins", prop, pin) {
|
||||
ret = sh_pfc_map_add_config(&maps[idx], pin,
|
||||
PIN_MAP_TYPE_CONFIGS_PIN,
|
||||
configs, num_configs);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
done:
|
||||
*index = idx;
|
||||
kfree(configs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_pfc_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (map == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_maps; ++i) {
|
||||
if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP ||
|
||||
map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
|
||||
kfree(map[i].data.configs.configs);
|
||||
}
|
||||
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map, unsigned *num_maps)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct device *dev = pmx->pfc->dev;
|
||||
struct device_node *child;
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
*map = NULL;
|
||||
*num_maps = 0;
|
||||
index = 0;
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
ret = sh_pfc_dt_subnode_to_map(dev, child, map, num_maps,
|
||||
&index);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If no mapping has been found in child nodes try the config node. */
|
||||
if (*num_maps == 0) {
|
||||
ret = sh_pfc_dt_subnode_to_map(dev, np, map, num_maps, &index);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*num_maps)
|
||||
return 0;
|
||||
|
||||
dev_err(dev, "no mapping found in node %s\n", np->full_name);
|
||||
ret = -EINVAL;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
sh_pfc_dt_free_map(pctldev, *map, *num_maps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static const struct pinctrl_ops sh_pfc_pinctrl_ops = {
|
||||
.get_groups_count = sh_pfc_get_groups_count,
|
||||
.get_group_name = sh_pfc_get_group_name,
|
||||
.get_group_pins = sh_pfc_get_group_pins,
|
||||
.pin_dbg_show = sh_pfc_pin_dbg_show,
|
||||
#ifdef CONFIG_OF
|
||||
.dt_node_to_map = sh_pfc_dt_node_to_map,
|
||||
.dt_free_map = sh_pfc_dt_free_map,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pmx->pfc->info->nr_functions;
|
||||
}
|
||||
|
||||
static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pmx->pfc->info->functions[selector].name;
|
||||
}
|
||||
|
||||
static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev,
|
||||
unsigned selector,
|
||||
const char * const **groups,
|
||||
unsigned * const num_groups)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = pmx->pfc->info->functions[selector].groups;
|
||||
*num_groups = pmx->pfc->info->functions[selector].nr_groups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
|
||||
for (i = 0; i < grp->nr_pins; ++i) {
|
||||
int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
|
||||
|
||||
if (cfg->type != PINMUX_TYPE_NONE) {
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < grp->nr_pins; ++i) {
|
||||
ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
int idx = sh_pfc_get_pin_index(pfc, offset);
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
|
||||
if (cfg->type != PINMUX_TYPE_NONE) {
|
||||
dev_err(pfc->dev,
|
||||
"Pin %u is busy, can't configure it as GPIO.\n",
|
||||
offset);
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!pfc->gpio) {
|
||||
/* If GPIOs are handled externally the pin mux type need to be
|
||||
* set to GPIO here.
|
||||
*/
|
||||
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
|
||||
|
||||
ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
cfg->type = PINMUX_TYPE_GPIO;
|
||||
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
int idx = sh_pfc_get_pin_index(pfc, offset);
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
cfg->type = PINMUX_TYPE_NONE;
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
}
|
||||
|
||||
static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset, bool input)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT;
|
||||
int idx = sh_pfc_get_pin_index(pfc, offset);
|
||||
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
|
||||
unsigned long flags;
|
||||
unsigned int dir;
|
||||
int ret;
|
||||
|
||||
/* Check if the requested direction is supported by the pin. Not all SoC
|
||||
* provide pin config data, so perform the check conditionally.
|
||||
*/
|
||||
if (pin->configs) {
|
||||
dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT;
|
||||
if (!(pin->configs & dir))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
|
||||
ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
cfg->type = new_type;
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops sh_pfc_pinmux_ops = {
|
||||
.get_functions_count = sh_pfc_get_functions_count,
|
||||
.get_function_name = sh_pfc_get_function_name,
|
||||
.get_function_groups = sh_pfc_get_function_groups,
|
||||
.set_mux = sh_pfc_func_set_mux,
|
||||
.gpio_request_enable = sh_pfc_gpio_request_enable,
|
||||
.gpio_disable_free = sh_pfc_gpio_disable_free,
|
||||
.gpio_set_direction = sh_pfc_gpio_set_direction,
|
||||
};
|
||||
|
||||
/* Check whether the requested parameter is supported for a pin. */
|
||||
static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin,
|
||||
enum pin_config_param param)
|
||||
{
|
||||
int idx = sh_pfc_get_pin_index(pfc, _pin);
|
||||
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
return true;
|
||||
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
return pin->configs & SH_PFC_PIN_CFG_PULL_UP;
|
||||
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
|
||||
unsigned long *config)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||
unsigned long flags;
|
||||
unsigned int bias;
|
||||
|
||||
if (!sh_pfc_pinconf_validate(pfc, _pin, param))
|
||||
return -ENOTSUPP;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (!pfc->info->ops || !pfc->info->ops->get_bias)
|
||||
return -ENOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
bias = pfc->info->ops->get_bias(pfc, _pin);
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
|
||||
if (bias != param)
|
||||
return -EINVAL;
|
||||
|
||||
*config = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
|
||||
unsigned long *configs, unsigned num_configs)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct sh_pfc *pfc = pmx->pfc;
|
||||
enum pin_config_param param;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
param = pinconf_to_config_param(configs[i]);
|
||||
|
||||
if (!sh_pfc_pinconf_validate(pfc, _pin, param))
|
||||
return -ENOTSUPP;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
if (!pfc->info->ops || !pfc->info->ops->set_bias)
|
||||
return -ENOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&pfc->lock, flags);
|
||||
pfc->info->ops->set_bias(pfc, _pin, param);
|
||||
spin_unlock_irqrestore(&pfc->lock, flags);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
} /* for each config */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
|
||||
unsigned long *configs,
|
||||
unsigned num_configs)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
const unsigned int *pins;
|
||||
unsigned int num_pins;
|
||||
unsigned int i;
|
||||
|
||||
pins = pmx->pfc->info->groups[group].pins;
|
||||
num_pins = pmx->pfc->info->groups[group].nr_pins;
|
||||
|
||||
for (i = 0; i < num_pins; ++i)
|
||||
sh_pfc_pinconf_set(pctldev, pins[i], configs, num_configs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinconf_ops sh_pfc_pinconf_ops = {
|
||||
.is_generic = true,
|
||||
.pin_config_get = sh_pfc_pinconf_get,
|
||||
.pin_config_set = sh_pfc_pinconf_set,
|
||||
.pin_config_group_set = sh_pfc_pinconf_group_set,
|
||||
.pin_config_config_dbg_show = pinconf_generic_dump_config,
|
||||
};
|
||||
|
||||
/* PFC ranges -> pinctrl pin descs */
|
||||
static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Allocate and initialize the pins and configs arrays. */
|
||||
pmx->pins = devm_kzalloc(pfc->dev,
|
||||
sizeof(*pmx->pins) * pfc->info->nr_pins,
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!pmx->pins))
|
||||
return -ENOMEM;
|
||||
|
||||
pmx->configs = devm_kzalloc(pfc->dev,
|
||||
sizeof(*pmx->configs) * pfc->info->nr_pins,
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!pmx->configs))
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < pfc->info->nr_pins; ++i) {
|
||||
const struct sh_pfc_pin *info = &pfc->info->pins[i];
|
||||
struct sh_pfc_pin_config *cfg = &pmx->configs[i];
|
||||
struct pinctrl_pin_desc *pin = &pmx->pins[i];
|
||||
|
||||
/* If the pin number is equal to -1 all pins are considered */
|
||||
pin->number = info->pin != (u16)-1 ? info->pin : i;
|
||||
pin->name = info->name;
|
||||
cfg->type = PINMUX_TYPE_NONE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx;
|
||||
int ret;
|
||||
|
||||
pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);
|
||||
if (unlikely(!pmx))
|
||||
return -ENOMEM;
|
||||
|
||||
pmx->pfc = pfc;
|
||||
pfc->pinctrl = pmx;
|
||||
|
||||
ret = sh_pfc_map_pins(pfc, pmx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pmx->pctl_desc.name = DRV_NAME;
|
||||
pmx->pctl_desc.owner = THIS_MODULE;
|
||||
pmx->pctl_desc.pctlops = &sh_pfc_pinctrl_ops;
|
||||
pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops;
|
||||
pmx->pctl_desc.confops = &sh_pfc_pinconf_ops;
|
||||
pmx->pctl_desc.pins = pmx->pins;
|
||||
pmx->pctl_desc.npins = pfc->info->nr_pins;
|
||||
|
||||
pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx);
|
||||
if (pmx->pctl == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc)
|
||||
{
|
||||
struct sh_pfc_pinctrl *pmx = pfc->pinctrl;
|
||||
|
||||
pinctrl_unregister(pmx->pctl);
|
||||
|
||||
pfc->pinctrl = NULL;
|
||||
return 0;
|
||||
}
|
319
drivers/pinctrl/sh-pfc/sh_pfc.h
Normal file
319
drivers/pinctrl/sh-pfc/sh_pfc.h
Normal file
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* SuperH Pin Function Controller Support
|
||||
*
|
||||
* Copyright (c) 2008 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef __SH_PFC_H
|
||||
#define __SH_PFC_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
enum {
|
||||
PINMUX_TYPE_NONE,
|
||||
PINMUX_TYPE_FUNCTION,
|
||||
PINMUX_TYPE_GPIO,
|
||||
PINMUX_TYPE_OUTPUT,
|
||||
PINMUX_TYPE_INPUT,
|
||||
};
|
||||
|
||||
#define SH_PFC_PIN_CFG_INPUT (1 << 0)
|
||||
#define SH_PFC_PIN_CFG_OUTPUT (1 << 1)
|
||||
#define SH_PFC_PIN_CFG_PULL_UP (1 << 2)
|
||||
#define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3)
|
||||
#define SH_PFC_PIN_CFG_NO_GPIO (1 << 31)
|
||||
|
||||
struct sh_pfc_pin {
|
||||
u16 pin;
|
||||
u16 enum_id;
|
||||
const char *name;
|
||||
unsigned int configs;
|
||||
};
|
||||
|
||||
#define SH_PFC_PIN_GROUP(n) \
|
||||
{ \
|
||||
.name = #n, \
|
||||
.pins = n##_pins, \
|
||||
.mux = n##_mux, \
|
||||
.nr_pins = ARRAY_SIZE(n##_pins), \
|
||||
}
|
||||
|
||||
struct sh_pfc_pin_group {
|
||||
const char *name;
|
||||
const unsigned int *pins;
|
||||
const unsigned int *mux;
|
||||
unsigned int nr_pins;
|
||||
};
|
||||
|
||||
#define SH_PFC_FUNCTION(n) \
|
||||
{ \
|
||||
.name = #n, \
|
||||
.groups = n##_groups, \
|
||||
.nr_groups = ARRAY_SIZE(n##_groups), \
|
||||
}
|
||||
|
||||
struct sh_pfc_function {
|
||||
const char *name;
|
||||
const char * const *groups;
|
||||
unsigned int nr_groups;
|
||||
};
|
||||
|
||||
struct pinmux_func {
|
||||
u16 enum_id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct pinmux_cfg_reg {
|
||||
unsigned long reg, reg_width, field_width;
|
||||
const u16 *enum_ids;
|
||||
const unsigned long *var_field_width;
|
||||
};
|
||||
|
||||
#define PINMUX_CFG_REG(name, r, r_width, f_width) \
|
||||
.reg = r, .reg_width = r_width, .field_width = f_width, \
|
||||
.enum_ids = (const u16 [(r_width / f_width) * (1 << f_width)])
|
||||
|
||||
#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
|
||||
.reg = r, .reg_width = r_width, \
|
||||
.var_field_width = (const unsigned long [r_width]) \
|
||||
{ var_fw0, var_fwn, 0 }, \
|
||||
.enum_ids = (const u16 [])
|
||||
|
||||
struct pinmux_data_reg {
|
||||
unsigned long reg, reg_width;
|
||||
const u16 *enum_ids;
|
||||
};
|
||||
|
||||
#define PINMUX_DATA_REG(name, r, r_width) \
|
||||
.reg = r, .reg_width = r_width, \
|
||||
.enum_ids = (const u16 [r_width]) \
|
||||
|
||||
struct pinmux_irq {
|
||||
int irq;
|
||||
const short *gpios;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_MULTIPLATFORM
|
||||
#define PINMUX_IRQ(irq_nr, ids...) \
|
||||
{ .gpios = (const short []) { ids, -1 } }
|
||||
#else
|
||||
#define PINMUX_IRQ(irq_nr, ids...) \
|
||||
{ .irq = irq_nr, .gpios = (const short []) { ids, -1 } }
|
||||
#endif
|
||||
|
||||
struct pinmux_range {
|
||||
u16 begin;
|
||||
u16 end;
|
||||
u16 force;
|
||||
};
|
||||
|
||||
struct sh_pfc;
|
||||
|
||||
struct sh_pfc_soc_operations {
|
||||
int (*init)(struct sh_pfc *pfc);
|
||||
unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
|
||||
void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
|
||||
unsigned int bias);
|
||||
};
|
||||
|
||||
struct sh_pfc_soc_info {
|
||||
const char *name;
|
||||
const struct sh_pfc_soc_operations *ops;
|
||||
|
||||
struct pinmux_range input;
|
||||
struct pinmux_range output;
|
||||
struct pinmux_range function;
|
||||
|
||||
const struct sh_pfc_pin *pins;
|
||||
unsigned int nr_pins;
|
||||
const struct sh_pfc_pin_group *groups;
|
||||
unsigned int nr_groups;
|
||||
const struct sh_pfc_function *functions;
|
||||
unsigned int nr_functions;
|
||||
|
||||
const struct pinmux_func *func_gpios;
|
||||
unsigned int nr_func_gpios;
|
||||
|
||||
const struct pinmux_cfg_reg *cfg_regs;
|
||||
const struct pinmux_data_reg *data_regs;
|
||||
|
||||
const u16 *gpio_data;
|
||||
unsigned int gpio_data_size;
|
||||
|
||||
const struct pinmux_irq *gpio_irq;
|
||||
unsigned int gpio_irq_size;
|
||||
|
||||
unsigned long unlock_reg;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Helper macros to create pin and port lists
|
||||
*/
|
||||
|
||||
/*
|
||||
* sh_pfc_soc_info gpio_data array macros
|
||||
*/
|
||||
|
||||
#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
|
||||
|
||||
#define PINMUX_IPSR_NOGP(ispr, fn) \
|
||||
PINMUX_DATA(fn##_MARK, FN_##fn)
|
||||
#define PINMUX_IPSR_DATA(ipsr, fn) \
|
||||
PINMUX_DATA(fn##_MARK, FN_##fn, FN_##ipsr)
|
||||
#define PINMUX_IPSR_NOGM(ispr, fn, ms) \
|
||||
PINMUX_DATA(fn##_MARK, FN_##fn, FN_##ms)
|
||||
#define PINMUX_IPSR_MSEL(ipsr, fn, ms) \
|
||||
PINMUX_DATA(fn##_MARK, FN_##fn, FN_##ipsr, FN_##ms)
|
||||
#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) \
|
||||
PINMUX_DATA(fn##_MARK, FN_##ms, FN_##ipsr, FN_##fn)
|
||||
|
||||
/*
|
||||
* GP port style (32 ports banks)
|
||||
*/
|
||||
|
||||
#define PORT_GP_1(bank, pin, fn, sfx) fn(bank, pin, GP_##bank##_##pin, sfx)
|
||||
|
||||
#define PORT_GP_32(bank, fn, sfx) \
|
||||
PORT_GP_1(bank, 0, fn, sfx), PORT_GP_1(bank, 1, fn, sfx), \
|
||||
PORT_GP_1(bank, 2, fn, sfx), PORT_GP_1(bank, 3, fn, sfx), \
|
||||
PORT_GP_1(bank, 4, fn, sfx), PORT_GP_1(bank, 5, fn, sfx), \
|
||||
PORT_GP_1(bank, 6, fn, sfx), PORT_GP_1(bank, 7, fn, sfx), \
|
||||
PORT_GP_1(bank, 8, fn, sfx), PORT_GP_1(bank, 9, fn, sfx), \
|
||||
PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx), \
|
||||
PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx), \
|
||||
PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx), \
|
||||
PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx), \
|
||||
PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx), \
|
||||
PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx), \
|
||||
PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx), \
|
||||
PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx), \
|
||||
PORT_GP_1(bank, 26, fn, sfx), PORT_GP_1(bank, 27, fn, sfx), \
|
||||
PORT_GP_1(bank, 28, fn, sfx), PORT_GP_1(bank, 29, fn, sfx), \
|
||||
PORT_GP_1(bank, 30, fn, sfx), PORT_GP_1(bank, 31, fn, sfx)
|
||||
|
||||
#define PORT_GP_32_REV(bank, fn, sfx) \
|
||||
PORT_GP_1(bank, 31, fn, sfx), PORT_GP_1(bank, 30, fn, sfx), \
|
||||
PORT_GP_1(bank, 29, fn, sfx), PORT_GP_1(bank, 28, fn, sfx), \
|
||||
PORT_GP_1(bank, 27, fn, sfx), PORT_GP_1(bank, 26, fn, sfx), \
|
||||
PORT_GP_1(bank, 25, fn, sfx), PORT_GP_1(bank, 24, fn, sfx), \
|
||||
PORT_GP_1(bank, 23, fn, sfx), PORT_GP_1(bank, 22, fn, sfx), \
|
||||
PORT_GP_1(bank, 21, fn, sfx), PORT_GP_1(bank, 20, fn, sfx), \
|
||||
PORT_GP_1(bank, 19, fn, sfx), PORT_GP_1(bank, 18, fn, sfx), \
|
||||
PORT_GP_1(bank, 17, fn, sfx), PORT_GP_1(bank, 16, fn, sfx), \
|
||||
PORT_GP_1(bank, 15, fn, sfx), PORT_GP_1(bank, 14, fn, sfx), \
|
||||
PORT_GP_1(bank, 13, fn, sfx), PORT_GP_1(bank, 12, fn, sfx), \
|
||||
PORT_GP_1(bank, 11, fn, sfx), PORT_GP_1(bank, 10, fn, sfx), \
|
||||
PORT_GP_1(bank, 9, fn, sfx), PORT_GP_1(bank, 8, fn, sfx), \
|
||||
PORT_GP_1(bank, 7, fn, sfx), PORT_GP_1(bank, 6, fn, sfx), \
|
||||
PORT_GP_1(bank, 5, fn, sfx), PORT_GP_1(bank, 4, fn, sfx), \
|
||||
PORT_GP_1(bank, 3, fn, sfx), PORT_GP_1(bank, 2, fn, sfx), \
|
||||
PORT_GP_1(bank, 1, fn, sfx), PORT_GP_1(bank, 0, fn, sfx)
|
||||
|
||||
/* GP_ALL(suffix) - Expand to a list of GP_#_#_suffix */
|
||||
#define _GP_ALL(bank, pin, name, sfx) name##_##sfx
|
||||
#define GP_ALL(str) CPU_ALL_PORT(_GP_ALL, str)
|
||||
|
||||
/* PINMUX_GPIO_GP_ALL - Expand to a list of sh_pfc_pin entries */
|
||||
#define _GP_GPIO(bank, _pin, _name, sfx) \
|
||||
[(bank * 32) + _pin] = { \
|
||||
.pin = (bank * 32) + _pin, \
|
||||
.name = __stringify(_name), \
|
||||
.enum_id = _name##_DATA, \
|
||||
}
|
||||
#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, unused)
|
||||
|
||||
/* PINMUX_DATA_GP_ALL - Expand to a list of name_DATA, name_FN marks */
|
||||
#define _GP_DATA(bank, pin, name, sfx) PINMUX_DATA(name##_DATA, name##_FN)
|
||||
#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, unused)
|
||||
|
||||
/*
|
||||
* PORT style (linear pin space)
|
||||
*/
|
||||
|
||||
#define PORT_1(pn, fn, pfx, sfx) fn(pn, pfx, sfx)
|
||||
|
||||
#define PORT_10(pn, fn, pfx, sfx) \
|
||||
PORT_1(pn, fn, pfx##0, sfx), PORT_1(pn+1, fn, pfx##1, sfx), \
|
||||
PORT_1(pn+2, fn, pfx##2, sfx), PORT_1(pn+3, fn, pfx##3, sfx), \
|
||||
PORT_1(pn+4, fn, pfx##4, sfx), PORT_1(pn+5, fn, pfx##5, sfx), \
|
||||
PORT_1(pn+6, fn, pfx##6, sfx), PORT_1(pn+7, fn, pfx##7, sfx), \
|
||||
PORT_1(pn+8, fn, pfx##8, sfx), PORT_1(pn+9, fn, pfx##9, sfx)
|
||||
|
||||
#define PORT_90(pn, fn, pfx, sfx) \
|
||||
PORT_10(pn+10, fn, pfx##1, sfx), PORT_10(pn+20, fn, pfx##2, sfx), \
|
||||
PORT_10(pn+30, fn, pfx##3, sfx), PORT_10(pn+40, fn, pfx##4, sfx), \
|
||||
PORT_10(pn+50, fn, pfx##5, sfx), PORT_10(pn+60, fn, pfx##6, sfx), \
|
||||
PORT_10(pn+70, fn, pfx##7, sfx), PORT_10(pn+80, fn, pfx##8, sfx), \
|
||||
PORT_10(pn+90, fn, pfx##9, sfx)
|
||||
|
||||
/* PORT_ALL(suffix) - Expand to a list of PORT_#_suffix */
|
||||
#define _PORT_ALL(pn, pfx, sfx) pfx##_##sfx
|
||||
#define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str)
|
||||
|
||||
/* PINMUX_GPIO - Expand to a sh_pfc_pin entry */
|
||||
#define PINMUX_GPIO(_pin) \
|
||||
[GPIO_##_pin] = { \
|
||||
.pin = (u16)-1, \
|
||||
.name = __stringify(GPIO_##_pin), \
|
||||
.enum_id = _pin##_DATA, \
|
||||
}
|
||||
|
||||
/* SH_PFC_PIN_CFG - Expand to a sh_pfc_pin entry (named PORT#) with config */
|
||||
#define SH_PFC_PIN_CFG(_pin, cfgs) \
|
||||
{ \
|
||||
.pin = _pin, \
|
||||
.name = __stringify(PORT##_pin), \
|
||||
.enum_id = PORT##_pin##_DATA, \
|
||||
.configs = cfgs, \
|
||||
}
|
||||
|
||||
/* SH_PFC_PIN_NAMED - Expand to a sh_pfc_pin entry with the given name */
|
||||
#define SH_PFC_PIN_NAMED(row, col, _name) \
|
||||
{ \
|
||||
.pin = PIN_NUMBER(row, col), \
|
||||
.name = __stringify(PIN_##_name), \
|
||||
.configs = SH_PFC_PIN_CFG_NO_GPIO, \
|
||||
}
|
||||
|
||||
/* PINMUX_DATA_ALL - Expand to a list of PORT_name_DATA, PORT_name_FN0,
|
||||
* PORT_name_OUT, PORT_name_IN marks
|
||||
*/
|
||||
#define _PORT_DATA(pn, pfx, sfx) \
|
||||
PINMUX_DATA(PORT##pfx##_DATA, PORT##pfx##_FN0, \
|
||||
PORT##pfx##_OUT, PORT##pfx##_IN)
|
||||
#define PINMUX_DATA_ALL() CPU_ALL_PORT(_PORT_DATA, , unused)
|
||||
|
||||
/* GPIO_FN(name) - Expand to a sh_pfc_pin entry for a function GPIO */
|
||||
#define PINMUX_GPIO_FN(gpio, base, data_or_mark) \
|
||||
[gpio - (base)] = { \
|
||||
.name = __stringify(gpio), \
|
||||
.enum_id = data_or_mark, \
|
||||
}
|
||||
#define GPIO_FN(str) \
|
||||
PINMUX_GPIO_FN(GPIO_FN_##str, PINMUX_FN_BASE, str##_MARK)
|
||||
|
||||
/*
|
||||
* PORTnCR macro
|
||||
*/
|
||||
#define _PCRH(in, in_pd, in_pu, out) \
|
||||
0, (out), (in), 0, \
|
||||
0, 0, 0, 0, \
|
||||
0, 0, (in_pd), 0, \
|
||||
0, 0, (in_pu), 0
|
||||
|
||||
#define PORTCR(nr, reg) \
|
||||
{ \
|
||||
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
|
||||
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
|
||||
PORT##nr##_FN0, PORT##nr##_FN1, \
|
||||
PORT##nr##_FN2, PORT##nr##_FN3, \
|
||||
PORT##nr##_FN4, PORT##nr##_FN5, \
|
||||
PORT##nr##_FN6, PORT##nr##_FN7 } \
|
||||
}
|
||||
|
||||
#endif /* __SH_PFC_H */
|
Loading…
Add table
Add a link
Reference in a new issue