drivers: pinctrl: add support for NuMaker series pinctrl
Add Nuvoton numaker series pinctrl support. Signed-off-by: cyliang tw <cyliang@nuvoton.com>
This commit is contained in:
parent
512371b75b
commit
5879810137
8 changed files with 2334 additions and 0 deletions
|
@ -32,3 +32,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_GECKO pinctrl_gecko.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c)
|
||||||
|
|
|
@ -61,5 +61,6 @@ source "drivers/pinctrl/Kconfig.gecko"
|
||||||
source "drivers/pinctrl/Kconfig.ti_k3"
|
source "drivers/pinctrl/Kconfig.ti_k3"
|
||||||
source "drivers/pinctrl/Kconfig.emsdp"
|
source "drivers/pinctrl/Kconfig.emsdp"
|
||||||
source "drivers/pinctrl/Kconfig.ti_cc32xx"
|
source "drivers/pinctrl/Kconfig.ti_cc32xx"
|
||||||
|
source "drivers/pinctrl/Kconfig.numaker"
|
||||||
|
|
||||||
endif # PINCTRL
|
endif # PINCTRL
|
||||||
|
|
11
drivers/pinctrl/Kconfig.numaker
Normal file
11
drivers/pinctrl/Kconfig.numaker
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Nuvoton NuMaker Pin Controller configuration options
|
||||||
|
|
||||||
|
# Copyright (c) 2023 Nuvoton Technology Corporation.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config PINCTRL_NUMAKER
|
||||||
|
bool "Nuvoton NuMaker pin controller driver"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_NUVOTON_NUMAKER_PINCTRL_ENABLED
|
||||||
|
help
|
||||||
|
This option enables the pin controller driver for Nuvoton NuMaker MCUs.
|
46
drivers/pinctrl/pinctrl_numaker.c
Normal file
46
drivers/pinctrl/pinctrl_numaker.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Nuvoton Technology Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT nuvoton_numaker_pinctrl
|
||||||
|
|
||||||
|
#include <zephyr/drivers/pinctrl.h>
|
||||||
|
#include <NuMicro.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure pin multi-function
|
||||||
|
*/
|
||||||
|
static void configure_pin(const pinctrl_soc_pin_t *pin)
|
||||||
|
{
|
||||||
|
uint32_t pin_mux = pin->pin_mux;
|
||||||
|
uint32_t pin_index = PIN_INDEX(pin_mux);
|
||||||
|
uint32_t port_index = PORT_INDEX(pin_mux);
|
||||||
|
uint32_t mfp_cfg = MFP_CFG(pin_mux);
|
||||||
|
|
||||||
|
/* Get mfp_base, it should be == (&SYS->GPA_MFP0) in M467 */
|
||||||
|
uint32_t mfp_base = DT_REG_ADDR(DT_NODELABEL(pinctrl));
|
||||||
|
|
||||||
|
uint32_t *GPx_MFPx = ((uint32_t *)mfp_base) + port_index * 4 + (pin_index / 4);
|
||||||
|
uint32_t pinMask = NU_MFP_MASK(pin_index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* E.g.: SYS->GPA_MFP0 = (SYS->GPA_MFP0 & (~SYS_GPA_MFP0_PA0MFP_Msk) ) |
|
||||||
|
* SYS_GPA_MFP0_PA0MFP_SC0_CD;
|
||||||
|
*/
|
||||||
|
*GPx_MFPx = (*GPx_MFPx & (~pinMask)) | mfp_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pinctrl API implementation */
|
||||||
|
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(reg);
|
||||||
|
|
||||||
|
/* Configure all peripheral devices' properties here. */
|
||||||
|
for (uint8_t i = 0U; i < pin_cnt; i++) {
|
||||||
|
configure_pin(&pins[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <arm/armv7-m.dtsi>
|
#include <arm/armv7-m.dtsi>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
|
#include <zephyr/dt-bindings/pinctrl/numaker-m46x-pinctrl.h>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
cpus {
|
cpus {
|
||||||
|
@ -36,6 +37,14 @@
|
||||||
clock-frequency = <200000000>;
|
clock-frequency = <200000000>;
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
soc {
|
||||||
|
pinctrl: pin-controller@40000500 {
|
||||||
|
compatible = "nuvoton,numaker-pinctrl";
|
||||||
|
reg = <0x40000500 0xa0>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&nvic {
|
&nvic {
|
||||||
|
|
80
dts/bindings/pinctrl/nuvoton,numaker-pinctrl.yaml
Normal file
80
dts/bindings/pinctrl/nuvoton,numaker-pinctrl.yaml
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# Copyright (c) Nuvoton Technology Corp. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Pin controller is responsible for controlling pin function
|
||||||
|
selection and pin properties. For example, for example you can
|
||||||
|
use this node to set UART0 RX as pin PB12 to fulfill SYS_GPB_MFP3_PB12MFP_UART0_RXD.
|
||||||
|
|
||||||
|
The node has the 'pinctrl' node label set in your SoC's devicetree,
|
||||||
|
so you can modify it like this:
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
/* your modifications go here */
|
||||||
|
};
|
||||||
|
|
||||||
|
All device pin configurations should be placed in child nodes of the
|
||||||
|
'pinctrl' node, as shown in this example:
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
/* configuration for the uart0 "default" state */
|
||||||
|
uart0_default: uart0_default {
|
||||||
|
/* configure PB13 as UART0 TX and PB12 as UART0 RX */
|
||||||
|
pinmux = <PB12MFP_UART0_RXD 0x0000>, <PB13MFP_UART0_TXD 0x0000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
To link pin configurations with a device, use a pinctrl-N property for some
|
||||||
|
number N, like this example you could place in your board's DTS file:
|
||||||
|
|
||||||
|
#include "board-pinctrl.dtsi"
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
pinctrl-0 = <&uart0_default>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
compatible: "nuvoton,numaker-pinctrl"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- name: base.yaml
|
||||||
|
- name: pincfg-node.yaml
|
||||||
|
child-binding:
|
||||||
|
property-allowlist:
|
||||||
|
- drive-push-pull
|
||||||
|
- drive-open-drain
|
||||||
|
- bias-disable
|
||||||
|
- bias-pull-down
|
||||||
|
- bias-pull-up
|
||||||
|
|
||||||
|
child-binding:
|
||||||
|
description: |
|
||||||
|
Each child node defines the configuration for a particular state.
|
||||||
|
properties:
|
||||||
|
pinmux:
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
|
description: |
|
||||||
|
An array of pins sharing the same group properties. The pins should
|
||||||
|
be defined using pre-defined macros or, alternatively, using NVT_PINMUX
|
||||||
|
macros depending on the pinmux model used by the SoC series.
|
||||||
|
drive-strength:
|
||||||
|
type: string
|
||||||
|
default: "low"
|
||||||
|
enum:
|
||||||
|
- "low"
|
||||||
|
- "fast"
|
||||||
|
description: |
|
||||||
|
Set the driving strength of a pin. Hardware default configuration is low and
|
||||||
|
it's enough to drive most components, like as LED, CAN transceiver and so on.
|
||||||
|
slew-rate:
|
||||||
|
type: string
|
||||||
|
default: "low"
|
||||||
|
enum:
|
||||||
|
- "fast"
|
||||||
|
- "low"
|
||||||
|
description: |
|
||||||
|
Set the speed of a pin. This setting effectively limits the
|
||||||
|
slew rate of the output signal. Hardware default configuration is low.
|
||||||
|
Fast slew rate could support high speed pins, like as SPI CLK up to 50MHz.
|
2154
include/zephyr/dt-bindings/pinctrl/numaker-m46x-pinctrl.h
Normal file
2154
include/zephyr/dt-bindings/pinctrl/numaker-m46x-pinctrl.h
Normal file
File diff suppressed because it is too large
Load diff
32
soc/arm/nuvoton_numaker/common/pinctrl_soc.h
Normal file
32
soc/arm/nuvoton_numaker/common/pinctrl_soc.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Nuvoton Technology Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NUVOTON_NUMAKER_PINCTRL_SOC_H_
|
||||||
|
#define _NUVOTON_NUMAKER_PINCTRL_SOC_H_
|
||||||
|
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PORT_INDEX(pinmux) (((pinmux)&0xF0000000) >> 28)
|
||||||
|
#define PIN_INDEX(pinmux) (((pinmux)&0x0F000000) >> 24)
|
||||||
|
#define MFP_CFG(pinmux) (((pinmux)&0x000000FF) << ((PIN_INDEX(pinmux) % 4) * 8))
|
||||||
|
#define NU_MFP_POS(pinindex) ((pinindex % 4) * 8)
|
||||||
|
#define NU_MFP_MASK(pinindex) (0x1f << NU_MFP_POS(pinindex))
|
||||||
|
|
||||||
|
typedef struct pinctrl_soc_pin_t {
|
||||||
|
uint32_t pin_mux;
|
||||||
|
} pinctrl_soc_pin_t;
|
||||||
|
|
||||||
|
#define NUMAKER_DT_PIN(node_id, prop, idx) {.pin_mux = DT_PROP_BY_IDX(node_id, prop, idx)},
|
||||||
|
|
||||||
|
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) NUMAKER_DT_PIN(node_id, prop, idx)
|
||||||
|
|
||||||
|
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
|
||||||
|
{ \
|
||||||
|
DT_FOREACH_PROP_ELEM(DT_PHANDLE(node_id, prop), pinmux, Z_PINCTRL_STATE_PIN_INIT) \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _NUVOTON_NUMAKER_PINCTRL_SOC_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue