Skip to content

Commit 12ccbea

Browse files
AzharMCHPArunMCHP
authored andcommitted
drivers: pinctrl: microchip: add pinctrl driver for Port G1 IP
Add pinctrl driver for Microchip Port G1 Peripheral IPs Signed-off-by: Mohamed Azhar <[email protected]>
1 parent 5853403 commit 12ccbea

File tree

5 files changed

+311
-0
lines changed

5 files changed

+311
-0
lines changed

drivers/pinctrl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_SY1XX pinctrl_sy1xx.c)
5757
zephyr_library_sources_ifdef(CONFIG_PINCTRL_REALTEK_RTS5912 pinctrl_realtek_rts5912.c)
5858
zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_20X_30X_AFIO pinctrl_wch_20x_30x_afio.c)
5959
zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_00X_AFIO pinctrl_wch_00x_afio.c)
60+
zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_PORT_G1 pinctrl_mchp_port_g1.c)
6061

6162
add_subdirectory(renesas)

drivers/pinctrl/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ source "drivers/pinctrl/Kconfig.sy1xx"
8282
source "drivers/pinctrl/Kconfig.realtek_rts5912"
8383
source "drivers/pinctrl/Kconfig.wch_20x_30x_afio"
8484
source "drivers/pinctrl/Kconfig.wch_00x_afio"
85+
source "drivers/pinctrl/Kconfig.mchp"
8586

8687
rsource "renesas/Kconfig"
8788

