diff --git a/drivers/pinmux/CMakeLists.txt b/drivers/pinmux/CMakeLists.txt index cac00b41b33..338d4de4710 100644 --- a/drivers/pinmux/CMakeLists.txt +++ b/drivers/pinmux/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_sources_ifdef(CONFIG_PINMUX_QMSI pinmux_qmsi.c) zephyr_sources_ifdef(CONFIG_PINMUX_STM32 stm32/pinmux_stm32.c) zephyr_sources_ifdef(CONFIG_PINMUX_SAM0 pinmux_sam0.c) zephyr_sources_ifdef(CONFIG_PINMUX_INTEL_S1000 pinmux_intel_s1000.c) +zephyr_sources_ifdef(CONFIG_PINMUX_RV32M1 pinmux_rv32m1.c) # "runtime" pinmux add_subdirectory_ifdef(CONFIG_PINMUX_DEV dev) diff --git a/drivers/pinmux/Kconfig b/drivers/pinmux/Kconfig index 146783f5fd2..14c1e894c95 100644 --- a/drivers/pinmux/Kconfig +++ b/drivers/pinmux/Kconfig @@ -61,4 +61,6 @@ source "drivers/pinmux/Kconfig.sam0" source "drivers/pinmux/Kconfig.intel_s1000" +source "drivers/pinmux/Kconfig.rv32m1" + endif # PINMUX diff --git a/drivers/pinmux/Kconfig.rv32m1 b/drivers/pinmux/Kconfig.rv32m1 new file mode 100644 index 00000000000..5d178c1da43 --- /dev/null +++ b/drivers/pinmux/Kconfig.rv32m1 @@ -0,0 +1,67 @@ +# Kconfig - RV31M1 SDK pinmux +# +# Copyright (c) 2018 Foundries.io +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig PINMUX_RV32M1 + bool "RV32M1 pinmux driver" + depends on PINMUX && SOC_OPENISA_RV32M1_RISCV32 + help + Enable the RV32M1 pinmux driver. + +if PINMUX_RV32M1 + +config PINMUX_RV32M1_PORTA + bool "Port A" + help + Enable Port A. + +config PINMUX_RV32M1_PORTA_NAME + string "Pinmux Port A driver name" + depends on PINMUX_RV32M1_PORTA + default "porta" + +config PINMUX_RV32M1_PORTB + bool "Port B" + help + Enable Port B. + +config PINMUX_RV32M1_PORTB_NAME + string "Pinmux Port B driver name" + depends on PINMUX_RV32M1_PORTB + default "portb" + +config PINMUX_RV32M1_PORTC + bool "Port C" + help + Enable Port C. + +config PINMUX_RV32M1_PORTC_NAME + string "Pinmux Port C driver name" + depends on PINMUX_RV32M1_PORTC + default "portc" + +config PINMUX_RV32M1_PORTD + bool "Port D" + help + Enable Port D. + +config PINMUX_RV32M1_PORTD_NAME + string "Pinmux Port D driver name" + depends on PINMUX_RV32M1_PORTD + default "portd" + +config PINMUX_RV32M1_PORTE + bool "Port E" + depends on RV32M1_INTMUX + help + Enable Port E. + +config PINMUX_RV32M1_PORTE_NAME + string "Pinmux Port E driver name" + depends on PINMUX_RV32M1_PORTE + default "porte" + +endif # PINMUX_RV32M1 diff --git a/drivers/pinmux/pinmux_rv32m1.c b/drivers/pinmux/pinmux_rv32m1.c new file mode 100644 index 00000000000..41cd82693ae --- /dev/null +++ b/drivers/pinmux/pinmux_rv32m1.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright (c) 2018 Foundries.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +struct pinmux_rv32m1_config { + clock_ip_name_t clock_ip_name; + PORT_Type *base; +}; + +static int pinmux_rv32m1_set(struct device *dev, u32_t pin, u32_t func) +{ + const struct pinmux_rv32m1_config *config = dev->config->config_info; + PORT_Type *base = config->base; + + base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | func; + + return 0; +} + +static int pinmux_rv32m1_get(struct device *dev, u32_t pin, u32_t *func) +{ + const struct pinmux_rv32m1_config *config = dev->config->config_info; + PORT_Type *base = config->base; + + *func = base->PCR[pin] & ~PORT_PCR_MUX_MASK; + + return 0; +} + +static int pinmux_rv32m1_pullup(struct device *dev, u32_t pin, u8_t func) +{ + return -ENOTSUP; +} + +static int pinmux_rv32m1_input(struct device *dev, u32_t pin, u8_t func) +{ + return -ENOTSUP; +} + +static int pinmux_rv32m1_init(struct device *dev) +{ + const struct pinmux_rv32m1_config *config = dev->config->config_info; + + CLOCK_EnableClock(config->clock_ip_name); + + return 0; +} + +static const struct pinmux_driver_api pinmux_rv32m1_driver_api = { + .set = pinmux_rv32m1_set, + .get = pinmux_rv32m1_get, + .pullup = pinmux_rv32m1_pullup, + .input = pinmux_rv32m1_input, +}; + +#ifdef CONFIG_PINMUX_RV32M1_PORTA +static const struct pinmux_rv32m1_config pinmux_rv32m1_porta_config = { + .base = (PORT_Type *)PINMUX_A_BASE_ADDRESS, + .clock_ip_name = kCLOCK_PortA, +}; + +DEVICE_AND_API_INIT(pinmux_porta, CONFIG_PINMUX_RV32M1_PORTA_NAME, + &pinmux_rv32m1_init, + NULL, &pinmux_rv32m1_porta_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_rv32m1_driver_api); +#endif + +#ifdef CONFIG_PINMUX_RV32M1_PORTB +static const struct pinmux_rv32m1_config pinmux_rv32m1_portb_config = { + .base = (PORT_Type *)PINMUX_B_BASE_ADDRESS, + .clock_ip_name = kCLOCK_PortB, +}; + +DEVICE_AND_API_INIT(pinmux_portb, CONFIG_PINMUX_RV32M1_PORTB_NAME, + &pinmux_rv32m1_init, + NULL, &pinmux_rv32m1_portb_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_rv32m1_driver_api); +#endif + +#ifdef CONFIG_PINMUX_RV32M1_PORTC +static const struct pinmux_rv32m1_config pinmux_rv32m1_portc_config = { + .base = (PORT_Type *)PINMUX_C_BASE_ADDRESS, + .clock_ip_name = kCLOCK_PortC, +}; + +DEVICE_AND_API_INIT(pinmux_portc, CONFIG_PINMUX_RV32M1_PORTC_NAME, + &pinmux_rv32m1_init, + NULL, &pinmux_rv32m1_portc_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_rv32m1_driver_api); +#endif + +#ifdef CONFIG_PINMUX_RV32M1_PORTD +static const struct pinmux_rv32m1_config pinmux_rv32m1_portd_config = { + .base = (PORT_Type *)PINMUX_D_BASE_ADDRESS, + .clock_ip_name = kCLOCK_PortD, +}; + +DEVICE_AND_API_INIT(pinmux_portd, CONFIG_PINMUX_RV32M1_PORTD_NAME, + &pinmux_rv32m1_init, + NULL, &pinmux_rv32m1_portd_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_rv32m1_driver_api); +#endif + +#ifdef CONFIG_PINMUX_RV32M1_PORTE +static const struct pinmux_rv32m1_config pinmux_rv32m1_porte_config = { + .base = (PORT_Type *)PINMUX_E_BASE_ADDRESS, + .clock_ip_name = kCLOCK_PortE, +}; + +DEVICE_AND_API_INIT(pinmux_porte, CONFIG_PINMUX_RV32M1_PORTE_NAME, + &pinmux_rv32m1_init, + NULL, &pinmux_rv32m1_porte_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &pinmux_rv32m1_driver_api); +#endif diff --git a/dts/bindings/pinctrl/openisa,rv32m1-pinmux.yaml b/dts/bindings/pinctrl/openisa,rv32m1-pinmux.yaml new file mode 100644 index 00000000000..17a0c5bb195 --- /dev/null +++ b/dts/bindings/pinctrl/openisa,rv32m1-pinmux.yaml @@ -0,0 +1,31 @@ +--- +title: RV32M1 Pinmux +version: 0.1 + +description: > + This is a representation of the RV32M1 Pinmux node + +properties: + compatible: + type: string + category: required + description: compatible strings + constraint: "openisa,rv32m1-pinmux" + generation: define + + reg: + type: int + description: mmio register space + generation: define + category: required + + clocks: + type: array + description: clock gate information + generation: define + category: required + +"#cells": + - pin + - function +... diff --git a/dts/riscv32/rv32m1_ri5cy.dtsi b/dts/riscv32/rv32m1_ri5cy.dtsi index 67e67fbf4de..9ace6688ba3 100644 --- a/dts/riscv32/rv32m1_ri5cy.dtsi +++ b/dts/riscv32/rv32m1_ri5cy.dtsi @@ -14,6 +14,11 @@ pcc-1 = &pcc1; intmux = &intmux; system-lptmr = &lptmr0; + pinmux-a = &pinmux_a; + pinmux-b = &pinmux_b; + pinmux-c = &pinmux_c; + pinmux-d = &pinmux_d; + pinmux-e = &pinmux_e; }; cpus { @@ -108,5 +113,35 @@ interrupts = ; label = "LPTMR_2"; }; + + pinmux_a: pinmux@40046000 { + compatible = "openisa,rv32m1-pinmux"; + reg = <0x40046000 0xd0>; + clocks = <&pcc0 0x118>; + }; + + pinmux_b: pinmux@40047000 { + compatible = "openisa,rv32m1-pinmux"; + reg = <0x40047000 0xd0>; + clocks = <&pcc0 0x11c>; + }; + + pinmux_c: pinmux@40048000 { + compatible = "openisa,rv32m1-pinmux"; + reg = <0x40048000 0xd0>; + clocks = <&pcc0 0x120>; + }; + + pinmux_d: pinmux@40049000 { + compatible = "openisa,rv32m1-pinmux"; + reg = <0x40049000 0xd0>; + clocks = <&pcc0 0x124>; + }; + + pinmux_e: pinmux@41037000 { + compatible = "openisa,rv32m1-pinmux"; + reg = <0x41037000 0xd0>; + clocks = <&pcc1 0xdc>; + }; }; }; diff --git a/soc/riscv32/openisa_rv32m1/Kconfig.defconfig b/soc/riscv32/openisa_rv32m1/Kconfig.defconfig index 4529e00f040..21e4ea3d046 100644 --- a/soc/riscv32/openisa_rv32m1/Kconfig.defconfig +++ b/soc/riscv32/openisa_rv32m1/Kconfig.defconfig @@ -167,4 +167,7 @@ config RV32M1_INTMUX_CHANNEL_7 endif # MULTI_LEVEL_INTERRUPTS +config PINMUX_RV32M1 + def_bool y + endif # SOC_OPENISA_RV32M1_RISCV32