diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/microchip_flexcom.c | 64 |
3 files changed, 74 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index ba50893b43..4985ea033b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -412,4 +412,13 @@ config IHS_FPGA by the devices. This driver supports both CON and CPU variants of the devices, depending on the device tree entry. +config MICROCHIP_FLEXCOM + bool "Enable Microchip Flexcom driver" + depends on MISC + help + The Atmel Flexcom is just a wrapper which embeds a SPI controller, + an I2C controller and an USART. + Only one function can be used at a time and is chosen at boot time + according to the device tree. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 0001d105ba..f61263640b 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -65,3 +65,4 @@ obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o +obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o diff --git a/drivers/misc/microchip_flexcom.c b/drivers/misc/microchip_flexcom.c new file mode 100644 index 0000000000..1bc19edfcb --- /dev/null +++ b/drivers/misc/microchip_flexcom.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019, Microchip Technology, Inc. + * Author: Eugen Hristev <eugen.hristev@microchip.com> + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <misc.h> +#include <asm/io.h> + +struct microchip_flexcom_regs { + u32 cr; +}; + +struct microchip_flexcom_platdata { + struct microchip_flexcom_regs *regs; + u32 flexcom_mode; +}; + +static int microchip_flexcom_ofdata_to_platdata(struct udevice *dev) +{ + struct microchip_flexcom_platdata *plat = dev_get_platdata(dev); + int ret; + + plat->regs = map_physmem(devfdt_get_addr(dev), + sizeof(struct microchip_flexcom_regs), + MAP_NOCACHE); + + ret = dev_read_u32(dev, "atmel,flexcom-mode", &plat->flexcom_mode); + + if (IS_ERR_VALUE(ret)) { + debug("Missing atmel,flexcom-mode property\n"); + return ret; + } + + /* + * The mode must have only 2 bits. If any other bits are set, + * the value is not supported. + */ + if (plat->flexcom_mode & 0xfffffffc) { + debug("Wrong atmel,flexcom-mode property\n"); + return -EINVAL; + } + + writel(plat->flexcom_mode, &plat->regs->cr); + + return 0; +} + +static const struct udevice_id microchip_flexcom_ids[] = { + { .compatible = "atmel,sama5d2-flexcom" }, + { .compatible = "microchip,flexcom" }, + {} +}; + +U_BOOT_DRIVER(microchip_flexcom) = { + .name = "microchip_flexcom", + .id = UCLASS_MISC, + .of_match = microchip_flexcom_ids, + .ofdata_to_platdata = microchip_flexcom_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct microchip_flexcom_platdata), +}; |