diff --git a/drivers/pinmux/Kconfig b/drivers/pinmux/Kconfig index 3e5769dadf8..a9f9062fe1a 100644 --- a/drivers/pinmux/Kconfig +++ b/drivers/pinmux/Kconfig @@ -52,4 +52,6 @@ source "drivers/pinmux/Kconfig.stm32" source "drivers/pinmux/Kconfig.beetle" +source "drivers/pinmux/Kconfig.fe310" + endif # PINMUX diff --git a/drivers/pinmux/Kconfig.fe310 b/drivers/pinmux/Kconfig.fe310 new file mode 100644 index 00000000000..a2a392efaac --- /dev/null +++ b/drivers/pinmux/Kconfig.fe310 @@ -0,0 +1,21 @@ +# Kconfig.fe310 - PINMUX configuration options for SiFive Freedom E310 SOC +# +# Copyright (c) 2017 Jean-Paul Etienne +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig PINMUX_FE310 + bool "SiFive Freedom E310 SOC pinmux driver" + depends on PINMUX && SOC_SERIES_RISCV32_FE310 + default n + help + Enable driver for the SiFive Freedom E310 SOC pinmux driver + +if PINMUX_FE310 + +config PINMUX_FE310_0_NAME + string "FE310 pinmux 0 driver name" + default "pinmux0" + +endif # PINMUX_FE310 diff --git a/drivers/pinmux/Makefile b/drivers/pinmux/Makefile index 6a5560c8fcc..9ab0986e5c1 100644 --- a/drivers/pinmux/Makefile +++ b/drivers/pinmux/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_BOARD_NUCLEO_L476RG) += stm32/pinmux_board_nucleo_l476rg.o obj-$(CONFIG_BOARD_OLIMEXINO_STM32) += stm32/pinmux_board_olimexino_stm32.o obj-$(CONFIG_BOARD_STM32_MINI_A15) += stm32/pinmux_board_stm32_mini_a15.o obj-$(CONFIG_PINMUX_QMSI) += pinmux_qmsi.o +obj-$(CONFIG_PINMUX_FE310) += pinmux_fe310.o # "runtime" pinmux obj-$(CONFIG_PINMUX_DEV) += dev/ diff --git a/drivers/pinmux/pinmux_fe310.c b/drivers/pinmux/pinmux_fe310.c new file mode 100644 index 00000000000..45e64cbdcb2 --- /dev/null +++ b/drivers/pinmux/pinmux_fe310.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief PINMUX driver for the SiFive Freedom E310 Processor + */ + +#include +#include +#include +#include + +struct pinmux_fe310_config { + uint32_t base; +}; + +struct pinmux_fe310_regs_t { + uint32_t iof_en; + uint32_t iof_sel; +}; + +#define DEV_CFG(dev) \ + ((const struct pinmux_fe310_config * const) \ + (dev)->config->config_info) + +#define DEV_PINMUX(dev) \ + ((struct pinmux_fe310_regs_t *)(DEV_CFG(dev))->base) + +static int pinmux_fe310_set(struct device *dev, uint32_t pin, uint32_t func) +{ + volatile struct pinmux_fe310_regs_t *pinmux = DEV_PINMUX(dev); + + if (func > FE310_PINMUX_IOF1 || + pin >= FE310_PINMUX_PINS) + return -EINVAL; + + if (func == FE310_PINMUX_IOF1) + pinmux->iof_sel |= (FE310_PINMUX_IOF1 << pin); + else + pinmux->iof_sel &= ~(FE310_PINMUX_IOF1 << pin); + + /* Enable IO function for this pin */ + pinmux->iof_en |= (1 << pin); + + return 0; +} + +static int pinmux_fe310_get(struct device *dev, uint32_t pin, uint32_t *func) +{ + volatile struct pinmux_fe310_regs_t *pinmux = DEV_PINMUX(dev); + + if (pin >= FE310_PINMUX_PINS || + func == NULL) + return -EINVAL; + + *func = (pinmux->iof_sel & (FE310_PINMUX_IOF1 << pin)) ? + FE310_PINMUX_IOF1 : FE310_PINMUX_IOF0; + + return 0; +} + +static int pinmux_fe310_pullup(struct device *dev, uint32_t pin, uint8_t func) +{ + return -ENOTSUP; +} + +static int pinmux_fe310_input(struct device *dev, uint32_t pin, uint8_t func) +{ + return -ENOTSUP; +} + +static int pinmux_fe310_init(struct device *dev) +{ + volatile struct pinmux_fe310_regs_t *pinmux = DEV_PINMUX(dev); + + /* Ensure that all pins are disabled initially */ + pinmux->iof_en = 0x0; + + return 0; +} + +static const struct pinmux_driver_api pinmux_fe310_driver_api = { + .set = pinmux_fe310_set, + .get = pinmux_fe310_get, + .pullup = pinmux_fe310_pullup, + .input = pinmux_fe310_input, +}; + +static const struct pinmux_fe310_config pinmux_fe310_0_config = { + .base = FE310_PINMUX_0_BASE_ADDR, +}; + +DEVICE_AND_API_INIT(pinmux_fe310_0, CONFIG_PINMUX_FE310_0_NAME, + &pinmux_fe310_init, NULL, + &pinmux_fe310_0_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_fe310_driver_api);