diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index f5ab30d7e76..e357a15024c 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -23,6 +23,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_IOCON pinctrl_lpc_iocon.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_CC13XX_CC26XX pinctrl_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ESP32 pinctrl_esp32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RV32M1 pinctrl_rv32m1.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_INFINEON_CAT1 pinctrl_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_XLNX_ZYNQ pinctrl_xlnx_zynq.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SMARTBOND pinctrl_smartbond.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_XMC4XXX pinctrl_xmc4xxx.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4ad102347e6..2f491ae5090 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -52,6 +52,7 @@ source "drivers/pinctrl/Kconfig.lpc_iocon" source "drivers/pinctrl/Kconfig.cc13xx_cc26xx" source "drivers/pinctrl/Kconfig.esp32" source "drivers/pinctrl/Kconfig.rv32m1" +source "drivers/pinctrl/Kconfig.ifx_cat1" source "drivers/pinctrl/Kconfig.xlnx" source "drivers/pinctrl/Kconfig.smartbond" source "drivers/pinctrl/Kconfig.xmc4xxx" diff --git a/drivers/pinctrl/Kconfig.ifx_cat1 b/drivers/pinctrl/Kconfig.ifx_cat1 new file mode 100644 index 00000000000..d0efe3e1e47 --- /dev/null +++ b/drivers/pinctrl/Kconfig.ifx_cat1 @@ -0,0 +1,12 @@ +# Infineon CAT1 Pin controller configuration options + +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_INFINEON_CAT1 + bool "Pin controller driver for Infineon CAT1 MCUs" + default y + depends on DT_HAS_INFINEON_CAT1_PINCTRL_ENABLED + help + Enable Pin controller driver for Infineon CAT1 MCUs diff --git a/drivers/pinctrl/pinctrl_ifx_cat1.c b/drivers/pinctrl/pinctrl_ifx_cat1.c new file mode 100644 index 00000000000..8f2bbcb0e43 --- /dev/null +++ b/drivers/pinctrl/pinctrl_ifx_cat1.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Pin control driver for Infineon CAT1 MCU family. + */ + +#include +#include +#include + +#define GPIO_PORT_OR_NULL(node_id) \ + COND_CODE_1(DT_NODE_EXISTS(node_id), ((GPIO_PRT_Type *)DT_REG_ADDR(node_id)), (NULL)) + +/* @brief Array containing pointers to each GPIO port. + * + * Entries will be NULL if the GPIO port is not enabled. + */ +static GPIO_PRT_Type *const gpio_ports[] = { + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt0)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt1)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt2)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt3)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt4)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt5)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt6)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt7)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt8)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt9)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt10)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt11)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt12)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt13)), + GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt14)) +}; + +/* @brief This function returns gpio drive mode, according to. + * bias and drive mode params defined in pinctrl node. + * + * @param flags - bias and drive mode flags from pinctrl node. + */ +static uint32_t soc_gpio_get_drv_mode(uint32_t flags) +{ + uint32_t drv_mode = CY_GPIO_DM_ANALOG; + uint32_t _flags; + + _flags = ((flags & SOC_GPIO_FLAGS_MASK) >> SOC_GPIO_FLAGS_POS); + + if (_flags & SOC_GPIO_OPENDRAIN) { + /* drive_open_drain */ + drv_mode = CY_GPIO_DM_OD_DRIVESLOW_IN_OFF; + + } else if (_flags & SOC_GPIO_OPENSOURCE) { + /* drive_open_source */ + drv_mode = CY_GPIO_DM_OD_DRIVESHIGH_IN_OFF; + + } else if (_flags & SOC_GPIO_PUSHPULL) { + /* drive_push_pull */ + drv_mode = CY_GPIO_DM_STRONG_IN_OFF; + + } else if ((_flags & SOC_GPIO_PULLUP) && (_flags & SOC_GPIO_PULLDOWN)) { + /* bias_pull_up and bias_pull_down */ + drv_mode = CY_GPIO_DM_PULLUP_DOWN_IN_OFF; + + } else if (_flags & SOC_GPIO_PULLUP) { + /* bias_pull_up */ + drv_mode = CY_GPIO_DM_PULLUP_IN_OFF; + + } else if (_flags & SOC_GPIO_PULLDOWN) { + /* bias_pull_down */ + drv_mode = CY_GPIO_DM_PULLDOWN_IN_OFF; + } else { + /* nothing do here */ + } + + if (_flags & SOC_GPIO_INPUTENABLE) { + /* input_enable */ + drv_mode |= CY_GPIO_DM_HIGHZ; + } + + return drv_mode; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, + uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + uint32_t drv_mode = soc_gpio_get_drv_mode(pins[i].pincfg); + uint32_t hsiom = CAT1_PINMUX_GET_HSIOM_FUNC(pins[i].pinmux); + uint32_t port_num = CAT1_PINMUX_GET_PORT_NUM(pins[i].pinmux); + uint32_t pin_num = CAT1_PINMUX_GET_PIN_NUM(pins[i].pinmux); + + /* Initialize pin */ + Cy_GPIO_Pin_FastInit(gpio_ports[port_num], pin_num, drv_mode, 1, hsiom); + + /* Force output to enable pulls */ + switch (drv_mode) { + case CY_GPIO_DM_PULLUP: + Cy_GPIO_Write(gpio_ports[port_num], pin_num, 1); + break; + case CY_GPIO_DM_PULLDOWN: + Cy_GPIO_Write(gpio_ports[port_num], pin_num, 0); + break; + default: + /* do nothing */ + break; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml b/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml new file mode 100644 index 00000000000..09e089b1baa --- /dev/null +++ b/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml @@ -0,0 +1,120 @@ +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Infineon CAT1 Pinctrl container node + + This is a singleton node responsible for controlling the pin function selection + and pin properties. For example, you can use this node to route + UART0 RX to a particular port/pin and enable the pull-up resistor on that + pin. + + The node has the 'pinctrl' node label set in SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* Your modifications go here */ + }; + + Pin configuration can also specify the pin properties, for example the + 'bias-pull-up' property. Here is a list of the supported standard pin + properties: + * bias-pull-up + * bias-pull-down + * drive-open-drain + * drive-open-source + * drive-push-pull (strong) + * input-enable (input-buffer) + + Infineon CAT1 SoC's devicetree includes a set of pre-defined pin control + Nodes, which can be found via MPN dtsi. + For example, board cy8cproto_062_4343w uses the CY8C624ABZI_S2D44 part, so + board dts (boards\arm\cy8cproto_062_4343w\cy8cproto_062_4343w.dts) includes MPN dts + (infineon/psoc6/mpns/CY8C624ABZI_S2D44.dtsi). + + Each MPN dtsi includes package dtsi (../psoc6_xx/psoc6_xx.yyy-zzz.dtsi), + For example, CY8C624ABZI_S2D44 includes "../psoc6_02/psoc6_02.124-bga.dtsi". + + An example of pre-defined pin control from package dtsi (e.g. psoc6_02.124-bga.dtsi): + p3_0_scb2_uart_rx - RX pin UART2 (SCB2) which connected to port3.0 + + /omit-if-no-ref/ p3_0_scb2_uart_rx: p3_0_scb2_uart_rx { + pinmux = ; + }; + + Refer to psoc6_02.124-bga.dtsi for the list of all pre-defined pin control nodes. + + NOTE1 Pre-defined pin control nodes use macro DT_CAT1_PINMUX to + initialize pinmux. DT_CAT1_PINMUX has the following input parameters + DT_CAT1_PINMUX(port_number, pin_number, hsiom), + hsiom is defined in the HSIOM_SEL_xxx macros in the + zephyr\include\zephyr\dt-bindings\pinctrl\ifx_cat1-pinctrl.h file. + + You can use DT_CAT1_PINMUX to define your own pin control node: + &pinctrl { + my_uart_rx: my_uart_rx { + pinmux = ; + }; + }; + + NOTE2 Pre-defined pin control nodes do not have bias pin configuration. + The bias configuration can be updated in board-pinctrl.dtsi + &pinctrl { + /* Configure pin control Bias mode for uart2 pins */ + p3_1_scb2_uart_tx { + drive-push-pull; + }; + + p3_0_scb2_uart_rx { + input-enable; + }; + + p3_2_scb2_uart_rts { + drive-push-pull; + }; + + p3_3_scb2_uart_cts { + input-enable; + }; + }; + + An example of the usage of pre-defined pin control nodes in your board's DTS file: + + &uart5 { + pinctrl-0 = <&p5_1_scb5_uart_tx &p5_0_scb5_uart_rx>; + pinctrl-names = "default"; + }; + + /* Configure pin control bias mode for uart5 pins */ + &p5_1_scb5_uart_tx { + drive-push-pull; + }; + + &p5_0_scb5_uart_rx { + input-enable; + }; + +compatible: "infineon,cat1-pinctrl" + +include: base.yaml + +child-binding: + description: This binding gives a base representation of the Infineon CAT1 pins configuration + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-pull-down + - bias-pull-up + - drive-push-pull + - drive-open-drain + - drive-open-source + - input-enable + + properties: + pinmux: + description: | + Encodes port/pin and alternate function. + required: true + type: int diff --git a/include/zephyr/dt-bindings/pinctrl/ifx_cat1-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/ifx_cat1-pinctrl.h new file mode 100644 index 00000000000..45aca8ca2e6 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/ifx_cat1-pinctrl.h @@ -0,0 +1,99 @@ +/* Copyright 2022 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Pin control binding helper. + */ + +/** + * Bit definition in PINMUX field + */ +#define SOC_PINMUX_PORT_POS (0) +#define SOC_PINMUX_PORT_MASK (0xFFul << SOC_PINMUX_PORT_POS) +#define SOC_PINMUX_PIN_POS (8) +#define SOC_PINMUX_PIN_MASK (0xFFul << SOC_PINMUX_PIN_POS) +#define SOC_PINMUX_HSIOM_FUNC_POS (16) +#define SOC_PINMUX_HSIOM_MASK (0xFFul << SOC_PINMUX_HSIOM_FUNC_POS) +#define SOC_PINMUX_SIGNAL_POS (24) +#define SOC_PINMUX_SIGNAL_MASK (0xFFul << SOC_PINMUX_SIGNAL_POS) + +/** + * Functions are defined using HSIOM SEL + */ +#define HSIOM_SEL_GPIO (0) +#define HSIOM_SEL_GPIO_DSI (1) +#define HSIOM_SEL_DSI_DSI (2) +#define HSIOM_SEL_DSI_GPIO (3) +#define HSIOM_SEL_AMUXA (4) +#define HSIOM_SEL_AMUXB (5) +#define HSIOM_SEL_AMUXA_DSI (6) +#define HSIOM_SEL_AMUXB_DSI (7) +#define HSIOM_SEL_ACT_0 (8) +#define HSIOM_SEL_ACT_1 (9) +#define HSIOM_SEL_ACT_2 (10) +#define HSIOM_SEL_ACT_3 (11) +#define HSIOM_SEL_DS_0 (12) +#define HSIOM_SEL_DS_1 (13) +#define HSIOM_SEL_DS_2 (14) +#define HSIOM_SEL_DS_3 (15) +#define HSIOM_SEL_ACT_4 (16) +#define HSIOM_SEL_ACT_5 (17) +#define HSIOM_SEL_ACT_6 (18) +#define HSIOM_SEL_ACT_7 (19) +#define HSIOM_SEL_ACT_8 (20) +#define HSIOM_SEL_ACT_9 (21) +#define HSIOM_SEL_ACT_10 (22) +#define HSIOM_SEL_ACT_11 (23) +#define HSIOM_SEL_ACT_12 (24) +#define HSIOM_SEL_ACT_13 (25) +#define HSIOM_SEL_ACT_14 (26) +#define HSIOM_SEL_ACT_15 (27) +#define HSIOM_SEL_DS_4 (28) +#define HSIOM_SEL_DS_5 (29) +#define HSIOM_SEL_DS_6 (30) +#define HSIOM_SEL_DS_7 (31) + +/** + * Macro to set drive mode + */ +#define DT_CAT1_DRIVE_MODE_INFO(peripheral_signal) \ + CAT1_PIN_MAP_DRIVE_MODE_##peripheral_signal + +/** + * Macro to set pin control information (from pinctrl node) + */ +#define DT_CAT1_PINMUX(port, pin, hsiom) \ + ((port << SOC_PINMUX_PORT_POS) | \ + (pin << SOC_PINMUX_PIN_POS) | \ + (hsiom << SOC_PINMUX_HSIOM_FUNC_POS)) + +/* Redefine DT GPIO label (Px) to CYHAL port macros (CYHAL_PORT_x) */ +#define P0 CYHAL_PORT_0 +#define P1 CYHAL_PORT_1 +#define P2 CYHAL_PORT_2 +#define P3 CYHAL_PORT_3 +#define P4 CYHAL_PORT_4 +#define P5 CYHAL_PORT_5 +#define P6 CYHAL_PORT_6 +#define P7 CYHAL_PORT_7 +#define P8 CYHAL_PORT_8 +#define P9 CYHAL_PORT_9 +#define P10 CYHAL_PORT_10 +#define P11 CYHAL_PORT_11 +#define P12 CYHAL_PORT_12 +#define P13 CYHAL_PORT_13 +#define P14 CYHAL_PORT_14 +#define P15 CYHAL_PORT_15 +#define P16 CYHAL_PORT_16 +#define P17 CYHAL_PORT_17 +#define P18 CYHAL_PORT_18 +#define P19 CYHAL_PORT_19 +#define P20 CYHAL_PORT_20 + +/* Returns CYHAL GPIO from Board device tree GPIO configuration */ +#define DT_GET_CYHAL_GPIO_FROM_DT_GPIOS(node, gpios_prop) \ + CYHAL_GET_GPIO(DT_STRING_TOKEN(DT_GPIO_CTLR_BY_IDX(node, gpios_prop, 0), label), \ + DT_PHA_BY_IDX(node, gpios_prop, 0, pin)) diff --git a/soc/arm/infineon_cat1/common/pinctrl_soc.h b/soc/arm/infineon_cat1/common/pinctrl_soc.h new file mode 100644 index 00000000000..51c01fcaaa1 --- /dev/null +++ b/soc/arm/infineon_cat1/common/pinctrl_soc.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016-2017 Piotr Mienkowski + * Copyright (c) 2021 ATL Electronics + * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/** + * @brief Infineon CAT1 SoC specific helpers for pinctrl driver. + */ + +#ifndef ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** + * Bit definition in PINMUX field + */ +#define SOC_PINMUX_PORT_POS (0) +#define SOC_PINMUX_PORT_MASK (0xFFul << SOC_PINMUX_PORT_POS) +#define SOC_PINMUX_PIN_POS (8) +#define SOC_PINMUX_PIN_MASK (0xFFul << SOC_PINMUX_PIN_POS) +#define SOC_PINMUX_HSIOM_FUNC_POS (16) +#define SOC_PINMUX_HSIOM_MASK (0xFFul << SOC_PINMUX_HSIOM_FUNC_POS) +#define SOC_PINMUX_SIGNAL_POS (24) +#define SOC_PINMUX_SIGNAL_MASK (0xFFul << SOC_PINMUX_SIGNAL_POS) + +/* + * Pin flags/attributes + */ +#define SOC_GPIO_DEFAULT (0) +#define SOC_GPIO_FLAGS_POS (0) +#define SOC_GPIO_FLAGS_MASK (0x3F << SOC_GPIO_FLAGS_POS) +#define SOC_GPIO_PULLUP_POS (0) +#define SOC_GPIO_PULLUP (1 << SOC_GPIO_PULLUP_POS) +#define SOC_GPIO_PULLDOWN_POS (1) +#define SOC_GPIO_PULLDOWN (1 << SOC_GPIO_PULLDOWN_POS) +#define SOC_GPIO_OPENDRAIN_POS (2) +#define SOC_GPIO_OPENDRAIN (1 << SOC_GPIO_OPENDRAIN_POS) +#define SOC_GPIO_OPENSOURCE_POS (3) +#define SOC_GPIO_OPENSOURCE (1 << SOC_GPIO_OPENSOURCE_POS) + +/* Push-Pull means Strong, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_GPIO_PUSHPULL_POS (4) +#define SOC_GPIO_PUSHPULL (1 << SOC_GPIO_PUSHPULL_POS) + +/* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_GPIO_INPUTENABLE_POS (5) +#define SOC_GPIO_INPUTENABLE (1 << SOC_GPIO_INPUTENABLE_POS) + +/** Type for CAT1 Soc pin. */ +typedef struct { + /** + * Pinmux settings (port, pin and function). + * [0..7] - Port nunder + * [8..15] - Pin number + * [16..23]- HSIOM function + */ + uint32_t pinmux; + + /** Pin configuration (bias, drive and slew rate). */ + uint32_t pincfg; +} pinctrl_soc_pin_t; + +#define CAT1_PINMUX_GET_PORT_NUM(pinmux) \ + (((pinmux) & SOC_PINMUX_PORT_MASK) >> SOC_PINMUX_PORT_POS) +#define CAT1_PINMUX_GET_PIN_NUM(pinmux) \ + (((pinmux) & SOC_PINMUX_PIN_MASK) >> SOC_PINMUX_PIN_POS) +#define CAT1_PINMUX_GET_HSIOM_FUNC(pinmux) \ + (((pinmux) & SOC_PINMUX_HSIOM_MASK) >> SOC_PINMUX_HSIOM_FUNC_POS) + +/** + * @brief Utility macro to initialize pinmux field in #pinctrl_pin_t. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_CAT1_PINMUX_INIT(node_id) DT_PROP(node_id, pinmux) + +/** + * @brief Utility macro to initialize pincfg field in #pinctrl_pin_t. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_CAT1_PINCFG_INIT(node_id) ( \ + (DT_PROP(node_id, bias_pull_up) << SOC_GPIO_PULLUP_POS) | \ + (DT_PROP(node_id, bias_pull_down) << SOC_GPIO_PULLDOWN_POS) | \ + (DT_PROP(node_id, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS) | \ + (DT_PROP(node_id, drive_open_source) << SOC_GPIO_OPENSOURCE_POS) | \ + (DT_PROP(node_id, drive_push_pull) << SOC_GPIO_PUSHPULL_POS) | \ + (DT_PROP(node_id, input_enable) << SOC_GPIO_INPUTENABLE_POS)) + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param state_prop State property name. + * @param idx State property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \ + { .pinmux = Z_PINCTRL_CAT1_PINMUX_INIT( \ + DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .pincfg = Z_PINCTRL_CAT1_PINCFG_INIT( \ + DT_PROP_BY_IDX(node_id, state_prop, idx)) }, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ */