* [PATCH v3 0/3] pinctrl: aspeed: Add AST2700 SoC1 support
@ 2026-05-15 9:37 Billy Tsai
2026-05-15 9:37 ` [PATCH v3 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl Billy Tsai
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Billy Tsai @ 2026-05-15 9:37 UTC (permalink / raw)
To: Linus Walleij, Tony Lindgren, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Bartosz Golaszewski,
Lee Jones, Ryan Chen
Cc: patrickw3, linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-aspeed, BMC-SW, openbmc, Andrew Jeffery, linux-clk,
Billy Tsai
Legacy ASPEED pin controllers have historically not had a coherent
register interface. Control fields often had no consistent mapping to
individual pins, and configuring a function frequently required
coordinating multiple control bits across several registers. As a
result, the existing ASPEED pinctrl drivers rely on complex macro
infrastructure to describe the dependencies between pins, functions,
and register fields.
The pin controller for SoC1 in the AST2700 breaks from this legacy
design.
For SoC1, each pin maps directly to a dedicated function field in the
SCU register space that determines the active mux function for that
pin. This results in a much more regular register layout compared to
previous generations.
While the behaviour is conceptually similar to pinctrl-single, the
register layout and configuration model differ enough that reusing
pinctrl-single directly is not practical. Therefore this driver is
implemented as a SoC-specific pinctrl driver using static data tables
to describe the register layout.
The binding reuses the standard pinmux and generic pin configuration
schemas and does not introduce any custom Devicetree properties.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
Changes in v3:
- Added pin configuration group support for AST2700 SoC1 by
implementing `pin_config_group_get()` and `pin_config_group_set()`.
- Restricted AST2700 SoC1 `drive-strength` settings to the supported
4/8/12/16 mA values in the pinctrl driver.
- Convert kernel-doc comment for aspeed_g7_soc1_drv_map to a regular
comment to avoid kernel-doc warning reported by kernel test robot.
- Update the AST2700 SoC1 pinctrl binding to describe the `reg`
property and require it.
- Allow standard pinconf properties in pin state nodes.
- Add a binding example for the AST2700 SoC1 pinctrl node.
- Add state-node description, function+groups dependency constraint,
and oneOf groups/pins constraint to the binding, matching the SoC0
binding style.
- Add pins enum (212 entries) to the binding to cover all physical pins
that support per-pin configuration.
- Add UART modem-line signals as independent functions/groups:
NCTS0/1/5/6, NDCD0/1/5/6, NDSR0/1/5/6, NDTR0/1/5/6,
NRI0/1/5/6, NRTS0/1/5/6; remove those pins from UART0/1/5/6 groups.
- Add LTPI_PS_I2C0/1/2/3 functions/groups for I2C-over-LTPI;
extend I2C0/1/2/3 functions with the new LTPI groups.
- Fix typo: rename RMII0RCKO/RMII1RCKO to RMII0RCLKO/RMII1RCLKO.
- Fix wrong index: rename DSGPM1 to DSGPM0.
- Kconfig: use "Aspeed G7 SoC1 pin control" to match neighbouring entries.
- pin_config_get: fix BIAS_DISABLE readback (val=!val must be skipped
for BIAS_DISABLE since hardware bit=1 means pull disabled).
- set_mux: remove dead null check on grp; propagate regmap_update_bits()
return value.
- gpio_request_enable: propagate regmap_update_bits() return value.
- Link to v2: https://lore.kernel.org/r/20260306-pinctrl-single-bit-v2-0-79918cfab641@aspeedtech.com
Changes in v2:
- Updated the series title to focus on AST2700 SoC1 support.
- Reworked implementation to use static SoC-specific layout tables
instead of a generic packed-field model.
- Dropped the generic "pinctrl-packed" driver approach.
- Removed custom Devicetree properties.
- Updated binding to reuse standard pinmux and generic pin
configuration schemas.
- Link to v1: https://lore.kernel.org/r/20260213-pinctrl-single-bit-v1-0-c60f2fb80efb@aspeedtech.com
---
Billy Tsai (3):
dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl
dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl
pinctrl: aspeed: Add AST2700 SoC1 support
.../bindings/mfd/aspeed,ast2x00-scu.yaml | 1 +
.../pinctrl/aspeed,ast2700-soc1-pinctrl.yaml | 760 +++++++++
drivers/pinctrl/aspeed/Kconfig | 14 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c | 1732 ++++++++++++++++++++
5 files changed, 2508 insertions(+)
---
base-commit: e532a5a81d0db872acd2c0a92d2639580ca3da44
change-id: 20260211-pinctrl-single-bit-da213f282c95
Best regards,
--
Billy Tsai <billy_tsai@aspeedtech.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl
2026-05-15 9:37 [PATCH v3 0/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
@ 2026-05-15 9:37 ` Billy Tsai
2026-05-15 9:37 ` [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl Billy Tsai
2026-05-15 9:37 ` [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2 siblings, 0 replies; 6+ messages in thread
From: Billy Tsai @ 2026-05-15 9:37 UTC (permalink / raw)
To: Linus Walleij, Tony Lindgren, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Bartosz Golaszewski,
Lee Jones, Ryan Chen
Cc: patrickw3, linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-aspeed, BMC-SW, openbmc, Andrew Jeffery, linux-clk,
Billy Tsai
The AST2700 SoC integrates two interconnected SoC instances, each
managed by its own System Control Unit (SCU).
Allow the AST2700 SoC1 pin controller to be described as a child
node of the SCU by extending the compatible strings accepted by
the SCU binding.
There is no functional change to the SCU binding beyond permitting
the aspeed,ast2700-soc1-pinctrl compatible string.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
Note: The companion AST2700 SoC0 pinctrl series modifies the same
binding and has been applied to pinctrl/for-next. Linus Walleij noted
for the equivalent SoC0 MFD patch that it should be applied through the
MFD tree by Lee Jones, providing an Acked-by in the process [1]. The
same routing applies to this patch.
[1] https://lore.kernel.org/all/CAD++jL=3p9BvDgaot3=emM4Zn5jU-ZAUKtB4UwT1HzDiyzKq4Q@mail.gmail.com/
---
Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
index a87f31fce019..b81c561d2a8c 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
+++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
@@ -87,6 +87,7 @@ patternProperties:
- aspeed,ast2400-pinctrl
- aspeed,ast2500-pinctrl
- aspeed,ast2600-pinctrl
+ - aspeed,ast2700-soc1-pinctrl
required:
- compatible
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl
2026-05-15 9:37 [PATCH v3 0/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2026-05-15 9:37 ` [PATCH v3 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl Billy Tsai
@ 2026-05-15 9:37 ` Billy Tsai
2026-05-15 10:08 ` sashiko-bot
2026-05-15 9:37 ` [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2 siblings, 1 reply; 6+ messages in thread
From: Billy Tsai @ 2026-05-15 9:37 UTC (permalink / raw)
To: Linus Walleij, Tony Lindgren, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Bartosz Golaszewski,
Lee Jones, Ryan Chen
Cc: patrickw3, linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-aspeed, BMC-SW, openbmc, Andrew Jeffery, linux-clk,
Billy Tsai
SoC1 in the AST2700 integrates its own pin controller responsible for
pin multiplexing and pin configuration.
The controller manages various peripheral functions such as eSPI, LPC,
VPI, SD, UART, I2C, I3C, PWM and others through SCU registers.
The binding reuses the standard pinmux and generic pin configuration
schemas and does not introduce custom Devicetree properties.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../pinctrl/aspeed,ast2700-soc1-pinctrl.yaml | 760 +++++++++++++++++++++
1 file changed, 760 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
new file mode 100644
index 000000000000..76944fd14e2c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
@@ -0,0 +1,760 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2700 SoC1 Pin Controller
+
+maintainers:
+ - Billy Tsai <billy_tsai@aspeedtech.com>
+
+description:
+ The AST2700 features a dual-SoC architecture with two interconnected SoCs,
+ each having its own System Control Unit (SCU) for independent pin control.
+ This pin controller manages the pin multiplexing for SoC1.
+
+ The SoC1 pin controller manages pin functions including eSPI, LPC and I2C,
+ among others.
+
+properties:
+ compatible:
+ const: aspeed,ast2700-soc1-pinctrl
+ reg:
+ maxItems: 1
+
+patternProperties:
+ '-state$':
+ description: |
+ Pin control state.
+
+ If `function` is present, the node describes a pinmux state and must
+ specify `groups`.
+
+ For pin configuration, exactly one of `groups` or `pins` must be
+ specified in each state node. Group-level configuration applies to all
+ pins in the group. Pin-level configuration may be supplied in a
+ separate state node for individual pins; when both group-level and
+ pin-level configuration apply to the same pin, the pin-level
+ configuration takes precedence.
+
+ type: object
+ allOf:
+ - $ref: pinmux-node.yaml#
+ - $ref: pincfg-node.yaml#
+ - if:
+ required:
+ - function
+ then:
+ required:
+ - groups
+ - oneOf:
+ - required:
+ - groups
+ - required:
+ - pins
+ additionalProperties: false
+
+ properties:
+ function:
+ enum:
+ - ADC0
+ - ADC1
+ - ADC10
+ - ADC11
+ - ADC12
+ - ADC13
+ - ADC14
+ - ADC15
+ - ADC2
+ - ADC3
+ - ADC4
+ - ADC5
+ - ADC6
+ - ADC7
+ - ADC8
+ - ADC9
+ - AUXPWRGOOD0
+ - AUXPWRGOOD1
+ - CANBUS
+ - ESPI0
+ - ESPI1
+ - FSI0
+ - FSI1
+ - FSI2
+ - FSI3
+ - FWQSPI
+ - FWSPIABR
+ - FWWPN
+ - HBLED
+ - I2C0
+ - I2C1
+ - I2C10
+ - I2C11
+ - I2C12
+ - I2C13
+ - I2C14
+ - I2C15
+ - I2C2
+ - I2C3
+ - I2C4
+ - I2C5
+ - I2C6
+ - I2C7
+ - I2C8
+ - I2C9
+ - I2CF0
+ - I2CF1
+ - I2CF2
+ - I3C0
+ - I3C1
+ - I3C10
+ - I3C11
+ - I3C12
+ - I3C13
+ - I3C14
+ - I3C15
+ - I3C2
+ - I3C3
+ - I3C4
+ - I3C5
+ - I3C6
+ - I3C7
+ - I3C8
+ - I3C9
+ - JTAGM1
+ - LPC0
+ - LPC1
+ - LTPI
+ - MACLINK0
+ - MACLINK1
+ - MACLINK2
+ - MDIO0
+ - MDIO1
+ - MDIO2
+ - NCTS0
+ - NCTS1
+ - NCTS5
+ - NCTS6
+ - NDCD0
+ - NDCD1
+ - NDCD5
+ - NDCD6
+ - NDSR0
+ - NDSR1
+ - NDSR5
+ - NDSR6
+ - NDTR0
+ - NDTR1
+ - NDTR5
+ - NDTR6
+ - NRI0
+ - NRI1
+ - NRI5
+ - NRI6
+ - NRTS0
+ - NRTS1
+ - NRTS5
+ - NRTS6
+ - OSCCLK
+ - PCIERC
+ - PWM0
+ - PWM1
+ - PWM10
+ - PWM11
+ - PWM12
+ - PWM13
+ - PWM14
+ - PWM15
+ - PWM2
+ - PWM3
+ - PWM4
+ - PWM5
+ - PWM6
+ - PWM7
+ - PWM8
+ - PWM9
+ - QSPI0
+ - QSPI1
+ - QSPI2
+ - RGMII0
+ - RGMII1
+ - RMII0
+ - RMII0RCLKO
+ - RMII1
+ - RMII1RCLKO
+ - SALT0
+ - SALT1
+ - SALT10
+ - SALT11
+ - SALT12
+ - SALT13
+ - SALT14
+ - SALT15
+ - SALT2
+ - SALT3
+ - SALT4
+ - SALT5
+ - SALT6
+ - SALT7
+ - SALT8
+ - SALT9
+ - SD
+ - SGMII
+ - SGPM0
+ - SGPM1
+ - SGPS
+ - SIOONCTRLN0
+ - SIOONCTRLN1
+ - SIOPBIN0
+ - SIOPBIN1
+ - SIOPBON0
+ - SIOPBON1
+ - SIOPWREQN0
+ - SIOPWREQN1
+ - SIOPWRGD1
+ - SIOS3N0
+ - SIOS3N1
+ - SIOS5N0
+ - SIOS5N1
+ - SIOSCIN0
+ - SIOSCIN1
+ - SMON0
+ - SMON1
+ - SPI0
+ - SPI0ABR
+ - SPI0CS1
+ - SPI0WPN
+ - SPI1
+ - SPI1ABR
+ - SPI1CS1
+ - SPI1WPN
+ - SPI2
+ - SPI2CS1
+ - TACH0
+ - TACH1
+ - TACH10
+ - TACH11
+ - TACH12
+ - TACH13
+ - TACH14
+ - TACH15
+ - TACH2
+ - TACH3
+ - TACH4
+ - TACH5
+ - TACH6
+ - TACH7
+ - TACH8
+ - TACH9
+ - THRU0
+ - THRU1
+ - THRU2
+ - THRU3
+ - UART0
+ - UART1
+ - UART10
+ - UART11
+ - UART2
+ - UART3
+ - UART5
+ - UART6
+ - UART7
+ - UART8
+ - UART9
+ - USB2C
+ - USB2D
+ - USBUART
+ - VGA
+ - VPI
+ - WDTRST0N
+ - WDTRST1N
+ - WDTRST2N
+ - WDTRST3N
+ - WDTRST4N
+ - WDTRST5N
+ - WDTRST6N
+ - WDTRST7N
+
+ groups:
+ enum:
+ - ADC0
+ - ADC1
+ - ADC10
+ - ADC11
+ - ADC12
+ - ADC13
+ - ADC14
+ - ADC15
+ - ADC2
+ - ADC3
+ - ADC4
+ - ADC5
+ - ADC6
+ - ADC7
+ - ADC8
+ - ADC9
+ - AUXPWRGOOD0
+ - AUXPWRGOOD1
+ - CANBUS
+ - DI2C0
+ - DI2C1
+ - DI2C10
+ - DI2C11
+ - DI2C12
+ - DI2C13
+ - DI2C14
+ - DI2C15
+ - DI2C2
+ - DI2C3
+ - DI2C8
+ - DI2C9
+ - DSGPM0
+ - ESPI0
+ - ESPI1
+ - FSI0
+ - FSI1
+ - FSI2
+ - FSI3
+ - FWQSPI
+ - FWSPIABR
+ - FWWPN
+ - HBLED
+ - HVI3C0
+ - HVI3C1
+ - HVI3C12
+ - HVI3C13
+ - HVI3C14
+ - HVI3C15
+ - HVI3C2
+ - HVI3C3
+ - I2C0
+ - I2C1
+ - I2C10
+ - I2C11
+ - I2C12
+ - I2C13
+ - I2C14
+ - I2C15
+ - I2C2
+ - I2C3
+ - I2C4
+ - I2C5
+ - I2C6
+ - I2C7
+ - I2C8
+ - I2C9
+ - I2CF0
+ - I2CF1
+ - I2CF2
+ - I3C10
+ - I3C11
+ - I3C4
+ - I3C5
+ - I3C6
+ - I3C7
+ - I3C8
+ - I3C9
+ - JTAGM1
+ - LPC0
+ - LPC1
+ - LTPI
+ - LTPI_PS_I2C0
+ - LTPI_PS_I2C1
+ - LTPI_PS_I2C2
+ - LTPI_PS_I2C3
+ - MACLINK0
+ - MACLINK1
+ - MACLINK2
+ - MDIO0
+ - MDIO1
+ - MDIO2
+ - NCTS0
+ - NCTS1
+ - NCTS5
+ - NCTS6
+ - NDCD0
+ - NDCD1
+ - NDCD5
+ - NDCD6
+ - NDSR0
+ - NDSR1
+ - NDSR5
+ - NDSR6
+ - NDTR0
+ - NDTR1
+ - NDTR5
+ - NDTR6
+ - NRI0
+ - NRI1
+ - NRI5
+ - NRI6
+ - NRTS0
+ - NRTS1
+ - NRTS5
+ - NRTS6
+ - OSCCLK
+ - PE2SGRSTN
+ - PWM0
+ - PWM1
+ - PWM10
+ - PWM11
+ - PWM12
+ - PWM13
+ - PWM14
+ - PWM15
+ - PWM2
+ - PWM3
+ - PWM4
+ - PWM5
+ - PWM6
+ - PWM7
+ - PWM8
+ - PWM9
+ - QSPI0
+ - QSPI1
+ - QSPI2
+ - RGMII0
+ - RGMII1
+ - RMII0
+ - RMII0RCLKO
+ - RMII1
+ - RMII1RCLKO
+ - SALT0
+ - SALT1
+ - SALT10
+ - SALT11
+ - SALT12
+ - SALT13
+ - SALT14
+ - SALT15
+ - SALT2
+ - SALT3
+ - SALT4
+ - SALT5
+ - SALT6
+ - SALT7
+ - SALT8
+ - SALT9
+ - SD
+ - SGMII
+ - SGPM0
+ - SGPM1
+ - SGPS
+ - SIOONCTRLN0
+ - SIOONCTRLN1
+ - SIOPBIN0
+ - SIOPBIN1
+ - SIOPBON0
+ - SIOPBON1
+ - SIOPWREQN0
+ - SIOPWREQN1
+ - SIOPWRGD1
+ - SIOS3N0
+ - SIOS3N1
+ - SIOS5N0
+ - SIOS5N1
+ - SIOSCIN0
+ - SIOSCIN1
+ - SMON0
+ - SMON1
+ - SPI0
+ - SPI0ABR
+ - SPI0CS1
+ - SPI0WPN
+ - SPI1
+ - SPI1ABR
+ - SPI1CS1
+ - SPI1WPN
+ - SPI2
+ - SPI2CS1
+ - TACH0
+ - TACH1
+ - TACH10
+ - TACH11
+ - TACH12
+ - TACH13
+ - TACH14
+ - TACH15
+ - TACH2
+ - TACH3
+ - TACH4
+ - TACH5
+ - TACH6
+ - TACH7
+ - TACH8
+ - TACH9
+ - THRU0
+ - THRU1
+ - THRU2
+ - THRU3
+ - UART0
+ - UART1
+ - UART10
+ - UART11
+ - UART2
+ - UART3
+ - UART5
+ - UART6
+ - UART7
+ - UART8
+ - UART9
+ - USB2CD
+ - USB2CH
+ - USB2CU
+ - USB2CUD
+ - USB2DD
+ - USB2DH
+ - USBUART
+ - VGA
+ - VPI
+ - WDTRST0N
+ - WDTRST1N
+ - WDTRST2N
+ - WDTRST3N
+ - WDTRST4N
+ - WDTRST5N
+ - WDTRST6N
+ - WDTRST7N
+
+ pins:
+ enum:
+ - A14
+ - A15
+ - A18
+ - A19
+ - A21
+ - A22
+ - A23
+ - A24
+ - A25
+ - A26
+ - A6
+ - A7
+ - A8
+ - AA12
+ - AA13
+ - AA14
+ - AA15
+ - AA16
+ - AA17
+ - AA18
+ - AA20
+ - AA21
+ - AA22
+ - AA23
+ - AA24
+ - AA25
+ - AA26
+ - AB15
+ - AB16
+ - AB17
+ - AB18
+ - AB19
+ - AB20
+ - AB21
+ - AB22
+ - AB23
+ - AB24
+ - AB25
+ - AB26
+ - AC15
+ - AC16
+ - AC17
+ - AC18
+ - AC19
+ - AC20
+ - AC22
+ - AC24
+ - AC25
+ - AC26
+ - AD15
+ - AD16
+ - AD17
+ - AD18
+ - AD19
+ - AD20
+ - AD22
+ - AD25
+ - AD26
+ - AE16
+ - AE17
+ - AE18
+ - AE19
+ - AE20
+ - AE21
+ - AE23
+ - AE25
+ - AE26
+ - AF16
+ - AF17
+ - AF18
+ - AF19
+ - AF20
+ - AF21
+ - AF23
+ - AF25
+ - AF26
+ - B10
+ - B11
+ - B12
+ - B13
+ - B14
+ - B15
+ - B16
+ - B18
+ - B19
+ - B21
+ - B22
+ - B23
+ - B24
+ - B25
+ - B26
+ - B6
+ - B7
+ - B8
+ - B9
+ - C10
+ - C11
+ - C12
+ - C13
+ - C14
+ - C15
+ - C16
+ - C17
+ - C18
+ - C19
+ - C20
+ - C23
+ - C26
+ - C6
+ - C7
+ - C8
+ - C9
+ - D10
+ - D12
+ - D14
+ - D15
+ - D19
+ - D20
+ - D24
+ - D26
+ - D7
+ - D8
+ - D9
+ - E10
+ - E11
+ - E12
+ - E13
+ - E14
+ - E26
+ - E7
+ - E8
+ - E9
+ - F10
+ - F11
+ - F12
+ - F13
+ - F14
+ - F26
+ - F7
+ - F8
+ - F9
+ - G10
+ - G11
+ - G7
+ - G8
+ - G9
+ - H10
+ - H11
+ - H7
+ - H8
+ - H9
+ - J10
+ - J11
+ - J12
+ - J13
+ - J9
+ - K12
+ - K13
+ - L12
+ - M13
+ - M14
+ - M15
+ - M16
+ - N13
+ - N14
+ - N15
+ - N25
+ - N26
+ - P13
+ - P14
+ - P25
+ - P26
+ - R14
+ - R25
+ - R26
+ - T23
+ - T24
+ - U21
+ - U22
+ - U25
+ - U26
+ - V14
+ - V16
+ - V17
+ - V18
+ - V19
+ - V20
+ - V21
+ - V22
+ - V23
+ - V24
+ - W14
+ - W16
+ - W17
+ - W18
+ - W20
+ - W21
+ - W22
+ - W25
+ - W26
+ - Y11
+ - Y15
+ - Y16
+ - Y17
+ - Y18
+ - Y20
+ - Y21
+ - Y22
+ - Y23
+ - Y24
+ - Y25
+ - Y26
+
+ drive-strength:
+ enum: [4, 8, 12, 16]
+
+ bias-disable: true
+ bias-pull-up: true
+ bias-pull-down: true
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: pinctrl.yaml#
+
+additionalProperties: false
+
+examples:
+ - |
+ pinctrl@400 {
+ compatible = "aspeed,ast2700-soc1-pinctrl";
+ reg = <0x400 0x2A0>;
+ sgpm0-state {
+ function = "SGPM0";
+ groups = "SGPM0";
+ };
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support
2026-05-15 9:37 [PATCH v3 0/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2026-05-15 9:37 ` [PATCH v3 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl Billy Tsai
2026-05-15 9:37 ` [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl Billy Tsai
@ 2026-05-15 9:37 ` Billy Tsai
2026-05-15 10:40 ` sashiko-bot
2 siblings, 1 reply; 6+ messages in thread
From: Billy Tsai @ 2026-05-15 9:37 UTC (permalink / raw)
To: Linus Walleij, Tony Lindgren, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Bartosz Golaszewski,
Lee Jones, Ryan Chen
Cc: patrickw3, linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-aspeed, BMC-SW, openbmc, Andrew Jeffery, linux-clk,
Billy Tsai
Implement pin multiplexing (and pin configuration where applicable)
for the AST2700 SoC1 SCU pinctrl block using static SoC data tables.
Unlike legacy ASPEED pin controllers, the SoC1 pin function control
fields are highly regular, which makes it practical to describe the
packed-field register layout directly in driver data rather than reuse
the existing Aspeed pinctrl macro infrastructure.
The driver uses the generic pinctrl, pinmux and pinconf frameworks.
The controller registers are accessed via regmap from the parent
syscon, allowing shared ownership of the SCU register block.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/pinctrl/aspeed/Kconfig | 14 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c | 1732 +++++++++++++++++++++++
3 files changed, 1747 insertions(+)
diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig
index f9672cca891e..8e1d4da0891d 100644
--- a/drivers/pinctrl/aspeed/Kconfig
+++ b/drivers/pinctrl/aspeed/Kconfig
@@ -40,3 +40,17 @@ config PINCTRL_ASPEED_G7_SOC0
Say Y here to enable pin controller support for the SoC0 instance
of Aspeed's 7th generation SoCs. GPIO is provided by a separate
GPIO driver.
+
+config PINCTRL_ASPEED_G7_SOC1
+ bool "Aspeed G7 SoC1 pin control"
+ depends on (ARCH_ASPEED || COMPILE_TEST) && OF
+ select MFD_SYSCON
+ select PINMUX
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINMUX_FUNCTIONS
+ select GENERIC_PINCONF
+ select REGMAP_MMIO
+ help
+ Say Y here to enable pin controller support for the SoC1 instance
+ of Aspeed's 7th generation SoCs. GPIO is provided by a separate
+ GPIO driver.
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index 0de524ca2c72..7a41ca45c6ba 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_PINCTRL_ASPEED_G4) += pinctrl-aspeed-g4.o
obj-$(CONFIG_PINCTRL_ASPEED_G5) += pinctrl-aspeed-g5.o
obj-$(CONFIG_PINCTRL_ASPEED_G6) += pinctrl-aspeed-g6.o
obj-$(CONFIG_PINCTRL_ASPEED_G7_SOC0) += pinctrl-aspeed-g7-soc0.o
+obj-$(CONFIG_PINCTRL_ASPEED_G7_SOC1) += pinctrl-aspeed-g7-soc1.o
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
new file mode 100644
index 000000000000..09d41ad4e52d
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
@@ -0,0 +1,1732 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Pinctrl driver for Aspeed G7 SoC1
+ *
+ * Copyright (C) 2026 Aspeed Technology Inc.
+ */
+
+#include <linux/errno.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "../pinctrl-utils.h"
+#include "../pinmux.h"
+
+#define ASPEED_G7_SOC1_NR_PINS 220
+#define ASPEED_G7_SOC1_REG_WIDTH 32
+#define ASPEED_G7_SOC1_REG_STRIDE 4
+
+#define ASPEED_G7_SOC1_MUX_BASE 0x400
+#define ASPEED_G7_SOC1_BIAS_BASE 0x480
+#define ASPEED_G7_SOC1_DRV_BASE 0x4C0
+#define ASPEED_G7_SOC1_PCIE_REG 0x908
+#define ASPEED_G7_SOC1_USB_MODE_REG 0x3B0
+
+#define ASPEED_G7_SOC1_MUX_FUNC_MASK 0x7
+#define ASPEED_G7_SOC1_MUX_BITS_PER_PIN 4
+#define ASPEED_G7_SOC1_MUX_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_MUX_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_BIAS_FUNC_MASK 0x1
+#define ASPEED_G7_SOC1_BIAS_BITS_PER_PIN 1
+#define ASPEED_G7_SOC1_BIAS_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_BIAS_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_DRV_FUNC_MASK 0x3
+#define ASPEED_G7_SOC1_DRV_BITS_PER_PIN 2
+#define ASPEED_G7_SOC1_DRV_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_DRV_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA 4
+#define ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE 1
+#define ASPEED_G7_SOC1_DRV_STRENGTH_MIN_MA \
+ (ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE * ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+#define ASPEED_G7_SOC1_DRV_STRENGTH_MAX_MA \
+ ((ASPEED_G7_SOC1_DRV_FUNC_MASK + ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE) * \
+ ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+
+/*
+ * NOTE: The numeric values of these enum entries are significant.
+ * They must match the SoC GPIO numbering / ball-to-GPIO ID mapping.
+ * Do not reorder alphabetically.
+ */
+enum {
+ C16,
+ C14,
+ C11,
+ D9,
+ F14,
+ D10,
+ C12,
+ C13,
+ AC26,
+ AA25,
+ AB23,
+ U22,
+ V21,
+ N26,
+ P25,
+ N25,
+ V23,
+ W22,
+ AB26,
+ AD26,
+ P26,
+ AE26,
+ AF26,
+ AF25,
+ AE25,
+ AD25,
+ AF23,
+ AF20,
+ AF21,
+ AE21,
+ AE23,
+ AD22,
+ AF17,
+ AA16,
+ Y16,
+ V17,
+ J13,
+ AB16,
+ AC16,
+ AF16,
+ AA15,
+ AB15,
+ AC15,
+ AD15,
+ Y15,
+ AA14,
+ W16,
+ V16,
+ AB18,
+ AC18,
+ K13,
+ AA17,
+ AB17,
+ AD16,
+ AC17,
+ AD17,
+ AE16,
+ AE17,
+ AB24,
+ W26,
+ HOLE0,
+ HOLE1,
+ HOLE2,
+ HOLE3,
+ W25,
+ Y23,
+ Y24,
+ W21,
+ AA23,
+ AC22,
+ AB22,
+ Y21,
+ AE20,
+ AF19,
+ Y22,
+ AA20,
+ AA22,
+ AB20,
+ AF18,
+ AE19,
+ AD20,
+ AC20,
+ AA21,
+ AB21,
+ AC19,
+ AE18,
+ AD19,
+ AD18,
+ U25,
+ U26,
+ Y26,
+ AA24,
+ R25,
+ AA26,
+ R26,
+ Y25,
+ B16,
+ D14,
+ B15,
+ B14,
+ C17,
+ B13,
+ E14,
+ C15,
+ D24,
+ B23,
+ B22,
+ C23,
+ B18,
+ B21,
+ M15,
+ B19,
+ B26,
+ A25,
+ A24,
+ B24,
+ E26,
+ A21,
+ A19,
+ A18,
+ D26,
+ C26,
+ A23,
+ A22,
+ B25,
+ F26,
+ A26,
+ A14,
+ E10,
+ E13,
+ D12,
+ F10,
+ E11,
+ F11,
+ F13,
+ N15,
+ C20,
+ C19,
+ A8,
+ R14,
+ A7,
+ P14,
+ D20,
+ A6,
+ B6,
+ N14,
+ B7,
+ B8,
+ B9,
+ M14,
+ J11,
+ E7,
+ D19,
+ B11,
+ D15,
+ B12,
+ B10,
+ P13,
+ C18,
+ C6,
+ C7,
+ D7,
+ N13,
+ C8,
+ C9,
+ C10,
+ M16,
+ A15,
+ G11,
+ H7,
+ H8,
+ H9,
+ H10,
+ H11,
+ J9,
+ J10,
+ E9,
+ F9,
+ F8,
+ M13,
+ F7,
+ D8,
+ E8,
+ L12,
+ F12,
+ E12,
+ J12,
+ G7,
+ G8,
+ G9,
+ G10,
+ K12,
+ W17,
+ V18,
+ W18,
+ Y17,
+ AA18,
+ AA13,
+ Y18,
+ AA12,
+ W20,
+ V20,
+ Y11,
+ V14,
+ V19,
+ W14,
+ Y20,
+ AB19,
+ U21,
+ T24,
+ V24,
+ V22,
+ T23,
+ AC25,
+ AB25,
+ AC24,
+ PCIERC2_PERST,
+ PORTC_MODE,
+ PORTD_MODE,
+ SGMII0,
+};
+
+struct aspeed_g7_soc1_pinctrl {
+ struct device *dev;
+ struct regmap *regmap;
+ struct pinctrl_dev *pctl;
+};
+
+struct aspeed_g7_field {
+ unsigned int reg;
+ unsigned int shift;
+ unsigned int mask;
+};
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_pinmux_field_from_pin(unsigned int pin)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_MUX_BASE +
+ (pin / ASPEED_G7_SOC1_MUX_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = (pin % ASPEED_G7_SOC1_MUX_PINS_PER_REG) *
+ ASPEED_G7_SOC1_MUX_BITS_PER_PIN,
+ .mask = ASPEED_G7_SOC1_MUX_FUNC_MASK,
+ };
+}
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_bias_field_from_pin(unsigned int pin)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_BIAS_BASE +
+ (pin / ASPEED_G7_SOC1_BIAS_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = pin % ASPEED_G7_SOC1_BIAS_PINS_PER_REG,
+ .mask = ASPEED_G7_SOC1_BIAS_FUNC_MASK,
+ };
+}
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_drv_field_from_idx(unsigned int idx)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_DRV_BASE +
+ (idx / ASPEED_G7_SOC1_DRV_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = (idx % ASPEED_G7_SOC1_DRV_PINS_PER_REG) *
+ ASPEED_G7_SOC1_DRV_BITS_PER_PIN,
+ .mask = ASPEED_G7_SOC1_DRV_FUNC_MASK,
+ };
+}
+
+#define PIN(n) PINCTRL_PIN(n, #n)
+
+static const struct pinctrl_pin_desc aspeed_g7_soc1_pins[] = {
+ PIN(C16),
+ PIN(C14),
+ PIN(C11),
+ PIN(D9),
+ PIN(F14),
+ PIN(D10),
+ PIN(C12),
+ PIN(C13),
+ PIN(AC26),
+ PIN(AA25),
+ PIN(AB23),
+ PIN(U22),
+ PIN(V21),
+ PIN(N26),
+ PIN(P25),
+ PIN(N25),
+ PIN(V23),
+ PIN(W22),
+ PIN(AB26),
+ PIN(AD26),
+ PIN(P26),
+ PIN(AE26),
+ PIN(AF26),
+ PIN(AF25),
+ PIN(AE25),
+ PIN(AD25),
+ PIN(AF23),
+ PIN(AF20),
+ PIN(AF21),
+ PIN(AE21),
+ PIN(AE23),
+ PIN(AD22),
+ PIN(AF17),
+ PIN(AA16),
+ PIN(Y16),
+ PIN(V17),
+ PIN(J13),
+ PIN(AB16),
+ PIN(AC16),
+ PIN(AF16),
+ PIN(AA15),
+ PIN(AB15),
+ PIN(AC15),
+ PIN(AD15),
+ PIN(Y15),
+ PIN(AA14),
+ PIN(W16),
+ PIN(V16),
+ PIN(AB18),
+ PIN(AC18),
+ PIN(K13),
+ PIN(AA17),
+ PIN(AB17),
+ PIN(AD16),
+ PIN(AC17),
+ PIN(AD17),
+ PIN(AE16),
+ PIN(AE17),
+ PIN(AB24),
+ PIN(W26),
+ PIN(HOLE0),
+ PIN(HOLE1),
+ PIN(HOLE2),
+ PIN(HOLE3),
+ PIN(W25),
+ PIN(Y23),
+ PIN(Y24),
+ PIN(W21),
+ PIN(AA23),
+ PIN(AC22),
+ PIN(AB22),
+ PIN(Y21),
+ PIN(AE20),
+ PIN(AF19),
+ PIN(Y22),
+ PIN(AA20),
+ PIN(AA22),
+ PIN(AB20),
+ PIN(AF18),
+ PIN(AE19),
+ PIN(AD20),
+ PIN(AC20),
+ PIN(AA21),
+ PIN(AB21),
+ PIN(AC19),
+ PIN(AE18),
+ PIN(AD19),
+ PIN(AD18),
+ PIN(U25),
+ PIN(U26),
+ PIN(Y26),
+ PIN(AA24),
+ PIN(R25),
+ PIN(AA26),
+ PIN(R26),
+ PIN(Y25),
+ PIN(B16),
+ PIN(D14),
+ PIN(B15),
+ PIN(B14),
+ PIN(C17),
+ PIN(B13),
+ PIN(E14),
+ PIN(C15),
+ PIN(D24),
+ PIN(B23),
+ PIN(B22),
+ PIN(C23),
+ PIN(B18),
+ PIN(B21),
+ PIN(M15),
+ PIN(B19),
+ PIN(B26),
+ PIN(A25),
+ PIN(A24),
+ PIN(B24),
+ PIN(E26),
+ PIN(A21),
+ PIN(A19),
+ PIN(A18),
+ PIN(D26),
+ PIN(C26),
+ PIN(A23),
+ PIN(A22),
+ PIN(B25),
+ PIN(F26),
+ PIN(A26),
+ PIN(A14),
+ PIN(E10),
+ PIN(E13),
+ PIN(D12),
+ PIN(F10),
+ PIN(E11),
+ PIN(F11),
+ PIN(F13),
+ PIN(N15),
+ PIN(C20),
+ PIN(C19),
+ PIN(A8),
+ PIN(R14),
+ PIN(A7),
+ PIN(P14),
+ PIN(D20),
+ PIN(A6),
+ PIN(B6),
+ PIN(N14),
+ PIN(B7),
+ PIN(B8),
+ PIN(B9),
+ PIN(M14),
+ PIN(J11),
+ PIN(E7),
+ PIN(D19),
+ PIN(B11),
+ PIN(D15),
+ PIN(B12),
+ PIN(B10),
+ PIN(P13),
+ PIN(C18),
+ PIN(C6),
+ PIN(C7),
+ PIN(D7),
+ PIN(N13),
+ PIN(C8),
+ PIN(C9),
+ PIN(C10),
+ PIN(M16),
+ PIN(A15),
+ PIN(G11),
+ PIN(H7),
+ PIN(H8),
+ PIN(H9),
+ PIN(H10),
+ PIN(H11),
+ PIN(J9),
+ PIN(J10),
+ PIN(E9),
+ PIN(F9),
+ PIN(F8),
+ PIN(M13),
+ PIN(F7),
+ PIN(D8),
+ PIN(E8),
+ PIN(L12),
+ PIN(F12),
+ PIN(E12),
+ PIN(J12),
+ PIN(G7),
+ PIN(G8),
+ PIN(G9),
+ PIN(G10),
+ PIN(K12),
+ PIN(W17),
+ PIN(V18),
+ PIN(W18),
+ PIN(Y17),
+ PIN(AA18),
+ PIN(AA13),
+ PIN(Y18),
+ PIN(AA12),
+ PIN(W20),
+ PIN(V20),
+ PIN(Y11),
+ PIN(V14),
+ PIN(V19),
+ PIN(W14),
+ PIN(Y20),
+ PIN(AB19),
+ PIN(U21),
+ PIN(T24),
+ PIN(V24),
+ PIN(V22),
+ PIN(T23),
+ PIN(AC25),
+ PIN(AB25),
+ PIN(AC24),
+ PIN(PCIERC2_PERST),
+ PIN(PORTC_MODE),
+ PIN(PORTD_MODE),
+ PIN(SGMII0),
+};
+
+static const struct pinctrl_ops aspeed_g7_soc1_pctl_ops = {
+ .get_groups_count = pinctrl_generic_get_group_count,
+ .get_group_name = pinctrl_generic_get_group_name,
+ .get_group_pins = pinctrl_generic_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+struct aspeed_g7_soc1_function {
+ struct pinfunction pinfunction;
+ const u8 *muxvals;
+};
+
+static int aspeed_g7_soc1_drive_strength_to_hw(u32 strength,
+ unsigned int *val)
+{
+ if (strength < ASPEED_G7_SOC1_DRV_STRENGTH_MIN_MA ||
+ strength > ASPEED_G7_SOC1_DRV_STRENGTH_MAX_MA ||
+ strength % ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+ return -EINVAL;
+
+ *val = (strength / ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA) -
+ ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE;
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int fselector, unsigned int group)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ const struct aspeed_g7_soc1_function *soc1_func;
+ const struct function_desc *fd;
+ const struct pinfunction *func;
+ const struct pingroup *grp;
+ struct group_desc *gd;
+ const char *gname;
+ int i, g_idx = -1, ret;
+
+ gd = pinctrl_generic_get_group(pctldev, group);
+ if (!gd)
+ return -EINVAL;
+
+ grp = &gd->grp;
+
+ fd = pinmux_generic_get_function(pctldev, fselector);
+ if (!fd)
+ return -EINVAL;
+
+ soc1_func = fd->data;
+ if (!soc1_func)
+ return -EINVAL;
+
+ func = &soc1_func->pinfunction;
+ gname = grp->name;
+
+ for (i = 0; i < func->ngroups; i++) {
+ if (!strcmp(gname, func->groups[i])) {
+ g_idx = i;
+ break;
+ }
+ }
+
+ if (g_idx < 0)
+ return -EINVAL;
+
+ for (i = 0; i < grp->npins; i++) {
+ unsigned int val = soc1_func->muxvals[g_idx];
+ unsigned int pin = grp->pins[i];
+ struct aspeed_g7_field field;
+
+ if (pin == PCIERC2_PERST) {
+ /*
+ * PCIERC2_PERST is a special case: it is managed by a
+ * dedicated control register (0x908) instead of the
+ * standard 4-bit multi-function field.
+ */
+ field.reg = ASPEED_G7_SOC1_PCIE_REG;
+ field.shift = 0;
+ field.mask = 0x1;
+ val = 1;
+ } else if (pin == PORTC_MODE || pin == PORTD_MODE) {
+ /*
+ * PORTC_MODE and PORTD_MODE are virtual "pins" that
+ * control the USB 2.0 controller mode settings.
+ * These reside in a specific control register (0x3B0)
+ * with non-standard bit widths.
+ */
+ field.reg = ASPEED_G7_SOC1_USB_MODE_REG;
+ field.mask = 0x3;
+ field.shift = pin == PORTC_MODE ? 0 : 2;
+ } else {
+ /* Standard 4-bit-per-pin multi-function configuration */
+ field = aspeed_g7_soc1_pinmux_field_from_pin(pin);
+ }
+
+ dev_dbg(pctl->dev,
+ "Setting pin %u reg 0x%x shift %u to function %s (muxval=0x%x)\n",
+ pin, field.reg, field.shift, func->name, val);
+
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift,
+ val << field.shift);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct aspeed_g7_field field;
+ int ret = -ENOTSUPP;
+
+ if (pin <= AC24) {
+ field = aspeed_g7_soc1_pinmux_field_from_pin(pin);
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift, 0);
+ }
+
+ return ret;
+}
+
+static const struct pinmux_ops aspeed_g7_soc1_pmx_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = aspeed_g7_soc1_set_mux,
+ .gpio_request_enable = aspeed_g7_soc1_gpio_request_enable,
+ .strict = true,
+};
+
+/*
+ * aspeed_g7_soc1_drv_map - Mapping table for pin drive strength control.
+ *
+ * In AST2700 SOC1, drive strength configuration is architecturally decoupled
+ * from the main pin mux registers (0x400 range). It is managed by a separate
+ * set of registers starting at 0x4C0.
+ *
+ * This table is required because:
+ * 1. The mapping between physical pin IDs and drive strength control slots
+ * is non-linear and sparse.
+ * For example, W25 maps to field index 8 (stored as 9),
+ * meaning it occupies bits [17:16] of the first 0x4C0 register.
+ * 2. Only a subset of physical pins supports drive strength configuration.
+ *
+ * The table stores (drive strength field index + 1).
+ * The field index refers to the 2-bit drive strength field position within the
+ * 0x4C0 register range. A value of 0 indicates that the pin does not support
+ * drive strength configuration (returning -ENOTSUPP).
+ * This +1 offset allows us to rely on C's default zero-initialization for
+ * unsupported pins while avoiding compiler warnings regarding overridden
+ * initializers.
+ */
+static const int aspeed_g7_soc1_drv_map[ASPEED_G7_SOC1_NR_PINS] = {
+ [C16] = 1, [C14] = 2, [C11] = 3, [D9] = 4, [F14] = 5, [D10] = 6, [C12] = 7,
+ [C13] = 8, [W25] = 9, [Y23] = 10, [Y24] = 11, [W21] = 12, [AA23] = 13, [AC22] = 14,
+ [AB22] = 15, [Y21] = 16, [AE20] = 17, [AF19] = 18, [Y22] = 19, [AA20] = 20, [AA22] = 21,
+ [AB20] = 22, [AF18] = 23, [AE19] = 24, [AD20] = 25, [AC20] = 26, [AA21] = 27, [AB21] = 28,
+ [AC19] = 29, [AE18] = 30, [AD19] = 31, [AD18] = 32, [U25] = 33, [U26] = 34, [Y26] = 35,
+ [AA24] = 36, [R25] = 37, [AA26] = 38, [R26] = 39, [Y25] = 40, [B16] = 41, [D14] = 42,
+ [B15] = 43, [B14] = 44, [C17] = 45, [B13] = 46, [E14] = 47, [C15] = 48, [D24] = 49,
+ [B23] = 50, [B22] = 51, [C23] = 52, [B18] = 53, [B21] = 54, [M15] = 55, [B19] = 56,
+ [B26] = 57, [A25] = 58, [A24] = 59, [B24] = 60, [E26] = 61, [A21] = 62, [A19] = 63,
+ [A18] = 64, [D26] = 65, [C26] = 66, [A23] = 67, [A22] = 68, [B25] = 69, [F26] = 70,
+ [A26] = 71, [A14] = 72, [E10] = 73, [E13] = 74, [D12] = 75, [F10] = 76, [E11] = 77,
+ [F11] = 78, [F13] = 79, [N15] = 80, [C20] = 81, [C19] = 82, [A8] = 83, [R14] = 84,
+ [A7] = 85, [P14] = 86, [D20] = 87, [A6] = 88, [B6] = 89, [N14] = 90, [B7] = 91,
+ [B8] = 92, [B9] = 93, [M14] = 94, [J11] = 95, [E7] = 96, [D19] = 97, [B11] = 98,
+ [D15] = 99, [B12] = 100, [B10] = 101, [P13] = 102, [C18] = 103, [C6] = 104, [C7] = 105,
+ [D7] = 106, [N13] = 107, [C8] = 108, [C9] = 109, [C10] = 110, [M16] = 111, [A15] = 112,
+ [E9] = 113, [F9] = 114, [F8] = 115, [M13] = 116, [F7] = 117, [D8] = 118, [E8] = 119,
+ [L12] = 120,
+};
+
+static int aspeed_g7_soc1_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *config)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ struct aspeed_g7_field field;
+ unsigned int val, val_raw;
+ int ret, ds_idx;
+
+ if (pin > AC24)
+ return -EINVAL;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_DISABLE:
+ field = aspeed_g7_soc1_bias_field_from_pin(pin);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ ds_idx = aspeed_g7_soc1_drv_map[pin];
+ if (!ds_idx)
+ return -ENOTSUPP;
+ ds_idx--; /* Adjust back to 0-based hardware index */
+ field = aspeed_g7_soc1_drv_field_from_idx(ds_idx);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ ret = regmap_read(pctl->regmap, field.reg, &val_raw);
+ if (ret)
+ return ret;
+
+ val = (val_raw & (field.mask << field.shift)) >> field.shift;
+ if (param == PIN_CONFIG_DRIVE_STRENGTH)
+ val = (val + ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE) *
+ ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA;
+ else if (param != PIN_CONFIG_BIAS_DISABLE)
+ val = !val;
+
+ *config = pinconf_to_config_packed(param, val);
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct aspeed_g7_field field;
+ enum pin_config_param param;
+ int i, ret, ds_idx;
+ unsigned int val;
+ u32 arg;
+
+ if (pin > AC24)
+ return -EINVAL;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_DISABLE:
+ field = aspeed_g7_soc1_bias_field_from_pin(pin);
+ val = (param == PIN_CONFIG_BIAS_DISABLE) ? 1 : 0;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ ds_idx = aspeed_g7_soc1_drv_map[pin];
+ if (!ds_idx)
+ return -ENOTSUPP;
+ ds_idx--; /* Adjust back to 0-based hardware index */
+ field = aspeed_g7_soc1_drv_field_from_idx(ds_idx);
+ ret = aspeed_g7_soc1_drive_strength_to_hw(arg, &val);
+ if (ret)
+ return ret;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ dev_dbg(pctl->dev,
+ "Configuring pin %u reg 0x%x shift %u param %d arg %u val 0x%x\n",
+ pin, field.reg, field.shift, param, arg, val);
+
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift,
+ val << field.shift);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *npins)
+{
+ struct group_desc *group;
+
+ group = pinctrl_generic_get_group(pctldev, selector);
+ if (!group)
+ return -EINVAL;
+
+ if (!group->grp.npins)
+ return -ENODEV;
+
+ *pins = group->grp.pins;
+ *npins = group->grp.npins;
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_pin_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *config)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+
+ ret = aspeed_g7_soc1_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ return aspeed_g7_soc1_pin_config_get(pctldev, pins[0], config);
+}
+
+static int aspeed_g7_soc1_pin_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+ int i;
+
+ ret = aspeed_g7_soc1_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < npins; i++) {
+ ret = aspeed_g7_soc1_pin_config_set(pctldev, pins[i], configs,
+ num_configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops aspeed_g7_soc1_conf_ops = {
+ .is_generic = true,
+ .pin_config_get = aspeed_g7_soc1_pin_config_get,
+ .pin_config_set = aspeed_g7_soc1_pin_config_set,
+ .pin_config_group_get = aspeed_g7_soc1_pin_config_group_get,
+ .pin_config_group_set = aspeed_g7_soc1_pin_config_group_set,
+ .pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static const struct pinctrl_desc aspeed_g7_soc1_desc = {
+ .name = "aspeed-g7-soc1-pinctrl",
+ .pins = aspeed_g7_soc1_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc1_pins),
+ .pctlops = &aspeed_g7_soc1_pctl_ops,
+ .pmxops = &aspeed_g7_soc1_pmx_ops,
+ .confops = &aspeed_g7_soc1_conf_ops,
+ .owner = THIS_MODULE,
+};
+
+ #define PIN_GROUP(name, ...) static const unsigned int name ## _pins[] = { __VA_ARGS__ }
+
+/* Pin Groups and Functions */
+PIN_GROUP(ADC0, W17);
+PIN_GROUP(ADC1, V18);
+PIN_GROUP(ADC10, Y11);
+PIN_GROUP(ADC11, V14);
+PIN_GROUP(ADC12, V19);
+PIN_GROUP(ADC13, W14);
+PIN_GROUP(ADC14, Y20);
+PIN_GROUP(ADC15, AB19);
+PIN_GROUP(ADC2, W18);
+PIN_GROUP(ADC3, Y17);
+PIN_GROUP(ADC4, AA18);
+PIN_GROUP(ADC5, AA13);
+PIN_GROUP(ADC6, Y18);
+PIN_GROUP(ADC7, AA12);
+PIN_GROUP(ADC8, W20);
+PIN_GROUP(ADC9, V20);
+PIN_GROUP(AUXPWRGOOD0, W14);
+PIN_GROUP(AUXPWRGOOD1, Y20);
+PIN_GROUP(CANBUS, G7, G8, G9);
+PIN_GROUP(DI2C0, C16, D9);
+PIN_GROUP(DI2C1, C14, F14);
+PIN_GROUP(DI2C10, R25, AA26);
+PIN_GROUP(DI2C11, R26, Y25);
+PIN_GROUP(DI2C12, W25, Y23);
+PIN_GROUP(DI2C13, Y24, W21);
+PIN_GROUP(DI2C14, AA23, AC22);
+PIN_GROUP(DI2C15, AB22, Y21);
+PIN_GROUP(DI2C2, D10, C12);
+PIN_GROUP(DI2C3, C11, C13);
+PIN_GROUP(DI2C8, U25, U26);
+PIN_GROUP(DI2C9, Y26, AA24);
+PIN_GROUP(DSGPM0, D19, B10, C7, D7);
+PIN_GROUP(ESPI0, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(ESPI1, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(FSI0, AD20, AC20);
+PIN_GROUP(FSI1, AA21, AB21);
+PIN_GROUP(FSI2, AC19, AE18);
+PIN_GROUP(FSI3, AD19, AD18);
+PIN_GROUP(FWQSPI, M16, A15);
+PIN_GROUP(FWSPIABR, A14);
+PIN_GROUP(FWWPN, N15);
+PIN_GROUP(HBLED, V24);
+PIN_GROUP(HVI3C0, U25, U26);
+PIN_GROUP(HVI3C1, Y26, AA24);
+PIN_GROUP(HVI3C12, W25, Y23);
+PIN_GROUP(HVI3C13, Y24, W21);
+PIN_GROUP(HVI3C14, AA23, AC22);
+PIN_GROUP(HVI3C15, AB22, Y21);
+PIN_GROUP(HVI3C2, R25, AA26);
+PIN_GROUP(HVI3C3, R26, Y25);
+PIN_GROUP(I2C0, G11, H7);
+PIN_GROUP(I2C1, H8, H9);
+PIN_GROUP(I2C10, G8, G9);
+PIN_GROUP(I2C11, G10, K12);
+PIN_GROUP(I2C12, AC18, AA17);
+PIN_GROUP(I2C13, AB17, AD16);
+PIN_GROUP(I2C14, AC17, AD17);
+PIN_GROUP(I2C15, AE16, AE17);
+PIN_GROUP(I2C2, H10, H11);
+PIN_GROUP(I2C3, J9, J10);
+PIN_GROUP(I2C4, E9, F9);
+PIN_GROUP(I2C5, F8, M13);
+PIN_GROUP(I2C6, F7, D8);
+PIN_GROUP(I2C7, E8, L12);
+PIN_GROUP(I2C8, F12, E12);
+PIN_GROUP(I2C9, J12, G7);
+PIN_GROUP(I2CF0, F12, E12, J12, G7);
+PIN_GROUP(I2CF1, E9, F9, F8, M13);
+PIN_GROUP(I2CF2, F7, D8, E8, L12);
+PIN_GROUP(I3C10, AC19, AE18);
+PIN_GROUP(I3C11, AD19, AD18);
+PIN_GROUP(I3C4, AE20, AF19);
+PIN_GROUP(I3C5, Y22, AA20);
+PIN_GROUP(I3C6, AA22, AB20);
+PIN_GROUP(I3C7, AF18, AE19);
+PIN_GROUP(I3C8, AD20, AC20);
+PIN_GROUP(I3C9, AA21, AB21);
+PIN_GROUP(JTAGM1, D12, F10, E11, F11, F13);
+PIN_GROUP(LPC0, AF26, AF25, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(LPC1, C16, C14, C11, D9, F14, D10, C12, C13, AE16, AE17);
+PIN_GROUP(LTPI, U25, U26, Y26, AA24);
+PIN_GROUP(LTPI_PS_I2C0, G11, H7);
+PIN_GROUP(LTPI_PS_I2C1, H8, H9);
+PIN_GROUP(LTPI_PS_I2C2, H10, H11);
+PIN_GROUP(LTPI_PS_I2C3, J9, J10);
+PIN_GROUP(MACLINK0, U21);
+PIN_GROUP(MACLINK1, AC24);
+PIN_GROUP(MACLINK2, T24);
+PIN_GROUP(MDIO0, B9, M14);
+PIN_GROUP(MDIO1, C9, C10);
+PIN_GROUP(MDIO2, E10, E13);
+PIN_GROUP(NCTS0, AF17);
+PIN_GROUP(NCTS1, AA15);
+PIN_GROUP(NCTS5, V21);
+PIN_GROUP(NCTS6, AB26);
+PIN_GROUP(NDCD0, AA16);
+PIN_GROUP(NDCD1, AB15);
+PIN_GROUP(NDCD5, N26);
+PIN_GROUP(NDCD6, AD26);
+PIN_GROUP(NDSR0, Y16);
+PIN_GROUP(NDSR1, AC15);
+PIN_GROUP(NDSR5, P25);
+PIN_GROUP(NDSR6, P26);
+PIN_GROUP(NDTR0, J13);
+PIN_GROUP(NDTR1, Y15);
+PIN_GROUP(NDTR5, V23);
+PIN_GROUP(NDTR6, AF26);
+PIN_GROUP(NRI0, V17);
+PIN_GROUP(NRI1, AD15);
+PIN_GROUP(NRI5, N25);
+PIN_GROUP(NRI6, AE26);
+PIN_GROUP(NRTS0, AB16);
+PIN_GROUP(NRTS1, AA14);
+PIN_GROUP(NRTS5, W22);
+PIN_GROUP(NRTS6, AF25);
+PIN_GROUP(OSCCLK, C17);
+PIN_GROUP(PE2SGRSTN, E10, PCIERC2_PERST);
+PIN_GROUP(PWM0, AE25);
+PIN_GROUP(PWM1, AD25);
+PIN_GROUP(PWM10, AB17);
+PIN_GROUP(PWM11, AD16);
+PIN_GROUP(PWM12, AC17);
+PIN_GROUP(PWM13, AD17);
+PIN_GROUP(PWM14, AE16);
+PIN_GROUP(PWM15, AE17);
+PIN_GROUP(PWM2, AF23);
+PIN_GROUP(PWM3, AF20);
+PIN_GROUP(PWM4, AF21);
+PIN_GROUP(PWM5, AE21);
+PIN_GROUP(PWM6, AE23);
+PIN_GROUP(PWM7, AD22);
+PIN_GROUP(PWM8, K13);
+PIN_GROUP(PWM9, AA17);
+PIN_GROUP(QSPI0, C23, B18);
+PIN_GROUP(QSPI1, B24, E26);
+PIN_GROUP(QSPI2, B25, F26);
+PIN_GROUP(RGMII0, C20, C19, A8, R14, A7, P14, D20, A6, B6, N14, B7, B8);
+PIN_GROUP(RGMII1, D19, B11, D15, B12, B10, P13, C18, C6, C7, D7, N13, C8);
+PIN_GROUP(RMII0, C20, A8, R14, A7, P14, A6, B6, N14);
+PIN_GROUP(RMII0RCLKO, D20);
+PIN_GROUP(RMII1, D19, D15, B12, B10, P13, C6, C7, D7);
+PIN_GROUP(RMII1RCLKO, C18);
+PIN_GROUP(SALT0, AC17);
+PIN_GROUP(SALT1, AD17);
+PIN_GROUP(SALT10, Y18);
+PIN_GROUP(SALT11, AA12);
+PIN_GROUP(SALT12, AB26);
+PIN_GROUP(SALT13, AD26);
+PIN_GROUP(SALT14, P26);
+PIN_GROUP(SALT15, AE26);
+PIN_GROUP(SALT2, AC15);
+PIN_GROUP(SALT3, AD15);
+PIN_GROUP(SALT4, W17);
+PIN_GROUP(SALT5, V18);
+PIN_GROUP(SALT6, W18);
+PIN_GROUP(SALT7, Y17);
+PIN_GROUP(SALT8, AA18);
+PIN_GROUP(SALT9, AA13);
+PIN_GROUP(SD, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(SGMII, SGMII0);
+PIN_GROUP(SGPM0, U21, T24, V22, T23);
+PIN_GROUP(SGPM1, AC25, AB25, AB24, W26);
+PIN_GROUP(SGPS, B11, C18, N13, C8);
+PIN_GROUP(SIOONCTRLN0, AE23);
+PIN_GROUP(SIOONCTRLN1, AA15);
+PIN_GROUP(SIOPBIN0, AD25);
+PIN_GROUP(SIOPBIN1, AA16);
+PIN_GROUP(SIOPBON0, AE25);
+PIN_GROUP(SIOPBON1, AF17);
+PIN_GROUP(SIOPWREQN0, AE21);
+PIN_GROUP(SIOPWREQN1, AB16);
+PIN_GROUP(SIOPWRGD1, AB15);
+PIN_GROUP(SIOS3N0, AF20);
+PIN_GROUP(SIOS3N1, V17);
+PIN_GROUP(SIOS5N0, AF21);
+PIN_GROUP(SIOS5N1, J13);
+PIN_GROUP(SIOSCIN0, AF23);
+PIN_GROUP(SIOSCIN1, Y16);
+PIN_GROUP(SMON0, U21, T24, V22, T23);
+PIN_GROUP(SMON1, W26, AC25, AB25);
+PIN_GROUP(SPI0, D24, B23, B22);
+PIN_GROUP(SPI0ABR, M15);
+PIN_GROUP(SPI0CS1, B21);
+PIN_GROUP(SPI0WPN, B19);
+PIN_GROUP(SPI1, B26, A25, A24);
+PIN_GROUP(SPI1ABR, A19);
+PIN_GROUP(SPI1CS1, A21);
+PIN_GROUP(SPI1WPN, A18);
+PIN_GROUP(SPI2, D26, C26, A23, A22);
+PIN_GROUP(SPI2CS1, A26);
+PIN_GROUP(TACH0, AC26);
+PIN_GROUP(TACH1, AA25);
+PIN_GROUP(TACH10, AB26);
+PIN_GROUP(TACH11, AD26);
+PIN_GROUP(TACH12, P26);
+PIN_GROUP(TACH13, AE26);
+PIN_GROUP(TACH14, AF26);
+PIN_GROUP(TACH15, AF25);
+PIN_GROUP(TACH2, AB23);
+PIN_GROUP(TACH3, U22);
+PIN_GROUP(TACH4, V21);
+PIN_GROUP(TACH5, N26);
+PIN_GROUP(TACH6, P25);
+PIN_GROUP(TACH7, N25);
+PIN_GROUP(TACH8, V23);
+PIN_GROUP(TACH9, W22);
+PIN_GROUP(THRU0, AC26, AA25);
+PIN_GROUP(THRU1, AB23, U22);
+PIN_GROUP(THRU2, A19, A18);
+PIN_GROUP(THRU3, B25, F26);
+PIN_GROUP(UART0, AC16, AF16);
+PIN_GROUP(UART1, W16, V16);
+PIN_GROUP(UART2, AB18, AC18);
+PIN_GROUP(UART3, K13, AA17);
+PIN_GROUP(UART5, AB17, AD16);
+PIN_GROUP(UART6, AC17, AD17);
+PIN_GROUP(UART7, AE16, AE17);
+PIN_GROUP(UART8, M15, B19);
+PIN_GROUP(UART9, B26, A25);
+PIN_GROUP(UART10, A24, B24);
+PIN_GROUP(UART11, E26, A21);
+PIN_GROUP(USB2CD, PORTC_MODE);
+PIN_GROUP(USB2CH, PORTC_MODE);
+PIN_GROUP(USB2CU, PORTC_MODE);
+PIN_GROUP(USB2CUD, PORTC_MODE);
+PIN_GROUP(USB2DD, PORTD_MODE);
+PIN_GROUP(USB2DH, PORTD_MODE);
+PIN_GROUP(USBUART, G10, K12);
+PIN_GROUP(VGA, J11, E7);
+PIN_GROUP(VPI, C16, C14, C11, D9, F14, D10, AC26, AA25, AB23, U22, V21, N26,
+ P25, N25, V23, W22, AB26, AD26, P26, AE26, AF26, AF25, AE25, AD25,
+ AF23, AF20, AF21, AE21);
+PIN_GROUP(WDTRST0N, K13);
+PIN_GROUP(WDTRST1N, AA17);
+PIN_GROUP(WDTRST2N, AB17);
+PIN_GROUP(WDTRST3N, AD16);
+PIN_GROUP(WDTRST4N, AC25);
+PIN_GROUP(WDTRST5N, AB25);
+PIN_GROUP(WDTRST6N, AC24);
+PIN_GROUP(WDTRST7N, AB24);
+
+#define GROUP(n) PINCTRL_PINGROUP(#n, n##_pins, ARRAY_SIZE(n##_pins))
+
+static const struct pingroup aspeed_g7_soc1_groups[] = {
+ GROUP(ADC0),
+ GROUP(ADC1),
+ GROUP(ADC10),
+ GROUP(ADC11),
+ GROUP(ADC12),
+ GROUP(ADC13),
+ GROUP(ADC14),
+ GROUP(ADC15),
+ GROUP(ADC2),
+ GROUP(ADC3),
+ GROUP(ADC4),
+ GROUP(ADC5),
+ GROUP(ADC6),
+ GROUP(ADC7),
+ GROUP(ADC8),
+ GROUP(ADC9),
+ GROUP(AUXPWRGOOD0),
+ GROUP(AUXPWRGOOD1),
+ GROUP(CANBUS),
+ GROUP(DI2C0),
+ GROUP(DI2C1),
+ GROUP(DI2C10),
+ GROUP(DI2C11),
+ GROUP(DI2C12),
+ GROUP(DI2C13),
+ GROUP(DI2C14),
+ GROUP(DI2C15),
+ GROUP(DI2C2),
+ GROUP(DI2C3),
+ GROUP(DI2C8),
+ GROUP(DI2C9),
+ GROUP(DSGPM0),
+ GROUP(ESPI0),
+ GROUP(ESPI1),
+ GROUP(FSI0),
+ GROUP(FSI1),
+ GROUP(FSI2),
+ GROUP(FSI3),
+ GROUP(FWQSPI),
+ GROUP(FWSPIABR),
+ GROUP(FWWPN),
+ GROUP(HBLED),
+ GROUP(HVI3C0),
+ GROUP(HVI3C1),
+ GROUP(HVI3C12),
+ GROUP(HVI3C13),
+ GROUP(HVI3C14),
+ GROUP(HVI3C15),
+ GROUP(HVI3C2),
+ GROUP(HVI3C3),
+ GROUP(I2C0),
+ GROUP(I2C1),
+ GROUP(I2C10),
+ GROUP(I2C11),
+ GROUP(I2C12),
+ GROUP(I2C13),
+ GROUP(I2C14),
+ GROUP(I2C15),
+ GROUP(I2C2),
+ GROUP(I2C3),
+ GROUP(I2C4),
+ GROUP(I2C5),
+ GROUP(I2C6),
+ GROUP(I2C7),
+ GROUP(I2C8),
+ GROUP(I2C9),
+ GROUP(I2CF0),
+ GROUP(I2CF1),
+ GROUP(I2CF2),
+ GROUP(I3C10),
+ GROUP(I3C11),
+ GROUP(I3C4),
+ GROUP(I3C5),
+ GROUP(I3C6),
+ GROUP(I3C7),
+ GROUP(I3C8),
+ GROUP(I3C9),
+ GROUP(JTAGM1),
+ GROUP(LPC0),
+ GROUP(LPC1),
+ GROUP(LTPI),
+ GROUP(LTPI_PS_I2C0),
+ GROUP(LTPI_PS_I2C1),
+ GROUP(LTPI_PS_I2C2),
+ GROUP(LTPI_PS_I2C3),
+ GROUP(MACLINK0),
+ GROUP(MACLINK1),
+ GROUP(MACLINK2),
+ GROUP(MDIO0),
+ GROUP(MDIO1),
+ GROUP(MDIO2),
+ GROUP(NCTS0),
+ GROUP(NCTS1),
+ GROUP(NCTS5),
+ GROUP(NCTS6),
+ GROUP(NDCD0),
+ GROUP(NDCD1),
+ GROUP(NDCD5),
+ GROUP(NDCD6),
+ GROUP(NDSR0),
+ GROUP(NDSR1),
+ GROUP(NDSR5),
+ GROUP(NDSR6),
+ GROUP(NDTR0),
+ GROUP(NDTR1),
+ GROUP(NDTR5),
+ GROUP(NDTR6),
+ GROUP(NRI0),
+ GROUP(NRI1),
+ GROUP(NRI5),
+ GROUP(NRI6),
+ GROUP(NRTS0),
+ GROUP(NRTS1),
+ GROUP(NRTS5),
+ GROUP(NRTS6),
+ GROUP(OSCCLK),
+ GROUP(PE2SGRSTN),
+ GROUP(PWM0),
+ GROUP(PWM1),
+ GROUP(PWM10),
+ GROUP(PWM11),
+ GROUP(PWM12),
+ GROUP(PWM13),
+ GROUP(PWM14),
+ GROUP(PWM15),
+ GROUP(PWM2),
+ GROUP(PWM3),
+ GROUP(PWM4),
+ GROUP(PWM5),
+ GROUP(PWM6),
+ GROUP(PWM7),
+ GROUP(PWM8),
+ GROUP(PWM9),
+ GROUP(QSPI0),
+ GROUP(QSPI1),
+ GROUP(QSPI2),
+ GROUP(RGMII0),
+ GROUP(RGMII1),
+ GROUP(RMII0),
+ GROUP(RMII0RCLKO),
+ GROUP(RMII1),
+ GROUP(RMII1RCLKO),
+ GROUP(SALT0),
+ GROUP(SALT1),
+ GROUP(SALT10),
+ GROUP(SALT11),
+ GROUP(SALT12),
+ GROUP(SALT13),
+ GROUP(SALT14),
+ GROUP(SALT15),
+ GROUP(SALT2),
+ GROUP(SALT3),
+ GROUP(SALT4),
+ GROUP(SALT5),
+ GROUP(SALT6),
+ GROUP(SALT7),
+ GROUP(SALT8),
+ GROUP(SALT9),
+ GROUP(SD),
+ GROUP(SGMII),
+ GROUP(SGPM0),
+ GROUP(SGPM1),
+ GROUP(SGPS),
+ GROUP(SIOONCTRLN0),
+ GROUP(SIOONCTRLN1),
+ GROUP(SIOPBIN0),
+ GROUP(SIOPBIN1),
+ GROUP(SIOPBON0),
+ GROUP(SIOPBON1),
+ GROUP(SIOPWREQN0),
+ GROUP(SIOPWREQN1),
+ GROUP(SIOPWRGD1),
+ GROUP(SIOS3N0),
+ GROUP(SIOS3N1),
+ GROUP(SIOS5N0),
+ GROUP(SIOS5N1),
+ GROUP(SIOSCIN0),
+ GROUP(SIOSCIN1),
+ GROUP(SMON0),
+ GROUP(SMON1),
+ GROUP(SPI0),
+ GROUP(SPI0ABR),
+ GROUP(SPI0CS1),
+ GROUP(SPI0WPN),
+ GROUP(SPI1),
+ GROUP(SPI1ABR),
+ GROUP(SPI1CS1),
+ GROUP(SPI1WPN),
+ GROUP(SPI2),
+ GROUP(SPI2CS1),
+ GROUP(TACH0),
+ GROUP(TACH1),
+ GROUP(TACH10),
+ GROUP(TACH11),
+ GROUP(TACH12),
+ GROUP(TACH13),
+ GROUP(TACH14),
+ GROUP(TACH15),
+ GROUP(TACH2),
+ GROUP(TACH3),
+ GROUP(TACH4),
+ GROUP(TACH5),
+ GROUP(TACH6),
+ GROUP(TACH7),
+ GROUP(TACH8),
+ GROUP(TACH9),
+ GROUP(THRU0),
+ GROUP(THRU1),
+ GROUP(THRU2),
+ GROUP(THRU3),
+ GROUP(UART0),
+ GROUP(UART1),
+ GROUP(UART10),
+ GROUP(UART11),
+ GROUP(UART2),
+ GROUP(UART3),
+ GROUP(UART5),
+ GROUP(UART6),
+ GROUP(UART7),
+ GROUP(UART8),
+ GROUP(UART9),
+ GROUP(USB2CD),
+ GROUP(USB2CH),
+ GROUP(USB2CU),
+ GROUP(USB2CUD),
+ GROUP(USB2DD),
+ GROUP(USB2DH),
+ GROUP(USBUART),
+ GROUP(VGA),
+ GROUP(VPI),
+ GROUP(WDTRST0N),
+ GROUP(WDTRST1N),
+ GROUP(WDTRST2N),
+ GROUP(WDTRST3N),
+ GROUP(WDTRST4N),
+ GROUP(WDTRST5N),
+ GROUP(WDTRST6N),
+ GROUP(WDTRST7N),
+};
+
+/**
+ * VM() - Helper macro to unwrap a parenthesized list of arguments.
+ * @...: The parenthesized list to be unwrapped.
+ *
+ * Since the C preprocessor treats commas inside braces {} as argument
+ * separators for macros, we wrap lists (like mux values) in parentheses ()
+ * to protect them during macro expansion. This macro strips those
+ * parentheses when the values are needed for array initialization.
+ */
+#define VM(...) __VA_ARGS__
+
+/**
+ * FUNC() - Macro to initialize an aspeed_g7_soc1_function entry.
+ * @n: Name of the pin function.
+ * @m: Parenthesized list of mux values, mapped 1:1 to the groups list.
+ * @...: Variable list of pin group names associated with this function.
+ *
+ * This macro solves complex static initialization by:
+ * 1. Creating anonymous arrays for both group names and mux values
+ * using C99 Compound Literals.
+ * 2. Using VM(m) to unwrap mux values into the array initializer.
+ * 3. Calculating the number of groups via sizeof() division, which
+ * bypasses the __must_be_array() check performed by ARRAY_SIZE()
+ * that often fails on compound literals in the kernel environment.
+ *
+ * Example: FUNC(i2c0, (1, 4), "i2c0", "di2c0")
+ * Maps "i2c0" group to mux value 1 and "di2c0" group to mux value 4.
+ */
+#define FUNC(n, m, ...) \
+ { \
+ .pinfunction = { \
+ .name = #n, \
+ .groups = (const char *const[]){ __VA_ARGS__ }, \
+ .ngroups = sizeof((const char *const[]){ __VA_ARGS__ }) / sizeof(char *), \
+ }, \
+ .muxvals = (const u8[]){ VM m } \
+ }
+
+static const struct aspeed_g7_soc1_function aspeed_g7_soc1_functions[] = {
+ FUNC(ADC0, (0), "ADC0"),
+ FUNC(ADC1, (0), "ADC1"),
+ FUNC(ADC10, (0), "ADC10"),
+ FUNC(ADC11, (0), "ADC11"),
+ FUNC(ADC12, (0), "ADC12"),
+ FUNC(ADC13, (0), "ADC13"),
+ FUNC(ADC14, (0), "ADC14"),
+ FUNC(ADC15, (0), "ADC15"),
+ FUNC(ADC2, (0), "ADC2"),
+ FUNC(ADC3, (0), "ADC3"),
+ FUNC(ADC4, (0), "ADC4"),
+ FUNC(ADC5, (0), "ADC5"),
+ FUNC(ADC6, (0), "ADC6"),
+ FUNC(ADC7, (0), "ADC7"),
+ FUNC(ADC8, (0), "ADC8"),
+ FUNC(ADC9, (0), "ADC9"),
+ FUNC(AUXPWRGOOD0, (2), "AUXPWRGOOD0"),
+ FUNC(AUXPWRGOOD1, (2), "AUXPWRGOOD1"),
+ FUNC(CANBUS, (2), "CANBUS"),
+ FUNC(ESPI0, (1), "ESPI0"),
+ FUNC(ESPI1, (1), "ESPI1"),
+ FUNC(FSI0, (2), "FSI0"),
+ FUNC(FSI1, (2), "FSI1"),
+ FUNC(FSI2, (2), "FSI2"),
+ FUNC(FSI3, (2), "FSI3"),
+ FUNC(FWQSPI, (1), "FWQSPI"),
+ FUNC(FWSPIABR, (1), "FWSPIABR"),
+ FUNC(FWWPN, (1), "FWWPN"),
+ FUNC(HBLED, (2), "HBLED"),
+ FUNC(I2C0, (1, 2, 4), "I2C0", "LTPI_PS_I2C0", "DI2C0"),
+ FUNC(I2C1, (1, 2, 4), "I2C1", "LTPI_PS_I2C1", "DI2C1"),
+ FUNC(I2C10, (1, 2), "I2C10", "DI2C10"),
+ FUNC(I2C11, (1, 2), "I2C11", "DI2C11"),
+ FUNC(I2C12, (4, 2), "I2C12", "DI2C12"),
+ FUNC(I2C13, (4, 2), "I2C13", "DI2C13"),
+ FUNC(I2C14, (4, 2), "I2C14", "DI2C14"),
+ FUNC(I2C15, (2, 2), "I2C15", "DI2C15"),
+ FUNC(I2C2, (1, 2, 4), "I2C2", "LTPI_PS_I2C2", "DI2C2"),
+ FUNC(I2C3, (1, 2, 4), "I2C3", "LTPI_PS_I2C3", "DI2C3"),
+ FUNC(I2C4, (1), "I2C4"),
+ FUNC(I2C5, (1), "I2C5"),
+ FUNC(I2C6, (1), "I2C6"),
+ FUNC(I2C7, (1), "I2C7"),
+ FUNC(I2C8, (1, 2), "I2C8", "DI2C8"),
+ FUNC(I2C9, (1, 2), "I2C9", "DI2C9"),
+ FUNC(I2CF0, (5), "I2CF0"),
+ FUNC(I2CF1, (5), "I2CF1"),
+ FUNC(I2CF2, (5), "I2CF2"),
+ FUNC(I3C0, (1), "HVI3C0"),
+ FUNC(I3C1, (1), "HVI3C1"),
+ FUNC(I3C10, (1), "I3C10"),
+ FUNC(I3C11, (1), "I3C11"),
+ FUNC(I3C12, (1), "HVI3C12"),
+ FUNC(I3C13, (1), "HVI3C13"),
+ FUNC(I3C14, (1), "HVI3C14"),
+ FUNC(I3C15, (1), "HVI3C15"),
+ FUNC(I3C2, (1), "HVI3C2"),
+ FUNC(I3C3, (1), "HVI3C3"),
+ FUNC(I3C4, (1), "I3C4"),
+ FUNC(I3C5, (1), "I3C5"),
+ FUNC(I3C6, (1), "I3C6"),
+ FUNC(I3C7, (1), "I3C7"),
+ FUNC(I3C8, (1), "I3C8"),
+ FUNC(I3C9, (1), "I3C9"),
+ FUNC(JTAGM1, (1), "JTAGM1"),
+ FUNC(LPC0, (2), "LPC0"),
+ FUNC(LPC1, (2), "LPC1"),
+ FUNC(LTPI, (2), "LTPI"),
+ FUNC(MACLINK0, (4), "MACLINK0"),
+ FUNC(MACLINK1, (3), "MACLINK1"),
+ FUNC(MACLINK2, (4), "MACLINK2"),
+ FUNC(MDIO0, (1), "MDIO0"),
+ FUNC(MDIO1, (1), "MDIO1"),
+ FUNC(MDIO2, (1), "MDIO2"),
+ FUNC(NCTS0, (1), "NCTS0"),
+ FUNC(NCTS1, (1), "NCTS1"),
+ FUNC(NCTS5, (4), "NCTS5"),
+ FUNC(NCTS6, (4), "NCTS6"),
+ FUNC(NDCD0, (1), "NDCD0"),
+ FUNC(NDCD1, (1), "NDCD1"),
+ FUNC(NDCD5, (4), "NDCD5"),
+ FUNC(NDCD6, (4), "NDCD6"),
+ FUNC(NDSR0, (1), "NDSR0"),
+ FUNC(NDSR1, (1), "NDSR1"),
+ FUNC(NDSR5, (4), "NDSR5"),
+ FUNC(NDSR6, (4), "NDSR6"),
+ FUNC(NDTR0, (1), "NDTR0"),
+ FUNC(NDTR1, (1), "NDTR1"),
+ FUNC(NDTR5, (4), "NDTR5"),
+ FUNC(NDTR6, (4), "NDTR6"),
+ FUNC(NRI0, (1), "NRI0"),
+ FUNC(NRI1, (1), "NRI1"),
+ FUNC(NRI5, (4), "NRI5"),
+ FUNC(NRI6, (4), "NRI6"),
+ FUNC(NRTS0, (1), "NRTS0"),
+ FUNC(NRTS1, (1), "NRTS1"),
+ FUNC(NRTS5, (4), "NRTS5"),
+ FUNC(NRTS6, (4), "NRTS6"),
+ FUNC(OSCCLK, (3), "OSCCLK"),
+ FUNC(PCIERC, (2), "PE2SGRSTN"),
+ FUNC(PWM0, (1), "PWM0"),
+ FUNC(PWM1, (1), "PWM1"),
+ FUNC(PWM10, (3), "PWM10"),
+ FUNC(PWM11, (3), "PWM11"),
+ FUNC(PWM12, (3), "PWM12"),
+ FUNC(PWM13, (3), "PWM13"),
+ FUNC(PWM14, (3), "PWM14"),
+ FUNC(PWM15, (3), "PWM15"),
+ FUNC(PWM2, (1), "PWM2"),
+ FUNC(PWM3, (1), "PWM3"),
+ FUNC(PWM4, (1), "PWM4"),
+ FUNC(PWM5, (1), "PWM5"),
+ FUNC(PWM6, (1), "PWM6"),
+ FUNC(PWM7, (1), "PWM7"),
+ FUNC(PWM8, (3), "PWM8"),
+ FUNC(PWM9, (3), "PWM9"),
+ FUNC(QSPI0, (1), "QSPI0"),
+ FUNC(QSPI1, (1), "QSPI1"),
+ FUNC(QSPI2, (1), "QSPI2"),
+ FUNC(RGMII0, (1), "RGMII0"),
+ FUNC(RGMII1, (1), "RGMII1"),
+ FUNC(RMII0, (2), "RMII0"),
+ FUNC(RMII0RCLKO, (2), "RMII0RCLKO"),
+ FUNC(RMII1, (2), "RMII1"),
+ FUNC(RMII1RCLKO, (2), "RMII1RCLKO"),
+ FUNC(SALT0, (2), "SALT0"),
+ FUNC(SALT1, (2), "SALT1"),
+ FUNC(SALT10, (2), "SALT10"),
+ FUNC(SALT11, (2), "SALT11"),
+ FUNC(SALT12, (2), "SALT12"),
+ FUNC(SALT13, (2), "SALT13"),
+ FUNC(SALT14, (2), "SALT14"),
+ FUNC(SALT15, (2), "SALT15"),
+ FUNC(SALT2, (2), "SALT2"),
+ FUNC(SALT3, (2), "SALT3"),
+ FUNC(SALT4, (2), "SALT4"),
+ FUNC(SALT5, (2), "SALT5"),
+ FUNC(SALT6, (2), "SALT6"),
+ FUNC(SALT7, (2), "SALT7"),
+ FUNC(SALT8, (2), "SALT8"),
+ FUNC(SALT9, (2), "SALT9"),
+ FUNC(SD, (3), "SD"),
+ FUNC(SGMII, (1), "SGMII"),
+ FUNC(SGPM0, (1, 4), "SGPM0", "DSGPM0"),
+ FUNC(SGPM1, (1), "SGPM1"),
+ FUNC(SGPS, (5), "SGPS"),
+ FUNC(SIOONCTRLN0, (2), "SIOONCTRLN0"),
+ FUNC(SIOONCTRLN1, (2), "SIOONCTRLN1"),
+ FUNC(SIOPBIN0, (2), "SIOPBIN0"),
+ FUNC(SIOPBIN1, (2), "SIOPBIN1"),
+ FUNC(SIOPBON0, (2), "SIOPBON0"),
+ FUNC(SIOPBON1, (2), "SIOPBON1"),
+ FUNC(SIOPWREQN0, (2), "SIOPWREQN0"),
+ FUNC(SIOPWREQN1, (2), "SIOPWREQN1"),
+ FUNC(SIOPWRGD1, (2), "SIOPWRGD1"),
+ FUNC(SIOS3N0, (2), "SIOS3N0"),
+ FUNC(SIOS3N1, (2), "SIOS3N1"),
+ FUNC(SIOS5N0, (2), "SIOS5N0"),
+ FUNC(SIOS5N1, (2), "SIOS5N1"),
+ FUNC(SIOSCIN0, (2), "SIOSCIN0"),
+ FUNC(SIOSCIN1, (2), "SIOSCIN1"),
+ FUNC(SMON0, (2), "SMON0"),
+ FUNC(SMON1, (4), "SMON1"),
+ FUNC(SPI0, (1), "SPI0"),
+ FUNC(SPI0ABR, (1), "SPI0ABR"),
+ FUNC(SPI0CS1, (1), "SPI0CS1"),
+ FUNC(SPI0WPN, (1), "SPI0WPN"),
+ FUNC(SPI1, (1), "SPI1"),
+ FUNC(SPI1ABR, (1), "SPI1ABR"),
+ FUNC(SPI1CS1, (1), "SPI1CS1"),
+ FUNC(SPI1WPN, (1), "SPI1WPN"),
+ FUNC(SPI2, (1), "SPI2"),
+ FUNC(SPI2CS1, (1), "SPI2CS1"),
+ FUNC(TACH0, (1), "TACH0"),
+ FUNC(TACH1, (1), "TACH1"),
+ FUNC(TACH10, (1), "TACH10"),
+ FUNC(TACH11, (1), "TACH11"),
+ FUNC(TACH12, (1), "TACH12"),
+ FUNC(TACH13, (1), "TACH13"),
+ FUNC(TACH14, (1), "TACH14"),
+ FUNC(TACH15, (1), "TACH15"),
+ FUNC(TACH2, (1), "TACH2"),
+ FUNC(TACH3, (1), "TACH3"),
+ FUNC(TACH4, (1), "TACH4"),
+ FUNC(TACH5, (1), "TACH5"),
+ FUNC(TACH6, (1), "TACH6"),
+ FUNC(TACH7, (1), "TACH7"),
+ FUNC(TACH8, (1), "TACH8"),
+ FUNC(TACH9, (1), "TACH9"),
+ FUNC(THRU0, (2), "THRU0"),
+ FUNC(THRU1, (2), "THRU1"),
+ FUNC(THRU2, (4), "THRU2"),
+ FUNC(THRU3, (4), "THRU3"),
+ FUNC(UART0, (1), "UART0"),
+ FUNC(UART1, (1), "UART1"),
+ FUNC(UART10, (3), "UART10"),
+ FUNC(UART11, (3), "UART11"),
+ FUNC(UART2, (1), "UART2"),
+ FUNC(UART3, (1), "UART3"),
+ FUNC(UART5, (4), "UART5"),
+ FUNC(UART6, (4), "UART6"),
+ FUNC(UART7, (1), "UART7"),
+ FUNC(UART8, (3), "UART8"),
+ FUNC(UART9, (3), "UART9"),
+ FUNC(USB2C, (0, 1, 2, 3), "USB2CUD", "USB2CD", "USB2CH", "USB2CU"),
+ FUNC(USB2D, (1, 2), "USB2DD", "USB2DH"),
+ FUNC(USBUART, (2), "USBUART"),
+ FUNC(VGA, (1), "VGA"),
+ FUNC(VPI, (5), "VPI"),
+ FUNC(WDTRST0N, (2), "WDTRST0N"),
+ FUNC(WDTRST1N, (2), "WDTRST1N"),
+ FUNC(WDTRST2N, (2), "WDTRST2N"),
+ FUNC(WDTRST3N, (2), "WDTRST3N"),
+ FUNC(WDTRST4N, (2), "WDTRST4N"),
+ FUNC(WDTRST5N, (2), "WDTRST5N"),
+ FUNC(WDTRST6N, (2), "WDTRST6N"),
+ FUNC(WDTRST7N, (2), "WDTRST7N"),
+};
+
+static int aspeed_g7_soc1_pinctrl_probe(struct platform_device *pdev)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl;
+ struct device *dev = &pdev->dev;
+ int i, ret;
+
+ pctl = devm_kzalloc(dev, sizeof(*pctl), GFP_KERNEL);
+ if (!pctl)
+ return -ENOMEM;
+
+ pctl->dev = dev;
+ pctl->regmap = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(pctl->regmap)) {
+ dev_err(dev, "Failed to get regmap from parent\n");
+ return PTR_ERR(pctl->regmap);
+ }
+
+ pctl->pctl = devm_pinctrl_register(dev, &aspeed_g7_soc1_desc, pctl);
+ if (IS_ERR(pctl->pctl)) {
+ dev_err(dev, "Failed to register pinctrl\n");
+ return PTR_ERR(pctl->pctl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aspeed_g7_soc1_groups); i++) {
+ const struct pingroup *grp = &aspeed_g7_soc1_groups[i];
+
+ ret = pinctrl_generic_add_group(pctl->pctl, grp->name, (unsigned int *)grp->pins,
+ grp->npins, pctl);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add group %s\n", grp->name);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aspeed_g7_soc1_functions); i++) {
+ const struct aspeed_g7_soc1_function *func = &aspeed_g7_soc1_functions[i];
+
+ ret = pinmux_generic_add_function(pctl->pctl, func->pinfunction.name,
+ func->pinfunction.groups,
+ func->pinfunction.ngroups, (void *)func);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add function %s\n", func->pinfunction.name);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id aspeed_g7_soc1_pinctrl_match[] = {
+ { .compatible = "aspeed,ast2700-soc1-pinctrl" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, aspeed_g7_soc1_pinctrl_match);
+
+static struct platform_driver aspeed_g7_soc1_pinctrl_driver = {
+ .probe = aspeed_g7_soc1_pinctrl_probe,
+ .driver = {
+ .name = "aspeed-g7-soc1-pinctrl",
+ .of_match_table = aspeed_g7_soc1_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init aspeed_g7_soc1_pinctrl_init(void)
+{
+ return platform_driver_register(&aspeed_g7_soc1_pinctrl_driver);
+}
+arch_initcall(aspeed_g7_soc1_pinctrl_init);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl
2026-05-15 9:37 ` [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl Billy Tsai
@ 2026-05-15 10:08 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-05-15 10:08 UTC (permalink / raw)
To: Billy Tsai; +Cc: devicetree, conor+dt, krzk+dt, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Schema uses `additionalProperties: false` alongside `$ref` instead of `unevaluatedProperties: false`.
--
commit f22ff0791aac86f631d0cc5f4662941db457d162
Author: Billy Tsai <billy_tsai@aspeedtech.com>
dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl
This commit introduces a new devicetree binding schema for the ASPEED
AST2700 SoC1 pin controller. It reuses the standard pinmux and generic
pin configuration schemas.
> diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
> new file mode 100644
> index 0000000000000..76944fd14e2c7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc1-pinctrl.yaml
> @@ -0,0 +1,760 @@
[ ... ]
> +patternProperties:
> + '-state$':
> + description: |
> + Pin control state.
[ ... ]
> + type: object
> + allOf:
> + - $ref: pinmux-node.yaml#
> + - $ref: pincfg-node.yaml#
[ ... ]
> + - pins
> + additionalProperties: false
Since this block references pinmux-node.yaml and pincfg-node.yaml, should
this use unevaluatedProperties: false instead? Using additionalProperties:
false might cause standard properties provided by the referenced schemas to
be incorrectly rejected during validation.
> +
> + properties:
> + function:
[ ... ]
> +required:
> + - compatible
> + - reg
> +
> +allOf:
> + - $ref: pinctrl.yaml#
> +
> +additionalProperties: false
Similarly, since the root level includes a reference to pinctrl.yaml, does
this also need to be unevaluatedProperties: false?
> +
> +examples:
> + - |
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-pinctrl-single-bit-v3-0-e97da4312104@aspeedtech.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support
2026-05-15 9:37 ` [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
@ 2026-05-15 10:40 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-05-15 10:40 UTC (permalink / raw)
To: Billy Tsai; +Cc: robh, conor+dt, krzk+dt, devicetree
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Calling `devm_pinctrl_register()` before adding groups and functions breaks device tree pin hogs and exposes an initialization race.
- [High] The SGMII0 pin register offset and shift calculations are corrupted by preceding virtual pins in the enum.
- [High] `ASPEED_G7_SOC1_MUX_FUNC_MASK` is defined as 0x7 instead of 0xF, leaving the highest bit of the 4-bit mux field uncleared.
- [Medium] `aspeed_g7_soc1_pin_config_get()` violates the generic pinconf API by failing to return `-EINVAL` for inactive boolean parameters.
--
commit d166d24632d04188131a95c43f87c2fa9c723d2e
Author: Billy Tsai <billy_tsai@aspeedtech.com>
pinctrl: aspeed: Add AST2700 SoC1 support
This patch implements pin multiplexing and configuration for the AST2700
SoC1 SCU pinctrl block. It describes the packed-field register layout directly
in driver data and accesses the controller registers via regmap.
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
[ ... ]
> +#define ASPEED_G7_SOC1_MUX_FUNC_MASK 0x7
> +#define ASPEED_G7_SOC1_MUX_BITS_PER_PIN 4
Should this mask be 0xF to cover all 4 bits?
Since ASPEED_G7_SOC1_MUX_BITS_PER_PIN is 4, using 0x7 will only clear the
lower 3 bits when regmap_update_bits() is called. If the bootloader leaves
the 4th bit set, will it remain set and corrupt the pin multiplexing behavior?
[ ... ]
> + AC25,
> + AB25,
> + AC24,
> + PCIERC2_PERST,
> + PORTC_MODE,
> + PORTD_MODE,
> + SGMII0,
> +};
Since SGMII0 is placed after the virtual pins in this enum, its index becomes
219 instead of 216.
When aspeed_g7_soc1_pinmux_field_from_pin() calculates the shift using
(pin % 8) * 4, will this inflated offset skip 3 pin slots (12 bits) and
configure the wrong hardware bits for SGMII0? Would it be safer to move the
virtual pins to the end of the enum?
[ ... ]
> +static int aspeed_g7_soc1_pin_config_get(struct pinctrl_dev *pctldev,
> + unsigned int pin,
> + unsigned long *config)
> +{
[ ... ]
> + val = (val_raw & (field.mask << field.shift)) >> field.shift;
> + if (param == PIN_CONFIG_DRIVE_STRENGTH)
> + val = (val + ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE) *
> + ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA;
> + else if (param != PIN_CONFIG_BIAS_DISABLE)
> + val = !val;
> +
> + *config = pinconf_to_config_packed(param, val);
> +
> + return 0;
> +}
Does this unconditionally return 0 (success) even if the queried boolean
parameter is not currently active?
The generic pinconf subsystem expects -EINVAL if a parameter like
PIN_CONFIG_BIAS_PULL_UP or PIN_CONFIG_BIAS_DISABLE is queried but not active
on the pin. Will returning 0 cause tools like debugfs to report mutually
exclusive states as active simultaneously?
[ ... ]
> +static int aspeed_g7_soc1_pinctrl_probe(struct platform_device *pdev)
> +{
[ ... ]
> + pctl->pctl = devm_pinctrl_register(dev, &aspeed_g7_soc1_desc, pctl);
> + if (IS_ERR(pctl->pctl)) {
> + dev_err(dev, "Failed to register pinctrl\n");
> + return PTR_ERR(pctl->pctl);
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(aspeed_g7_soc1_groups); i++) {
> + const struct pingroup *grp = &aspeed_g7_soc1_groups[i];
> +
> + ret = pinctrl_generic_add_group(pctl->pctl, grp->name, (unsigned int *)grp->pins,
> + grp->npins, pctl);
Is it safe to call devm_pinctrl_register() before the groups and functions
are added to the radix trees?
devm_pinctrl_register() immediately exposes the device and parses device tree
pin hogs via pinctrl_enable(). Will any DT hogs defined for this controller
fail to apply because the internal radix trees are still empty?
Should this use devm_pinctrl_register_and_init() instead, followed by an
explicit pinctrl_enable() after populating the groups and functions?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-pinctrl-single-bit-v3-0-e97da4312104@aspeedtech.com?part=3
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-15 10:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-15 9:37 [PATCH v3 0/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2026-05-15 9:37 ` [PATCH v3 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl Billy Tsai
2026-05-15 9:37 ` [PATCH v3 2/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc1-pinctrl Billy Tsai
2026-05-15 10:08 ` sashiko-bot
2026-05-15 9:37 ` [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support Billy Tsai
2026-05-15 10:40 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox