soc: atmel_sam0: common: Add soc_port
Introduce soc_port common functions. The sam0 pinmux driver was refactored to use soc_port_pinmux_set common function. This create the common base to implement sam0 pinctrl functions. Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
parent
94485364e9
commit
6de5f4d729
11 changed files with 215 additions and 14 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Google LLC.
|
||||
* Copyright (c) 2021 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -15,21 +16,8 @@ static int pinmux_sam0_set(const struct device *dev, uint32_t pin,
|
|||
uint32_t func)
|
||||
{
|
||||
const struct pinmux_sam0_config *cfg = dev->config;
|
||||
bool odd_pin = pin & 1;
|
||||
int idx = pin / 2U;
|
||||
|
||||
/* Each pinmux register holds the config for two pins. The
|
||||
* even numbered pin goes in the bits 0..3 and the odd
|
||||
* numbered pin in bits 4..7.
|
||||
*/
|
||||
if (odd_pin) {
|
||||
cfg->regs->PMUX[idx].bit.PMUXO = func;
|
||||
} else {
|
||||
cfg->regs->PMUX[idx].bit.PMUXE = func;
|
||||
}
|
||||
cfg->regs->PINCFG[pin].bit.PMUXEN = 1;
|
||||
|
||||
return 0;
|
||||
return soc_port_pinmux_set(cfg->regs, pin, func);
|
||||
}
|
||||
|
||||
static int pinmux_sam0_get(const struct device *dev, uint32_t pin,
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
# Copyright (c) 2019 ML!PA Consulting GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources(soc_port.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_BOOTLOADER_BOSSA bossa.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD20 soc_samd2x.c)
|
||||
|
|
79
soc/arm/atmel_sam0/common/soc_port.c
Normal file
79
soc/arm/atmel_sam0/common/soc_port.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Piotr Mienkowski
|
||||
* Copyright (c) 2018 Google LLC.
|
||||
* Copyright (c) 2021 Gerson Fernando Budke
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Atmel SAM0 MCU family I/O Pin Controller (PORT)
|
||||
*/
|
||||
|
||||
#include "soc_port.h"
|
||||
|
||||
int soc_port_pinmux_set(PortGroup *pg, uint32_t pin, uint32_t func)
|
||||
{
|
||||
bool is_odd = pin & 1;
|
||||
int idx = pin / 2U;
|
||||
|
||||
/* Each pinmux register holds the config for two pins. The
|
||||
* even numbered pin goes in the bits 0..3 and the odd
|
||||
* numbered pin in bits 4..7.
|
||||
*/
|
||||
if (is_odd) {
|
||||
pg->PMUX[idx].bit.PMUXO = func;
|
||||
} else {
|
||||
pg->PMUX[idx].bit.PMUXE = func;
|
||||
}
|
||||
pg->PINCFG[pin].bit.PMUXEN = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void soc_port_configure(const struct soc_port_pin *pin)
|
||||
{
|
||||
PortGroup *pg = pin->regs;
|
||||
uint32_t flags = pin->flags;
|
||||
uint32_t func = (pin->flags & SOC_PORT_FUNC_MASK) >> SOC_PORT_FUNC_POS;
|
||||
PORT_PINCFG_Type pincfg = { .reg = 0 };
|
||||
|
||||
/* Reset or analog I/O: all digital disabled */
|
||||
pg->PINCFG[pin->pinum] = pincfg;
|
||||
pg->DIRCLR.reg = (1 << pin->pinum);
|
||||
pg->OUTCLR.reg = (1 << pin->pinum);
|
||||
|
||||
if (flags & SOC_PORT_PMUXEN_ENABLE) {
|
||||
soc_port_pinmux_set(pg, pin->pinum, func);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & (SOC_PORT_PULLUP | SOC_PORT_PULLDOWN)) {
|
||||
if (flags & SOC_PORT_PULLUP) {
|
||||
pg->OUTSET.reg = (1 << pin->pinum);
|
||||
}
|
||||
|
||||
pincfg.bit.PULLEN = 1;
|
||||
}
|
||||
|
||||
if (flags & SOC_PORT_INPUT_ENABLE) {
|
||||
pincfg.bit.INEN = 1;
|
||||
}
|
||||
|
||||
if (flags & SOC_PORT_OUTPUT_ENABLE) {
|
||||
pg->DIRSET.reg = (1 << pin->pinum);
|
||||
}
|
||||
|
||||
if (flags & SOC_PORT_STRENGTH_STRONGER) {
|
||||
pincfg.bit.DRVSTR = 1;
|
||||
}
|
||||
|
||||
pg->PINCFG[pin->pinum] = pincfg;
|
||||
}
|
||||
|
||||
void soc_port_list_configure(const struct soc_port_pin pins[],
|
||||
unsigned int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++) {
|
||||
soc_port_configure(&pins[i]);
|
||||
}
|
||||
}
|
125
soc/arm/atmel_sam0/common/soc_port.h
Normal file
125
soc/arm/atmel_sam0/common/soc_port.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017 Piotr Mienkowski
|
||||
* Copyright (c) 2020-2021 Gerson Fernando Budke
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Atmel SAM0 MCU family I/O Pin Controller (PORT)
|
||||
*/
|
||||
|
||||
#ifndef ATMEL_SAM0_SOC_PORT_H_
|
||||
#define ATMEL_SAM0_SOC_PORT_H_
|
||||
|
||||
#include <soc.h>
|
||||
|
||||
/*
|
||||
* Pin flags/attributes
|
||||
*/
|
||||
#define SOC_PORT_DEFAULT (0)
|
||||
|
||||
#define SOC_PORT_FLAGS_POS (0)
|
||||
#define SOC_PORT_FLAGS_MASK (0x3F << SOC_PORT_FLAGS_POS)
|
||||
#define SOC_PORT_PULLUP_POS (0)
|
||||
#define SOC_PORT_PULLUP (1 << SOC_PORT_PULLUP_POS)
|
||||
#define SOC_PORT_PULLDOWN_POS (1)
|
||||
#define SOC_PORT_PULLDOWN (1 << SOC_PORT_PULLDOWN_POS)
|
||||
/* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */
|
||||
#define SOC_PORT_INPUT_ENABLE_POS (2)
|
||||
#define SOC_PORT_INPUT_ENABLE (1 << SOC_PORT_INPUT_ENABLE_POS)
|
||||
/* Output-Enable, see dts/pinctrl/pincfg-node.yaml */
|
||||
#define SOC_PORT_OUTPUT_ENABLE_POS (3)
|
||||
#define SOC_PORT_OUTPUT_ENABLE (1 << SOC_PORT_OUTPUT_ENABLE_POS)
|
||||
/* Drive-Strength, 0mA means normal, any other value means stronger */
|
||||
#define SOC_PORT_STRENGTH_STRONGER_POS (4)
|
||||
#define SOC_PORT_STRENGTH_STRONGER (1 << SOC_PORT_STRENGTH_STRONGER_POS)
|
||||
/* Peripheral Multiplexer Enable */
|
||||
#define SOC_PORT_PMUXEN_ENABLE_POS (5)
|
||||
#define SOC_PORT_PMUXEN_ENABLE (1 << SOC_PORT_PMUXEN_ENABLE_POS)
|
||||
|
||||
/* Bit field: SOC_PORT_FUNC */
|
||||
#define SOC_PORT_FUNC_POS (16)
|
||||
#define SOC_PORT_FUNC_MASK (0xF << SOC_PORT_FUNC_POS)
|
||||
|
||||
/** Connect pin to peripheral A. */
|
||||
#define SOC_PORT_FUNC_A (0x0 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral B. */
|
||||
#define SOC_PORT_FUNC_B (0x1 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral C. */
|
||||
#define SOC_PORT_FUNC_C (0x2 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral D. */
|
||||
#define SOC_PORT_FUNC_D (0x3 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral E. */
|
||||
#define SOC_PORT_FUNC_E (0x4 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral F. */
|
||||
#define SOC_PORT_FUNC_F (0x5 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral G. */
|
||||
#define SOC_PORT_FUNC_G (0x6 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral H. */
|
||||
#define SOC_PORT_FUNC_H (0x7 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral I. */
|
||||
#define SOC_PORT_FUNC_I (0x8 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral J. */
|
||||
#define SOC_PORT_FUNC_J (0x9 << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral K. */
|
||||
#define SOC_PORT_FUNC_K (0xa << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral L. */
|
||||
#define SOC_PORT_FUNC_L (0xb << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral M. */
|
||||
#define SOC_PORT_FUNC_M (0xc << SOC_PORT_FUNC_POS)
|
||||
/** Connect pin to peripheral N. */
|
||||
#define SOC_PORT_FUNC_N (0xd << SOC_PORT_FUNC_POS)
|
||||
|
||||
struct soc_port_pin {
|
||||
PortGroup *regs; /** pointer to registers of the I/O Pin Controller */
|
||||
uint32_t pinum; /** pin number */
|
||||
uint32_t flags; /** pin flags/attributes */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configure PORT pin muxing.
|
||||
*
|
||||
* Configure one pin muxing belonging to some PORT.
|
||||
*
|
||||
* @param pg PortGroup register
|
||||
* @param pin Pin number
|
||||
* @param func Pin Function
|
||||
*/
|
||||
int soc_port_pinmux_set(PortGroup *pg, uint32_t pin, uint32_t func);
|
||||
|
||||
/**
|
||||
* @brief Configure PORT pin.
|
||||
*
|
||||
* Configure one pin belonging to some PORT.
|
||||
* Example scenarios:
|
||||
* - configure pin(s) as input.
|
||||
* - connect pin(s) to a peripheral B and enable pull-up.
|
||||
*
|
||||
* @remark During Reset, all PORT lines are configured as inputs with input
|
||||
* buffers, output buffers and pull disabled. When the device is set to the
|
||||
* BACKUP sleep mode, even if the PORT configuration registers and input
|
||||
* synchronizers will lose their contents (these will not be restored when
|
||||
* PORT is powered up again), the latches in the pads will keep their current
|
||||
* configuration, such as the output value and pull settings. Refer to the
|
||||
* Power Manager documentation for more features related to the I/O lines
|
||||
* configuration in and out of BACKUP mode. The PORT peripheral will continue
|
||||
* operating in any Sleep mode where its source clock is running.
|
||||
*
|
||||
* @param pin pin's configuration data such as pin mask, pin attributes, etc.
|
||||
*/
|
||||
void soc_port_configure(const struct soc_port_pin *pin);
|
||||
|
||||
/**
|
||||
* @brief Configure a list of PORT 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_port_list_configure(const struct soc_port_pin pins[],
|
||||
unsigned int size);
|
||||
|
||||
#endif /* ATMEL_SAM0_SOC_PORT_H_ */
|
|
@ -56,6 +56,7 @@
|
|||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
/** Processor Clock (HCLK) Frequency */
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
/** Processor Clock (HCLK) Frequency */
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "sercom_fixup_samd5x.h"
|
||||
#include "tc_fixup_samd5x.h"
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
#define SOC_ATMEL_SAM0_OSC32K_FREQ_HZ 32768
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "sercom_fixup_samd5x.h"
|
||||
#include "tc_fixup_samd5x.h"
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
#define SOC_ATMEL_SAM0_OSC32K_FREQ_HZ 32768
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "sercom_fixup_samd5x.h"
|
||||
#include "tc_fixup_samd5x.h"
|
||||
#include "gmac_fixup_samd5x.h"
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
#define SOC_ATMEL_SAM0_OSC32K_FREQ_HZ 32768
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "sercom_fixup_samd5x.h"
|
||||
#include "tc_fixup_samd5x.h"
|
||||
#include "gmac_fixup_samd5x.h"
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
#define SOC_ATMEL_SAM0_OSC32K_FREQ_HZ 32768
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#include "../common/soc_port.h"
|
||||
#include "../common/atmel_sam0_dt.h"
|
||||
|
||||
/** Processor Clock (HCLK) Frequency */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue