sunxi: pinctrl: Create the driver skeleton

Create a do-nothing driver for each sunxi pin controller variant.

Since only one driver can automatically bind to a DT node, since the
GPIO driver already requires a manual binding process, and since the
pinctrl driver needs access to some of the same information, refactor
the GPIO driver to be bound by the pinctrl driver. This commit should
cause no functional change.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Samuel Holland 2021-08-12 20:09:43 -05:00 committed by Andre Przywara
parent e4b6ebd3de
commit b799eabc7e
9 changed files with 501 additions and 129 deletions

View File

@ -520,6 +520,7 @@ F: arch/arm/mach-sunxi/
F: board/sunxi/
F: drivers/clk/sunxi/
F: drivers/phy/allwinner/
F: drivers/pinctrl/sunxi/
F: drivers/video/sunxi/
ARM TEGRA

View File

@ -1072,6 +1072,7 @@ config ARCH_SUNXI
select OF_BOARD_SETUP
select OF_CONTROL
select OF_SEPARATE
select PINCTRL
select SPECIFY_CONSOLE_INDEX
select SPL_SEPARATE_BSS if SPL
select SPL_STACK_R if SPL

View File

@ -224,6 +224,11 @@ enum sunxi_gpio_number {
#define SUNXI_GPIO_AXP0_VBUS_ENABLE 5
#define SUNXI_GPIO_AXP0_GPIO_COUNT 6
struct sunxi_gpio_plat {
struct sunxi_gpio *regs;
char bank_name[3];
};
void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);

View File

