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_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)
|
||||
|
|
|
@ -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
|
||||
|
|
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 <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 {
|
||||
|
|
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