drivers/pinctrl/Kconfig.mchp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) 2025 Microchip Technology Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config PINCTRL_MCHP_PORT_ID_U2210_2_2_0
5+
bool
6+
default n
7+
help
8+
Internal flag to enable PORT ID U2210_2_2_0 support.
9+
10+
config PINCTRL_MCHP_PORT_G1
11+
bool "Microchip PORT_G1 pin controller driver"
12+
default y
13+
depends on DT_HAS_MICROCHIP_PORT_G1_PINCTRL_ENABLED
14+
select PINCTRL_MCHP_PORT_ID_U2210_2_2_0 if SOC_FAMILY_MCHP_SAM_D5X_E5X
15+
help
16+
Microchip pin controller driver for Pinctrl group1 IP
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2025 Microchip Technology Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file pinctrl_mchp_port_g1.c
9+
* @brief Pin control driver for Microchip devices.
10+
*
11+
* This file provides the implementation of pin control functions
12+
* for Microchip-based systems.
13+
*/
14+
15+
#include <zephyr/drivers/pinctrl.h>
16+
#include <soc.h>
17+
18+
/**
19+
* @brief Utility macro that expands to the PORT address if it exists.
20+
*
21+
* This macro checks if a node label exists in the device tree and, if it does,
22+
* it expands to the register address of that node label. If the node label does
23+
* not exist, it expands to nothing.
24+
*
25+
* @param nodelabel The node label to check in the device tree.
26+
*/
27+
#define MCHP_PORT_ADDR_OR_NONE(nodelabel) \
28+
IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \
29+
(DT_REG_ADDR(DT_NODELABEL(nodelabel))))
30+
31+
/**
32+
* @brief Array of port addresses for the MCHP SAMD5x_E5x series.
33+
*
34+
* This array contains the register addresses of the ports (PORTA, PORTB, PORTC, and PORTD)
35+
* for the MCHP SAMD5x_E5x series microcontrollers. The addresses are obtained using the
36+
* MCHP_PORT_ADDR_OR_NONE macro, which ensures that only existing ports are included.
37+
* This can be updated for other devices using conditional comiplation directives
38+
*/
39+
static const uint32_t mchp_port_addrs[] = {
40+
MCHP_PORT_ADDR_OR_NONE(porta),
41+
MCHP_PORT_ADDR_OR_NONE(portb),
42+
MCHP_PORT_ADDR_OR_NONE(portc),
43+
MCHP_PORT_ADDR_OR_NONE(portd),
44+
};
45+
46+
/**
47+
* @brief Set pinmux registers using odd/even logic
48+
*
49+
* This function configures the pinmux registers for a given pin based on
50+
* the provided pin control information. It determines whether the pin number
51+
* is odd or even and sets the appropriate bits in the PORT_PMUX register.
52+
*
53+
* @param pin Pointer to the pin control information
54+
* @param reg Pointer to the base address of the port group registers
55+
*/
56+
static void pinctrl_pinmux(const pinctrl_soc_pin_t *pin)
57+
{
58+
port_group_registers_t *pRegister;
59+
60+
uint8_t pin_num = MCHP_PINMUX_PIN_GET(pin->pinmux);
61+
uint8_t port_id = MCHP_PINMUX_PORT_GET(pin->pinmux);
62+
uint8_t pin_mux = MCHP_PINMUX_PERIPH_GET(pin->pinmux);
63+
64+
bool is_odd = pin_num & 1;
65+
uint32_t idx = pin_num / 2U;
66+
67+
pRegister = (port_group_registers_t *)mchp_port_addrs[port_id];
68+
69+
if (pRegister != NULL) {
70+
/* Each pinmux register holds the config for two pins. The
71+
* even numbered pin goes in the bits 0..3 and the odd
72+
* numbered pin in bits 4..7.
73+
*/
74+
if (is_odd == true) {
75+
pRegister->PORT_PMUX[idx] |= PORT_PMUX_PMUXO(pin_mux);
76+
} else {
77+
pRegister->PORT_PMUX[idx] |= PORT_PMUX_PMUXE(pin_mux);
78+
}
79+
pRegister->PORT_PINCFG[pin_num] |= (uint8_t)PORT_PINCFG_PMUXEN_Msk;
80+
}
81+
}
82+
83+
/**
84+
* @brief Set all pin configuration registers by checking the flags
85+
*
86+
* This function configures various pin settings such as pull-up, pull-down,
87+
* input enable, output enable, and drive strength based on the provided
88+
* pin control information.
89+
*
90+
* @param pin Pointer to the pin control information
91+
* @param reg Pointer to the base address of the port group registers
92+
*/
93+
static void pinctrl_set_flags(const pinctrl_soc_pin_t *pin)
94+
{
95+
port_group_registers_t *pRegister;
96+
97+
uint8_t pin_num = MCHP_PINMUX_PIN_GET(pin->pinmux);
98+
uint8_t port_id = MCHP_PINMUX_PORT_GET(pin->pinmux);
99+
100+
pRegister = (port_group_registers_t *)mchp_port_addrs[port_id];
101+
102+
if (pRegister != NULL) {
103+
104+
/* Check if pull-up or pull-down resistors need to be configured */
105+
if (((pin->pinflag & MCHP_PINCTRL_PULLUP) != 0) ||
106+
((pin->pinflag & MCHP_PINCTRL_PULLDOWN) != 0)) {
107+
if ((pin->pinflag & MCHP_PINCTRL_PULLUP) != 0) {
108+
/* If pull-up resistor enabled,
109+
* set the corresponding bit in PORT_OUT reg
110+
*/
111+
pRegister->PORT_OUT |= (1 << pin_num);
112+
}
113+
pRegister->PORT_PINCFG[pin_num] |= PORT_PINCFG_PULLEN(1);
114+
} else {
115+
pRegister->PORT_PINCFG[pin_num] &= ~PORT_PINCFG_PULLEN(1);
116+
}
117+
118+
/* if input is enabled, set the corresponding bit in PORT_PINCFG register */
119+
if ((pin->pinflag & MCHP_PINCTRL_INPUTENABLE) != 0) {
120+
pRegister->PORT_PINCFG[pin_num] |= PORT_PINCFG_INEN(1);
121+
} else {
122+
pRegister->PORT_PINCFG[pin_num] &= ~PORT_PINCFG_INEN(1);
123+
}
124+
125+
/* if output is enabled, set the corresponding bit in PORT_DIR register */
126+
if ((pin->pinflag & MCHP_PINCTRL_OUTPUTENABLE) != 0) {
127+
pRegister->PORT_DIR |= (1 << pin_num);
128+
} else {
129+
pRegister->PORT_DIR &= ~(1 << pin_num);
130+
}
131+
132+
/* if drive strength is enabled, set the corresponding bit in PORT_PINCFG reg */
133+
if ((pin->pinflag & MCHP_PINCTRL_DRIVESTRENGTH) != 0) {
134+
pRegister->PORT_PINCFG[pin_num] |= PORT_PINCFG_DRVSTR(1);
135+
} else {
136+
pRegister->PORT_PINCFG[pin_num] &= ~PORT_PINCFG_DRVSTR(1);
137+
}
138+
}
139+
}
140+
141+
/**
142+
* @brief Configure a specific pin based on the provided pin configuration.
143+
*
144+
* This helper function configures a pin by determining its port function and then
145+
* calling the appropriate functions to set the pinmux and other pin configurations.
146+
*
147+
* @param pin The pin configuration to be applied. This is of type pinctrl_soc_pin_t.
148+
*/
149+
static void pinctrl_configure_pin(pinctrl_soc_pin_t pin)
150+
{
151+
uint8_t port_func = MCHP_PINMUX_FUNC_GET(pin.pinmux);
152+
153+
/* call pinmux function if alternate function is configured */
154+
if (port_func == MCHP_PINMUX_FUNC_periph) {
155+
pinctrl_pinmux(&pin);
156+
}
157+
158+
/* set all other pin configurations */
159+
pinctrl_set_flags(&pin);
160+
}
161+
162+
/**
163+
* @brief Configure multiple pins.
164+
*
165+
* This function configures a set of pins based on the provided pin
166+
* configuration array.
167+
*
168+
* @param pins Pointer to an array of pinctrl_soc_pin_t structures that
169+
* define the pin configurations.
170+
* @param pin_cnt Number of pins to configure.
171+
* @param reg Unused parameter.
172+
*
173+
* @return 0 on success.
174+
*/
175+
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
176+
{
177+
ARG_UNUSED(reg);
178+
179+
for (uint8_t i = 0U; i < pin_cnt; i++) {
180+
pinctrl_configure_pin(*pins);
181+
pins++;
182+
}
183+
184+
return 0;
185+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2025 Microchip Technology Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef SOC_MICROCHIP_SAM_D5X_E5X_COMMON_PINCTRL_SOC_H_
8+
#define SOC_MICROCHIP_SAM_D5X_E5X_COMMON_PINCTRL_SOC_H_
9+
10+
#include <zephyr/devicetree.h>
11+
#include <zephyr/types.h>
12+
#include "dt-bindings/sam/sam_d5x_e5x/common/mchp_pinctrl_pinmux_sam.h"
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
/** @cond INTERNAL_HIDDEN */
19+
20+
/**
21+
* @brief Structure representing the pin control settings for a SOC pin.
22+
*
23+
* This structure is used to define the pinmux and pin configuration settings
24+
* for a specific pin on the SOC. It includes information about the port, pin,
25+
* function, bias, drive, and other configuration options.
26+
*/
27+
typedef struct pinctrl_soc_pin {
28+
/** Pinmux settings (port, pin and function). */
29+
uint16_t pinmux;
30+
/** Pin configuration (bias, drive etc). */
31+
uint16_t pinflag;
32+
} pinctrl_soc_pin_t;
33+
34+
/**
35+
* @brief Utility macro to initialize pinmux field.
36+
*
37+
* @param node_id Node identifier.
38+
*/
39+
#define Z_PINCTRL_MCHP_PINMUX_INIT(node_id, prop, idx) DT_PROP_BY_IDX(node_id, prop, idx)
40+
41+
/**
42+
* @brief Utility macro to initialize each pin.
43+
*
44+
* @param node_id Node identifier.
45+
* @param prop Property name.
46+
* @param idx Property entry index.
47+
*/
48+
#define Z_PINCTRL_MCHP_PINFLAG_INIT(node_id, prop, idx) \
49+
((DT_PROP(node_id, bias_pull_up) << MCHP_PINCTRL_PULLUP_POS) | \
50+
(DT_PROP(node_id, bias_pull_down) << MCHP_PINCTRL_PULLDOWN_POS) | \
51+
(DT_PROP(node_id, input_enable) << MCHP_PINCTRL_INPUTENABLE_POS) | \
52+
(DT_PROP(node_id, output_enable) << MCHP_PINCTRL_OUTPUTENABLE_POS) | \
53+
(DT_ENUM_IDX(node_id, drive_strength) << MCHP_PINCTRL_DRIVESTRENGTH_POS)),
54+
55+
/**
56+
* @brief Utility macro to initialize each pin.
57+
*
58+
* @param node_id Node identifier.
59+
* @param prop Property name.
60+
* @param idx Property entry index.
61+
*/
62+
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
63+
{.pinmux = Z_PINCTRL_MCHP_PINMUX_INIT(node_id, prop, idx), \
64+
.pinflag = Z_PINCTRL_MCHP_PINFLAG_INIT(node_id, prop, idx)},
65+
66+
/**
67+
* @brief Utility macro to initialize state pins contained in a given property.
68+
*
69+
* @param node_id Node identifier.
70+
* @param prop Property name describing state pins.
71+
*/
72+
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
73+
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \
74+
Z_PINCTRL_STATE_PIN_INIT)}
75+
76+
/** @endcond */
77+
78+
/**
79+
* @brief Pin flags/attributes
80+
* @anchor MCHP_PINFLAGS
81+
*
82+
* @{
83+
*/
84+
85+
#define MCHP_PINCTRL_FLAGS_DEFAULT (0U)
86+
#define MCHP_PINCTRL_FLAGS_POS (0U)
87+
#define MCHP_PINCTRL_FLAGS_MASK (0x3F << MCHP_PINCTRL_FLAGS_POS)
88+
#define MCHP_PINCTRL_FLAG_MASK (1U)
89+
#define MCHP_PINCTRL_PULLUP_POS (MCHP_PINCTRL_FLAGS_POS)
90+
#define MCHP_PINCTRL_PULLUP (1U << MCHP_PINCTRL_PULLUP_POS)
91+
#define MCHP_PINCTRL_PULLDOWN_POS (MCHP_PINCTRL_PULLUP_POS + 1U)
92+
#define MCHP_PINCTRL_PULLDOWN (1U << MCHP_PINCTRL_PULLDOWN_POS)
93+
#define MCHP_PINCTRL_OPENDRAIN_POS (MCHP_PINCTRL_PULLDOWN_POS + 1U)
94+
#define MCHP_PINCTRL_OPENDRAIN (1U << MCHP_PINCTRL_OPENDRAIN_POS)
95+
#define MCHP_PINCTRL_INPUTENABLE_POS (MCHP_PINCTRL_OPENDRAIN_POS + 1U)
96+
#define MCHP_PINCTRL_INPUTENABLE (1U << MCHP_PINCTRL_INPUTENABLE_POS)
97+
#define MCHP_PINCTRL_OUTPUTENABLE_POS (MCHP_PINCTRL_INPUTENABLE_POS + 1U)
98+
#define MCHP_PINCTRL_OUTPUTENABLE (1U << MCHP_PINCTRL_OUTPUTENABLE_POS)
99+
#define MCHP_PINCTRL_DRIVESTRENGTH_POS (MCHP_PINCTRL_OUTPUTENABLE_POS + 1U)
100+
#define MCHP_PINCTRL_DRIVESTRENGTH (1U << MCHP_PINCTRL_DRIVESTRENGTH_POS)
101+
102+
/** @} */
103+
104+
#ifdef __cplusplus
105+
}
106+
#endif
107+
108+
#endif /* SOC_MICROCHIP_SAM_D5X_E5X_COMMON_PINCTRL_SOC_H_ */

0 commit comments

Comments
 (0)