@ -16,15 +16,8 @@
#include <malloc.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm/device-internal.h>
#include <dt-bindings/gpio/gpio.h>
struct sunxi_gpio_plat {
struct sunxi_gpio *regs;
const char *bank_name; /* Name of bank, e.g. "B" */
int gpio_count;
};
#if !CONFIG_IS_ENABLED(DM_GPIO)
static int sunxi_gpio_output(u32 pin, u32 val)
{
@ -211,28 +204,6 @@ static const struct dm_gpio_ops gpio_sunxi_ops = {
.set_flags = sunxi_gpio_set_flags,
};
/**
* Returns the name of a GPIO bank
*
* GPIO banks are named A, B, C, ...
*
* @bank: Bank number (0, 1..n-1)
* Return: allocated string containing the name
*/
static char *gpio_bank_name(int bank)
{
char *name;
name = malloc(3);
if (name) {
name[0] = 'P';
name[1] = 'A' + bank;
name[2] = '\0';
}
return name;
}
static int gpio_sunxi_probe(struct udevice *dev)
{
struct sunxi_gpio_plat *plat = dev_get_plat(dev);
@ -240,114 +211,17 @@ static int gpio_sunxi_probe(struct udevice *dev)
/* Tell the uclass how many GPIOs we have */
if (plat) {
uc_priv->gpio_count = plat->gpio_count;
uc_priv->gpio_count = SUNXI_GPIOS_PER_BANK;
uc_priv->bank_name = plat->bank_name;
}
return 0;
}
struct sunxi_gpio_soc_data {
int start;
int no_banks;
};
/**
* We have a top-level GPIO device with no actual GPIOs. It has a child
* device for each Sunxi bank.
*/
static int gpio_sunxi_bind(struct udevice *parent)
{
struct sunxi_gpio_soc_data *soc_data =
(struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
struct sunxi_gpio_plat *plat = dev_get_plat(parent);
struct sunxi_gpio_reg *ctlr;
int bank, ret;
/* If this is a child device, there is nothing to do here */
if (plat)
return 0;
ctlr = dev_read_addr_ptr(parent);
for (bank = 0; bank < soc_data->no_banks; bank++) {
struct sunxi_gpio_plat *plat;
struct udevice *dev;
plat = calloc(1, sizeof(*plat));
if (!plat)
return -ENOMEM;
plat->regs = &ctlr->gpio_bank[bank];
plat->bank_name = gpio_bank_name(soc_data->start + bank);
plat->gpio_count = SUNXI_GPIOS_PER_BANK;
ret = device_bind(parent, parent->driver, plat->bank_name, plat,
dev_ofnode(parent), &dev);
if (ret)
return ret;
}
return 0;
}
static const struct sunxi_gpio_soc_data soc_data_a_all = {
.start = 0,
.no_banks = SUNXI_GPIO_BANKS,
};
static const struct sunxi_gpio_soc_data soc_data_l_1 = {
.start = 'L' - 'A',
.no_banks = 1,
};
static const struct sunxi_gpio_soc_data soc_data_l_2 = {
.start = 'L' - 'A',
.no_banks = 2,
};
static const struct sunxi_gpio_soc_data soc_data_l_3 = {
.start = 'L' - 'A',
.no_banks = 3,
};
#define ID(_compat_, _soc_data_) \
{ .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
static const struct udevice_id sunxi_gpio_ids[] = {
ID("allwinner,sun4i-a10-pinctrl", a_all),
ID("allwinner,sun5i-a10s-pinctrl", a_all),
ID("allwinner,sun5i-a13-pinctrl", a_all),
ID("allwinner,sun50i-h5-pinctrl", a_all),
ID("allwinner,sun6i-a31-pinctrl", a_all),
ID("allwinner,sun6i-a31s-pinctrl", a_all),
ID("allwinner,sun7i-a20-pinctrl", a_all),
ID("allwinner,sun8i-a23-pinctrl", a_all),
ID("allwinner,sun8i-a33-pinctrl", a_all),
ID("allwinner,sun8i-a83t-pinctrl", a_all),
ID("allwinner,sun8i-h3-pinctrl", a_all),
ID("allwinner,sun8i-r40-pinctrl", a_all),
ID("allwinner,sun8i-v3-pinctrl", a_all),
ID("allwinner,sun8i-v3s-pinctrl", a_all),
ID("allwinner,sun9i-a80-pinctrl", a_all),
ID("allwinner,sun50i-a64-pinctrl", a_all),
ID("allwinner,sun50i-h6-pinctrl", a_all),
ID("allwinner,sun50i-h616-pinctrl", a_all),
ID("allwinner,sun6i-a31-r-pinctrl", l_2),
ID("allwinner,sun8i-a23-r-pinctrl", l_1),
ID("allwinner,sun8i-a83t-r-pinctrl", l_1),
ID("allwinner,sun8i-h3-r-pinctrl", l_1),
ID("allwinner,sun9i-a80-r-pinctrl", l_3),
ID("allwinner,sun50i-a64-r-pinctrl", l_1),
ID("allwinner,sun50i-h6-r-pinctrl", l_2),
ID("allwinner,sun50i-h616-r-pinctrl", l_1),
{ }
};
U_BOOT_DRIVER(gpio_sunxi) = {
.name = "gpio_sunxi",
.id = UCLASS_GPIO,
.ops = &gpio_sunxi_ops,
.of_match = sunxi_gpio_ids,
.bind = gpio_sunxi_bind,
.probe = gpio_sunxi_probe,
.ops = &gpio_sunxi_ops,
};
#endif /* DM_GPIO */

View File

@ -332,6 +332,7 @@ source "drivers/pinctrl/nexell/Kconfig"
source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/renesas/Kconfig"
source "drivers/pinctrl/rockchip/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
endmenu

View File

@ -14,7 +14,7 @@ obj-$(CONFIG_PINCTRL_INTEL) += intel/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_RMOBILE) += renesas/
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/

View File

@ -0,0 +1,125 @@
# SPDX-License-Identifier: GPL-2.0
if ARCH_SUNXI
config PINCTRL_SUNXI
select PINCTRL_FULL
select PINCTRL_GENERIC
bool
config PINCTRL_SUNIV_F1C100S
bool "Support for the Allwinner F1C100s PIO"
default MACH_SUNIV
select PINCTRL_SUNXI
config PINCTRL_SUN4I_A10
bool "Support for the Allwinner A10 PIO"
default MACH_SUN4I
select PINCTRL_SUNXI
config PINCTRL_SUN5I_A13
bool "Support for the Allwinner A10s/A13 PIO"
default MACH_SUN5I
select PINCTRL_SUNXI
config PINCTRL_SUN6I_A31
bool "Support for the Allwinner A31 PIO"
default MACH_SUN6I
select PINCTRL_SUNXI
config PINCTRL_SUN6I_A31_R
bool "Support for the Allwinner A31 R-PIO"
default MACH_SUN6I
select PINCTRL_SUNXI
config PINCTRL_SUN7I_A20
bool "Support for the Allwinner A20/R40 PIO"
default MACH_SUN7I || MACH_SUN8I_R40
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A23
bool "Support for the Allwinner A23 PIO"
default MACH_SUN8I_A23
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A23_R
bool "Support for the Allwinner A23/A33 R-PIO"
default MACH_SUN8I_A23 || MACH_SUN8I_A33
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A33
bool "Support for the Allwinner A33 PIO"
default MACH_SUN8I_A33
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A83T
bool "Support for the Allwinner A83T PIO"
default MACH_SUN8I_A83T
select PINCTRL_SUNXI
config PINCTRL_SUN8I_A83T_R
bool "Support for the Allwinner A83T R-PIO"
default MACH_SUN8I_A83T
select PINCTRL_SUNXI
config PINCTRL_SUN8I_H3
bool "Support for the Allwinner H3 PIO"
default MACH_SUN8I_H3
select PINCTRL_SUNXI
config PINCTRL_SUN8I_H3_R
bool "Support for the Allwinner H3/H5 R-PIO"
default MACH_SUN8I_H3 || MACH_SUN50I_H5
select PINCTRL_SUNXI
config PINCTRL_SUN8I_V3S
bool "Support for the Allwinner V3s PIO"
default MACH_SUN8I_V3S
select PINCTRL_SUNXI
config PINCTRL_SUN9I_A80
bool "Support for the Allwinner A80 PIO"
default MACH_SUN9I
select PINCTRL_SUNXI
config PINCTRL_SUN9I_A80_R
bool "Support for the Allwinner A80 R-PIO"
default MACH_SUN9I
select PINCTRL_SUNXI
config PINCTRL_SUN50I_A64
bool "Support for the Allwinner A64 PIO"
default MACH_SUN50I
select PINCTRL_SUNXI
config PINCTRL_SUN50I_A64_R
bool "Support for the Allwinner A64 R-PIO"
default MACH_SUN50I
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H5
bool "Support for the Allwinner H5 PIO"
default MACH_SUN50I_H5
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H6
bool "Support for the Allwinner H6 PIO"
default MACH_SUN50I_H6
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H6_R
bool "Support for the Allwinner H6 R-PIO"
default MACH_SUN50I_H6
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H616
bool "Support for the Allwinner H616 PIO"
default MACH_SUN50I_H616
select PINCTRL_SUNXI
config PINCTRL_SUN50I_H616_R
bool "Support for the Allwinner H616 R-PIO"
default MACH_SUN50I_H616
select PINCTRL_SUNXI
endif

View File

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += pinctrl-sunxi.o

View File

@ -0,0 +1,362 @@
// SPDX-License-Identifier: GPL-2.0
#include <clk.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/pinctrl.h>
#include <errno.h>
#include <malloc.h>
#include <asm/gpio.h>
extern U_BOOT_DRIVER(gpio_sunxi);
struct sunxi_pinctrl_desc {
u8 first_bank;
u8 num_banks;
};
struct sunxi_pinctrl_plat {
struct sunxi_gpio __iomem *base;
};
static const struct pinctrl_ops sunxi_pinctrl_ops = {
.set_state = pinctrl_generic_set_state,
};
static int sunxi_pinctrl_bind(struct udevice *dev)
{
struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
struct sunxi_pinctrl_desc *desc;
struct sunxi_gpio_plat *gpio_plat;
struct udevice *gpio_dev;
int i, ret;
desc = (void *)dev_get_driver_data(dev);
if (!desc)
return -EINVAL;
dev_set_priv(dev, desc);
plat->base = dev_read_addr_ptr(dev);
ret = device_bind_driver_to_node(dev, "gpio_sunxi", dev->name,
dev_ofnode(dev), &gpio_dev);
if (ret)
return ret;
for (i = 0; i < desc->num_banks; ++i) {
gpio_plat = malloc(sizeof(*gpio_plat));
if (!gpio_plat)
return -ENOMEM;
gpio_plat->regs = plat->base + i;
gpio_plat->bank_name[0] = 'P';
gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
gpio_plat->bank_name[2] = '\0';
ret = device_bind(gpio_dev, DM_DRIVER_REF(gpio_sunxi),
gpio_plat->bank_name, gpio_plat,
ofnode_null(), NULL);
if (ret)
return ret;
}
return 0;
}
static int sunxi_pinctrl_probe(struct udevice *dev)
{
struct clk *apb_clk;
apb_clk = devm_clk_get(dev, "apb");
if (!IS_ERR(apb_clk))
clk_enable(apb_clk);
return 0;
}
static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 6,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 9,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 7,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 2,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 9,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 1,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 1,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 7,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 1,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 7,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 3,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 1,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 7,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 8,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 2,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = {
.first_bank = SUNXI_GPIO_A,
.num_banks = 9,
};
static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = {
.first_bank = SUNXI_GPIO_L,
.num_banks = 1,
};
static const struct udevice_id sunxi_pinctrl_ids[] = {
#ifdef CONFIG_PINCTRL_SUNIV_F1C100S
{
.compatible = "allwinner,suniv-f1c100s-pinctrl",
.data = (ulong)&suniv_f1c100s_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN4I_A10
{
.compatible = "allwinner,sun4i-a10-pinctrl",
.data = (ulong)&sun4i_a10_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN5I_A13
{
.compatible = "allwinner,sun5i-a10s-pinctrl",
.data = (ulong)&sun5i_a13_pinctrl_desc,
},
{
.compatible = "allwinner,sun5i-a13-pinctrl",
.data = (ulong)&sun5i_a13_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN6I_A31
{
.compatible = "allwinner,sun6i-a31-pinctrl",
.data = (ulong)&sun6i_a31_pinctrl_desc,
},
{
.compatible = "allwinner,sun6i-a31s-pinctrl",
.data = (ulong)&sun6i_a31_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN6I_A31_R
{
.compatible = "allwinner,sun6i-a31-r-pinctrl",
.data = (ulong)&sun6i_a31_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN7I_A20
{
.compatible = "allwinner,sun7i-a20-pinctrl",
.data = (ulong)&sun7i_a20_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_A23
{
.compatible = "allwinner,sun8i-a23-pinctrl",
.data = (ulong)&sun8i_a23_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_A23_R
{
.compatible = "allwinner,sun8i-a23-r-pinctrl",
.data = (ulong)&sun8i_a23_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_A33
{
.compatible = "allwinner,sun8i-a33-pinctrl",
.data = (ulong)&sun8i_a33_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_A83T
{
.compatible = "allwinner,sun8i-a83t-pinctrl",
.data = (ulong)&sun8i_a83t_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_A83T_R
{
.compatible = "allwinner,sun8i-a83t-r-pinctrl",
.data = (ulong)&sun8i_a83t_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_H3
{
.compatible = "allwinner,sun8i-h3-pinctrl",
.data = (ulong)&sun8i_h3_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_H3_R
{
.compatible = "allwinner,sun8i-h3-r-pinctrl",
.data = (ulong)&sun8i_h3_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN7I_A20
{
.compatible = "allwinner,sun8i-r40-pinctrl",
.data = (ulong)&sun7i_a20_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN8I_V3S
{
.compatible = "allwinner,sun8i-v3-pinctrl",
.data = (ulong)&sun8i_v3s_pinctrl_desc,
},
{
.compatible = "allwinner,sun8i-v3s-pinctrl",
.data = (ulong)&sun8i_v3s_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN9I_A80
{
.compatible = "allwinner,sun9i-a80-pinctrl",
.data = (ulong)&sun9i_a80_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN9I_A80_R
{
.compatible = "allwinner,sun9i-a80-r-pinctrl",
.data = (ulong)&sun9i_a80_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_A64
{
.compatible = "allwinner,sun50i-a64-pinctrl",
.data = (ulong)&sun50i_a64_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_A64_R
{
.compatible = "allwinner,sun50i-a64-r-pinctrl",
.data = (ulong)&sun50i_a64_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_H5
{
.compatible = "allwinner,sun50i-h5-pinctrl",
.data = (ulong)&sun50i_h5_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_H6
{
.compatible = "allwinner,sun50i-h6-pinctrl",
.data = (ulong)&sun50i_h6_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_H6_R
{
.compatible = "allwinner,sun50i-h6-r-pinctrl",
.data = (ulong)&sun50i_h6_r_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_H616
{
.compatible = "allwinner,sun50i-h616-pinctrl",
.data = (ulong)&sun50i_h616_pinctrl_desc,
},
#endif
#ifdef CONFIG_PINCTRL_SUN50I_H616_R
{
.compatible = "allwinner,sun50i-h616-r-pinctrl",
.data = (ulong)&sun50i_h616_r_pinctrl_desc,
},
#endif
{}
};
U_BOOT_DRIVER(sunxi_pinctrl) = {
.name = "sunxi-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = sunxi_pinctrl_ids,
.bind = sunxi_pinctrl_bind,
.probe = sunxi_pinctrl_probe,
.plat_auto = sizeof(struct sunxi_pinctrl_plat),
.ops = &sunxi_pinctrl_ops,
};