Commit d549af46 authored by Camille BAUD's avatar Camille BAUD Committed by Benjamin Cabé
Browse files

drivers: pinctrl: Introduce WCH CH32V20x/30x pinctrl Driver



This introduces the picntrl driver and partial bindings for
WCH CH32 V20x and V30x series

Signed-off-by: default avatarCamille BAUD <mail@massdriver.space>
parent 2e23dfd4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -46,5 +46,6 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_MEC5 pinctrl_mchp_mec5.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_AFIO pinctrl_wch_afio.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_SY1XX pinctrl_sy1xx.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_REALTEK_RTS5912 pinctrl_realtek_rts5912.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_20X_30X_AFIO pinctrl_wch_20x_30x_afio.c)

add_subdirectory(renesas)
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ source "drivers/pinctrl/Kconfig.mec5"
source "drivers/pinctrl/Kconfig.wch_afio"
source "drivers/pinctrl/Kconfig.sy1xx"
source "drivers/pinctrl/Kconfig.realtek_rts5912"
source "drivers/pinctrl/Kconfig.wch_20x_30x_afio"

rsource "renesas/Kconfig"

+9 −0
Original line number Diff line number Diff line
# Copyright (c) 2024 MASSDRIVER EI (massdriver.sapce)
# SPDX-License-Identifier: Apache-2.0

config PINCTRL_WCH_20X_30X_AFIO
	bool "WCH AFIO pin controller driver for CH32V20x/30x"
	default y
	depends on DT_HAS_WCH_20X_30X_AFIO_ENABLED
	help
	  WCH CH32V20x/30x AFIO pin controller driver.
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2024 MASSDRIVER EI (massdriver.space)
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/pinctrl.h>
#include <zephyr/dt-bindings/pinctrl/ch32v20x_30x-pinctrl.h>

#include <ch32fun.h>

static GPIO_TypeDef *const wch_afio_pinctrl_regs[] = {
	(GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpioa)),
	(GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpiob)),
	(GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpioc)),
	(GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpiod)),
#if DT_NODE_EXISTS(DT_NODELABEL(gpioe))
	(GPIO_TypeDef *)DT_REG_ADDR(DT_NODELABEL(gpioe)),
#endif
};

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
{
	int i;

	for (i = 0; i < pin_cnt; i++, pins++) {
		uint8_t port = FIELD_GET(CH32V20X_V30X_PINCTRL_PORT_MASK, pins->config);
		uint8_t pin = FIELD_GET(CH32V20X_V30X_PINCTRL_PIN_MASK, pins->config);
		uint8_t bit0 = FIELD_GET(CH32V20X_V30X_PINCTRL_RM_BASE_MASK, pins->config);
		uint8_t pcfr_id = FIELD_GET(CH32V20X_V30X_PINCTRL_PCFR_ID_MASK, pins->config);
		uint8_t remap = FIELD_GET(CH32V20X_V30X_PINCTRL_RM_MASK, pins->config);
		GPIO_TypeDef *regs = wch_afio_pinctrl_regs[port];
		uint32_t pcfr = pcfr_id == 0 ? AFIO->PCFR1 : AFIO->PCFR2;
		uint8_t cfg = 0;

		if (pins->output_high || pins->output_low) {
			cfg |= (pins->slew_rate + 1);
			if (pins->drive_open_drain) {
				cfg |= BIT(2);
			}
			/* Select the alternate function */
			cfg |= BIT(3);
		} else {
			if (pins->bias_pull_up || pins->bias_pull_down) {
				cfg |= BIT(3);
			}
		}

		if (pin < 8) {
			regs->CFGLR = (regs->CFGLR & ~(0x0F << (pin * 4))) | (cfg << (pin * 4));
		} else {
			regs->CFGHR = (regs->CFGHR & ~(0x0F << ((pin - 8) * 4))) |
				      (cfg << ((pin - 8) * 4));
		}
		if (pins->output_high) {
			regs->OUTDR |= BIT(pin);
			regs->BSHR |= BIT(pin);
		} else if (pins->output_low) {
			regs->OUTDR |= BIT(pin);
			/* Reset the pin. */
			regs->BSHR |= BIT(pin + 16);
		} else {
			regs->OUTDR &= ~BIT(pin);
			if (pins->bias_pull_up) {
				regs->BSHR = BIT(pin);
			}
			if (pins->bias_pull_down) {
				regs->BCR = BIT(pin);
			}
		}

		pcfr |= remap << bit0;

		if (pcfr_id == 0) {
			AFIO->PCFR1 = pcfr;
		} else {
			AFIO->PCFR2 = pcfr;
		}

		if (bit0 == CH32V20X_V30X_PINMUX_USART1_RM) {
			pcfr = AFIO->PCFR2;
			pcfr |= ((uint32_t)((remap >> 1) & 1)
				 << (CH32V20X_V30X_PINMUX_USART1_RM1 & 0x1F));
			AFIO->PCFR2 = pcfr;
		}
	}

	return 0;
}
+52 −0
Original line number Diff line number Diff line
# Copyright (c) 2024 Michael Hope
# SPDX-License-Identifier: Apache-2.0

description: WCH CH32V20x/30x AFIO

compatible: "wch,20x_30x-afio"

include: base.yaml

properties:
  reg:
    required: true
  "#address-cells":
    required: true
    const: 1
  "#size-cells":
    required: true
    const: 1

child-binding:
  description: |
    Each child node defines the configuration for a particular state.
  child-binding:
    description: |
      The grandchild nodes group pins that share the same pin configuration.

    include:
      - name: pincfg-node.yaml
        property-allowlist:
          - bias-high-impedance
          - bias-pull-up
          - bias-pull-down
          - drive-open-drain
          - drive-push-pull
          - output-high
          - output-low

    properties:
      slew-rate:
        type: string
        default: "max-speed-2mhz"
        enum:
          - "max-speed-10mhz"
          - "max-speed-2mhz"
          - "max-speed-50mhz"

      pinmux:
        required: true
        type: array
        description: |
          An array of pins sharing the same group properties. The pins should
          be defined using pre-defined macros.
Loading