soc: arm: cypress: Add PSoC-6 pinctrl soc support

Add SoC support to enable Cypress PSoC-6 pinctrl.  This add devicetree
macros to handle pinctrl nodes and SoC GPIO methods to configure pins.

Signed-off-by: Gerson Fernando Budke <gerson.budke@atl-electronics.com>
This commit is contained in:
Gerson Fernando Budke 2021-03-02 22:53:52 -03:00 committed by Kumar Gala
parent 68dcac3be6
commit 868f722ca1
6 changed files with 227 additions and 2 deletions

View file

@ -1,7 +1,9 @@
#
# Copyright (c) 2018, Cypress
# Copyright (c) 2021, ATL Electronics
#
# SPDX-License-Identifier: Apache-2.0
#
add_subdirectory(${SOC_SERIES})
add_subdirectory(common)

View file

@ -0,0 +1,6 @@
# Copyright (c) 2021 ATL Electronics
# SPDX-License-Identifier: Apache-2.0
zephyr_include_directories(.)
zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_PSOC6 soc_gpio.c)

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2020 Linaro Ltd.
* Copyright (c) 2020 ATL Electronics
* Copyright (c) 2020-2021 ATL Electronics
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -98,4 +98,64 @@
irq_enable(CY_PSOC6_NVIC_MUX_IRQN(n)); \
} while (0)
/*
* Devicetree related macros to construct pin control config data
*/
/* Get a node id from a pinctrl-0 prop at index 'i' */
#define NODE_ID_FROM_PINCTRL_0(inst, i) \
DT_INST_PHANDLE_BY_IDX(inst, pinctrl_0, i)
/* Get GPIO register address associated with pinctrl-0 pin at index 'i' */
#define CY_PSOC6_PIN_TO_GPIO_REG_ADDR(inst, i) \
DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins))
/* Get PIN associated with pinctrl-0 pin at index 'i' */
#define CY_PSOC6_PIN(inst, i) \
DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins, pin)
/* Get HSIOM value associated with pinctrl-0 pin at index 'i' */
#define CY_PSOC6_PIN_HSIOM(inst, i) \
DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), cypress_pins, hsiom)
/* Helper function for CY_PSOC6_PIN_FLAGS */
#define CY_PSOC6_PIN_FLAG(inst, i, flag) \
DT_PROP(NODE_ID_FROM_PINCTRL_0(inst, i), flag)
/* Convert DT flags to SoC flags */
#define CY_PSOC6_PIN_FLAGS(inst, i) \
(CY_PSOC6_PIN_FLAG(inst, i, bias_pull_up) << \
SOC_GPIO_PULLUP_POS | \
CY_PSOC6_PIN_FLAG(inst, i, bias_pull_down) << \
SOC_GPIO_PULLUP_POS | \
CY_PSOC6_PIN_FLAG(inst, i, drive_open_drain) << \
SOC_GPIO_OPENDRAIN_POS | \
CY_PSOC6_PIN_FLAG(inst, i, drive_open_source) << \
SOC_GPIO_OPENSOURCE_POS | \
CY_PSOC6_PIN_FLAG(inst, i, drive_push_pull) << \
SOC_GPIO_PUSHPULL_POS | \
CY_PSOC6_PIN_FLAG(inst, i, input_enable) << \
SOC_GPIO_INPUTENABLE_POS)
/* Construct a soc_pio_pin element for pin cfg */
#define CY_PSOC6_DT_INST_PIN(inst, idx) \
{ \
(GPIO_PRT_Type *)CY_PSOC6_PIN_TO_GPIO_REG_ADDR(inst, idx), \
CY_PSOC6_PIN(inst, idx), \
CY_PSOC6_PIN_HSIOM(inst, idx) << SOC_GPIO_FUNC_POS | \
CY_PSOC6_PIN_FLAGS(inst, idx) \
}
/* Get the number of pins for pinctrl-0 */
#define CY_PSOC6_DT_INST_NUM_PINS(inst) DT_INST_PROP_LEN(inst, pinctrl_0)
/* internal macro to structure things for use with UTIL_LISTIFY */
#define CY_PSOC6_PIN_ELEM(idx, inst) CY_PSOC6_DT_INST_PIN(inst, idx),
/* Construct an array intializer for soc_gpio_pin for a device instance */
#define CY_PSOC6_DT_INST_PINS(inst) \
{ UTIL_LISTIFY(CY_PSOC6_DT_INST_NUM_PINS(inst), \
CY_PSOC6_PIN_ELEM, inst) \
}
#endif /* _CYPRESS_PSOC6_SOC_DT_H_ */

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2016 Piotr Mienkowski
* Copyright (c) 2021 ATL Electronics
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Cypress PSoC-6 MCU family General Purpose Input Output (GPIO)
* module HAL driver.
*/
#include "soc_gpio.h"
#include "cy_gpio.h"
static uint32_t soc_gpio_get_drv_mode(uint32_t flags)
{
uint32_t drv_mode = CY_GPIO_DM_ANALOG;
flags = ((flags & SOC_GPIO_FLAGS_MASK) >> SOC_GPIO_FLAGS_POS);
if (flags & SOC_GPIO_OPENDRAIN) {
drv_mode = CY_GPIO_DM_OD_DRIVESLOW_IN_OFF;
} else if (flags & SOC_GPIO_OPENSOURCE) {
drv_mode = CY_GPIO_DM_OD_DRIVESHIGH_IN_OFF;
} else if (flags & SOC_GPIO_PUSHPULL) {
drv_mode = CY_GPIO_DM_STRONG_IN_OFF;
} else if ((flags & SOC_GPIO_PULLUP) && (flags & SOC_GPIO_PULLDOWN)) {
drv_mode = CY_GPIO_DM_PULLUP_DOWN_IN_OFF;
} else if (flags & SOC_GPIO_PULLUP) {
drv_mode = CY_GPIO_DM_PULLUP_IN_OFF;
} else if (flags & SOC_GPIO_PULLDOWN) {
drv_mode = CY_GPIO_DM_PULLDOWN_IN_OFF;
}
if (flags & SOC_GPIO_INPUTENABLE) {
drv_mode |= CY_GPIO_DM_HIGHZ;
}
return drv_mode;
}
void soc_gpio_configure(const struct soc_gpio_pin *pin)
{
uint32_t drv_mode = soc_gpio_get_drv_mode(pin->flags);
uint32_t function = ((pin->flags & SOC_GPIO_FUNC_MASK) >>
SOC_GPIO_FUNC_POS);
Cy_GPIO_SetHSIOM(pin->regs, pin->pinum, function);
Cy_GPIO_SetDrivemode(pin->regs, pin->pinum, drv_mode);
}
void soc_gpio_list_configure(const struct soc_gpio_pin pins[], size_t size)
{
for (size_t i = 0; i < size; i++) {
soc_gpio_configure(&pins[i]);
}
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2016-2017 Piotr Mienkowski
* Copyright (c) 2021 ATL Electronics
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Cypress PSoC-6 MCU family General Purpose Input Output (GPIO)
* module HAL driver.
*/
#ifndef _CYPRESS_PSOC6_SOC_GPIO_H_
#define _CYPRESS_PSOC6_SOC_GPIO_H_
#include <zephyr/types.h>
#include <soc.h>
/*
* 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)
/* Bit field: SOC_GPIO_IN_FILTER */
#define SOC_GPIO_IN_FILTER_POS (6)
#define SOC_GPIO_IN_FILTER_MASK (3 << SOC_GPIO_IN_FILTER_POS)
#define SOC_GPIO_IN_FILTER_NONE (0 << SOC_GPIO_IN_FILTER_POS)
#define SOC_GPIO_IN_FILTER_DEBOUNCE (1 << SOC_GPIO_IN_FILTER_POS)
#define SOC_GPIO_IN_FILTER_DEGLITCH (2 << SOC_GPIO_IN_FILTER_POS)
#define SOC_GPIO_INT_ENABLE (1 << 8)
/* Bit field: SOC_GPIO_INT_TRIG */
#define SOC_GPIO_INT_TRIG_POS (9)
#define SOC_GPIO_INT_TRIG_MASK (3 << SOC_GPIO_INT_TRIG_POS)
/** Interrupt is triggered by a level detection event. */
#define SOC_GPIO_INT_TRIG_LEVEL (0 << SOC_GPIO_INT_TRIG_POS)
/** Interrupt is triggered by an edge detection event. */
#define SOC_GPIO_INT_TRIG_EDGE (1 << SOC_GPIO_INT_TRIG_POS)
/** Interrupt is triggered by any edge detection event. */
#define SOC_GPIO_INT_TRIG_DOUBLE_EDGE (2 << SOC_GPIO_INT_TRIG_POS)
/** Interrupt is triggered by a high level / rising edge detection event */
#define SOC_GPIO_INT_ACTIVE_HIGH (1 << 11)
/* Bit field: SOC_GPIO_FUNC */
#define SOC_GPIO_FUNC_POS (16)
#define SOC_GPIO_FUNC_MASK (0x1F << SOC_GPIO_FUNC_POS)
struct soc_gpio_pin {
GPIO_PRT_Type *regs; /** pointer to registers of the GPIO controller */
uint32_t pinum; /** pin number */
uint32_t flags; /** pin flags/attributes */
};
/**
* @brief Configure GPIO pin(s).
*
* Configure one or several pins belonging to the same GPIO port.
* Example scenarios:
* - configure pin(s) as input with debounce filter enabled.
* - connect pin(s) to a HSIOM function and enable pull-up.
* - configure pin(s) as open drain output.
* All pins are configured in the same way.
*
* @param pin pin's configuration data such as pin mask, pin attributes, etc.
*/
void soc_gpio_configure(const struct soc_gpio_pin *pin);
/**
* @brief Configure a list of GPIO pin(s).
*
* Configure an arbitrary amount of pins in an arbitrary way. Each
* configuration entry is a single item in an array passed as an
* argument to the function.
*
* @param pins an array where each item contains pin's configuration data.
* @param size size of the pin list.
*/
void soc_gpio_list_configure(const struct soc_gpio_pin pins[], size_t size);
#endif /* _CYPRESS_PSOC6_SOC_GPIO_H_ */

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, Cypress
* Copyright (c) 2020, ATL Electronics
* Copyright (c) 2020-2021, ATL Electronics
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -24,6 +24,7 @@
#include <cy_device_headers.h>
#include "../common/soc_gpio.h"
#include "../common/cypress_psoc6_dt.h"
#endif /* !_ASMLANGUAGE */