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:
cyliang tw 2023-03-03 17:27:55 +08:00 committed by Fabio Baltieri
commit 5879810137
8 changed files with 2334 additions and 0 deletions

View file

@ -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_EMSDP pinctrl_emsdp.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c)

View file

@ -61,5 +61,6 @@ source "drivers/pinctrl/Kconfig.gecko"
source "drivers/pinctrl/Kconfig.ti_k3"
source "drivers/pinctrl/Kconfig.emsdp"
source "drivers/pinctrl/Kconfig.ti_cc32xx"
source "drivers/pinctrl/Kconfig.numaker"
endif # PINCTRL

View 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.

View 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;
}

View file

@ -6,6 +6,7 @@
#include <arm/armv7-m.dtsi>
#include <mem.h>
#include <zephyr/dt-bindings/pinctrl/numaker-m46x-pinctrl.h>
/ {
cpus {
@ -36,6 +37,14 @@
clock-frequency = <200000000>;
#clock-cells = <0>;
};
soc {
pinctrl: pin-controller@40000500 {
compatible = "nuvoton,numaker-pinctrl";
reg = <0x40000500 0xa0>;
status = "okay";
};
};
};
&nvic {

View 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.

File diff suppressed because it is too large Load diff

View 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_ */