diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index c91ed202f57..a9119d481ba 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -13,3 +13,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_KINETIS pinctrl_kinetis.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_XEC pinctrl_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCUX_RT pinctrl_mcux_rt.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_SIFIVE pinctrl_sifive.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b0572429c45..59a3081272d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -38,5 +38,6 @@ source "drivers/pinctrl/Kconfig.stm32" source "drivers/pinctrl/Kconfig.kinetis" source "drivers/pinctrl/Kconfig.xec" source "drivers/pinctrl/Kconfig.mcux" +source "drivers/pinctrl/Kconfig.sifive" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.sifive b/drivers/pinctrl/Kconfig.sifive new file mode 100644 index 00000000000..c8b9bedda3a --- /dev/null +++ b/drivers/pinctrl/Kconfig.sifive @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_SIFIVE_PINCTRL := sifive,pinctrl + +config PINCTRL_SIFIVE + bool "SiFive Freedom SoC pinmux driver" + depends on SOC_SERIES_RISCV_SIFIVE_FREEDOM + default $(dt_compat_enabled,$(DT_COMPAT_SIFIVE_PINCTRL)) + help + Enable driver for the SiFive Freedom SoC pinctrl driver diff --git a/drivers/pinctrl/pinctrl_sifive.c b/drivers/pinctrl/pinctrl_sifive.c new file mode 100644 index 00000000000..29a10559891 --- /dev/null +++ b/drivers/pinctrl/pinctrl_sifive.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sifive_pinctrl + +#include +#include +#include + +#define PINCTRL_BASE_ADDR DT_INST_REG_ADDR(0) +#define PINCTRL_IOF_EN (PINCTRL_BASE_ADDR + 0x0) +#define PINCTRL_IOF_SEL (PINCTRL_BASE_ADDR + 0x4) + +static int pinctrl_sifive_set(uint32_t pin, uint32_t func) +{ + uint32_t val; + + if (func > SIFIVE_PINMUX_IOF1 || pin >= SIFIVE_PINMUX_PINS) { + return -EINVAL; + } + + val = sys_read32(PINCTRL_IOF_SEL); + if (func == SIFIVE_PINMUX_IOF1) { + val |= (SIFIVE_PINMUX_IOF1 << pin); + } else { + val &= ~(SIFIVE_PINMUX_IOF1 << pin); + } + sys_write32(val, PINCTRL_IOF_SEL); + + /* Enable IO function for this pin */ + val = sys_read32(PINCTRL_IOF_EN); + val |= BIT(pin); + sys_write32(val, PINCTRL_IOF_EN); + + return 0; +} + + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + int i; + + for (i = 0; i < pin_cnt; i++) { + pinctrl_sifive_set(pins[i].pin, pins[i].iof); + } + + return 0; +} diff --git a/dts/bindings/pinctrl/sifive,pinctrl.yaml b/dts/bindings/pinctrl/sifive,pinctrl.yaml new file mode 100644 index 00000000000..41acb79e175 --- /dev/null +++ b/dts/bindings/pinctrl/sifive,pinctrl.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2022 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: | + SiFive FE310 IO Function (iof) binding covers the IOF_EN/IOF_SEL registers + that are a subset of the GPIO controller. You can use this node to set the + value of IOF_EN/IOF_SEL registers to control pin settings. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with a pair consisting of a pin number and its IO + function. The available IO functions are: + - SIFIVE_PINMUX_IOF0 + - SIFIVE_PINMUX_IOF1 + + For example, setting pins 16 and 17 both to IOF0 would look like this: + + #include + + &pinctrl { + uart0_rx_default: uart0_rx_default { + pinmux = <16 SIFIVE_PINMUX_IOF0>; + }; + uart0_tx_default: uart0_tx_default { + pinmux = <17 SIFIVE_PINMUX_IOF0>; + }; + }; + +compatible: "sifive,pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the SiFive FE310 pins + configuration. + + properties: + pinmux: + required: true + type: array + description: | + SiFive FE310 pin's configuration (pin, IO function). diff --git a/soc/riscv/riscv-privilege/sifive-freedom/pinctrl_soc.h b/soc/riscv/riscv-privilege/sifive-freedom/pinctrl_soc.h new file mode 100644 index 00000000000..ed534237da1 --- /dev/null +++ b/soc/riscv/riscv-privilege/sifive-freedom/pinctrl_soc.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_SIFIVE_FREEDOM_PINCTRL_H_ +#define ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_SIFIVE_FREEDOM_PINCTRL_H_ + +#include + +typedef struct pinctrl_soc_pin_t { + uint8_t pin; + uint8_t iof; +} pinctrl_soc_pin_t; + +#define SIFIVE_DT_PIN(node_id) \ + { \ + .pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .iof = DT_PROP_BY_IDX(node_id, pinmux, 1) \ + }, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + SIFIVE_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + +#endif /* ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_SIFIVE_FREEDOM_PINCTRL_H_ */