From f81649586df766083c987bfa6ea72547fc5acb7e Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Wed, 9 Oct 2019 09:23:39 +0000 Subject: [PATCH] misc: microchip_flexcom: introduce microchip_flexcom driver The Microchip 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. The bindings are kept as in Linux. The driver registers to MISC_UCLASS. Signed-off-by: Eugen Hristev --- drivers/misc/Kconfig | 9 ++++++ drivers/misc/Makefile | 1 + drivers/misc/microchip_flexcom.c | 64 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 drivers/misc/microchip_flexcom.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index ba50893..4985ea0 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 0001d10..f612636 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 0000000..1bc19ed --- /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 + */ + +#include +#include +#include +#include +#include + +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), +}; -- 2.7.4