Browse Source

clocks: atmel: sam0: Fix gclk and mclk clock bindings

The Atmel SAM0 SoC enable peripherals clocks in distinct places: PM and
MCLK. The old devices had defined the peripheral clock enable bit at PM.
On the newer devices this was extracted on a dedicated memory section
called Master Clock (MCLK). This change excludes the dedicated bindings
in favor of a generic approach that cover all cases.

Now the clocks properties is complemented by the atmel,assigned-clocks
property. It gives the liberty to user to customize the clock source
from a generic clock or configure the direct connections.

All peripherals drivers were reworked with the newer solution.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
pull/83930/head
Gerson Fernando Budke 7 months ago committed by Benjamin Cabé
parent
commit
ea7922195b
  1. 157
      drivers/adc/adc_sam0.c
  2. 30
      drivers/can/can_sam0.c
  3. 128
      drivers/counter/counter_sam0_tc32.c
  4. 63
      drivers/dac/dac_sam0.c
  5. 52
      drivers/i2c/i2c_sam0.c
  6. 78
      drivers/pwm/pwm_sam0_tc.c
  7. 79
      drivers/pwm/pwm_sam0_tcc.c
  8. 58
      drivers/serial/uart_sam0.c
  9. 50
      drivers/spi/spi_sam0.c
  10. 31
      drivers/timer/sam0_rtc_timer.c
  11. 12
      dts/arm/atmel/samc21.dtsi
  12. 41
      dts/arm/atmel/samc2x.dtsi
  13. 37
      dts/arm/atmel/samd20.dtsi
  14. 43
      dts/arm/atmel/samd21.dtsi
  15. 13
      dts/arm/atmel/samd2x.dtsi
  16. 88
      dts/arm/atmel/samd5x.dtsi
  17. 5
      dts/arm/atmel/same5x.dtsi
  18. 29
      dts/arm/atmel/saml21.dtsi
  19. 32
      dts/arm/atmel/saml2x.dtsi
  20. 1
      dts/arm/atmel/samr34.dtsi
  21. 9
      dts/bindings/adc/atmel,sam0-adc.yaml
  22. 7
      dts/bindings/arm/atmel,sam0-sercom.yaml
  23. 19
      dts/bindings/arm/atmel,samd2x-pm.yaml
  24. 10
      dts/bindings/can/atmel,sam0-can.yaml
  25. 66
      dts/bindings/clock/atmel,sam0-gclk.yaml
  26. 48
      dts/bindings/clock/atmel,sam0-mclk.yaml
  27. 38
      dts/bindings/clock/atmel,sam0-osc32kctrl.yaml
  28. 18
      dts/bindings/clock/atmel,samc2x-gclk.yaml
  29. 19
      dts/bindings/clock/atmel,samc2x-mclk.yaml
  30. 18
      dts/bindings/clock/atmel,samd2x-gclk.yaml
  31. 18
      dts/bindings/clock/atmel,samd5x-gclk.yaml
  32. 19
      dts/bindings/clock/atmel,samd5x-mclk.yaml
  33. 18
      dts/bindings/clock/atmel,saml2x-gclk.yaml
  34. 19
      dts/bindings/clock/atmel,saml2x-mclk.yaml
  35. 8
      dts/bindings/counter/atmel,sam0-tc32.yaml
  36. 8
      dts/bindings/dac/atmel,sam0-dac.yaml
  37. 8
      dts/bindings/i2c/atmel,sam0-i2c.yaml
  38. 8
      dts/bindings/pwm/atmel,sam0-tc-pwm.yaml
  39. 8
      dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml
  40. 15
      dts/bindings/rtc/atmel,sam0-rtc.yaml
  41. 10
      dts/bindings/serial/atmel,sam0-uart.yaml
  42. 8
      dts/bindings/spi/atmel,sam0-spi.yaml
  43. 26
      soc/atmel/sam0/common/atmel_sam0_dt.h
  44. 8
      tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay

157
drivers/adc/adc_sam0.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -14,6 +15,8 @@ @@ -14,6 +15,8 @@
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(adc_sam0, CONFIG_ADC_LOG_LEVEL);
/* clang-format off */
#define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h"
@ -46,18 +49,12 @@ struct adc_sam0_data { @@ -46,18 +49,12 @@ struct adc_sam0_data {
struct adc_sam0_cfg {
Adc *regs;
const struct pinctrl_dev_config *pcfg;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint32_t gclk_mask;
uint32_t gclk_gen;
uint16_t gclk_id;
#else
uint32_t gclk;
#endif
uint32_t freq;
uint16_t prescaler;
void (*config_func)(const struct device *dev);
};
@ -449,14 +446,15 @@ static int adc_sam0_init(const struct device *dev) @@ -449,14 +446,15 @@ static int adc_sam0_init(const struct device *dev)
Adc *const adc = cfg->regs;
int retval;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = cfg->gclk_mask | GCLK_PCHCTRL_CHEN;
*cfg->mclk |= cfg->mclk_mask;
MCLK_ADC |= cfg->mclk_mask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
PM->APBCMASK.bit.ADC_ = 1;
GCLK->CLKCTRL.reg = cfg->gclk | GCLK_CLKCTRL_CLKEN;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
@ -515,81 +513,82 @@ static DEVICE_API(adc, adc_sam0_api) = { @@ -515,81 +513,82 @@ static DEVICE_API(adc, adc_sam0_api) = {
#ifdef MCLK
#define ADC_SAM0_CLOCK_CONTROL(n) \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \
.gclk_mask = UTIL_CAT(GCLK_PCHCTRL_GEN_GCLK, \
DT_INST_PROP(n, gclk)), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch), \
.prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \
UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)),
#define ADC_SAM0_CONFIGURE(n) \
do { \
const struct adc_sam0_cfg *const cfg = dev->config; \
Adc * const adc = cfg->regs; \
adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \
| ADC_SAM0_BIASR2R(n) \
| ADC_SAM0_BIASREFBUF(n); \
#define ADC_SAM0_CONFIGURE(n) \
do { \
const struct adc_sam0_cfg *const cfg = dev->config; \
Adc * const adc = cfg->regs; \
adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \
| ADC_SAM0_BIASR2R(n) \
| ADC_SAM0_BIASREFBUF(n); \
} while (false)
#else
#define ADC_SAM0_CLOCK_CONTROL(n) \
.gclk = UTIL_CAT(GCLK_CLKCTRL_GEN_GCLK, DT_INST_PROP(n, gclk)) |\
GCLK_CLKCTRL_ID_ADC, \
.prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \
UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)),
#define ADC_SAM0_CONFIGURE(n) \
do { \
const struct adc_sam0_cfg *const cfg = dev->config; \
Adc * const adc = cfg->regs; \
/* Linearity is split across two words */ \
#define ADC_SAM0_CONFIGURE(n) \
do { \
const struct adc_sam0_cfg *const cfg = dev->config; \
Adc * const adc = cfg->regs; \
/* Linearity is split across two words */ \
uint32_t lin = ((*(uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) & \
ADC_FUSES_LINEARITY_0_Msk) >> \
ADC_FUSES_LINEARITY_0_Pos; \
lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \
ADC_FUSES_LINEARITY_1_Msk) >> \
ADC_FUSES_LINEARITY_1_Pos) << 4; \
ADC_FUSES_LINEARITY_0_Msk) >> \
ADC_FUSES_LINEARITY_0_Pos; \
lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \
ADC_FUSES_LINEARITY_1_Msk) >> \
ADC_FUSES_LINEARITY_1_Pos) << 4; \
uint32_t bias = ((*(uint32_t *)ADC_FUSES_BIASCAL_ADDR) & \
ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \
adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \
ADC_CALIB_LINEARITY_CAL(lin); \
ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \
adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \
ADC_CALIB_LINEARITY_CAL(lin); \
} while (false)
#endif
#define ADC_SAM0_DEVICE(n) \
PINCTRL_DT_INST_DEFINE(n); \
static void adc_sam0_config_##n(const struct device *dev); \
static const struct adc_sam0_cfg adc_sam_cfg_##n = { \
.regs = (Adc *)DT_INST_REG_ADDR(n), \
ADC_SAM0_CLOCK_CONTROL(n) \
.freq = UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \
DT_INST_PROP(n, gclk)), \
_FREQ_HZ) / \
DT_INST_PROP(n, prescaler), \
.config_func = &adc_sam0_config_##n, \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
}; \
static struct adc_sam0_data adc_sam_data_##n = { \
ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \
ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \
ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \
}; \
DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \
&adc_sam_data_##n, \
&adc_sam_cfg_##n, POST_KERNEL, \
CONFIG_ADC_INIT_PRIORITY, \
&adc_sam0_api); \
static void adc_sam0_config_##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \
DT_INST_IRQ_BY_NAME(n, resrdy, priority), \
adc_sam0_isr, \
DEVICE_DT_INST_GET(n), 0); \
irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \
ADC_SAM0_CONFIGURE(n); \
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define ADC_SAM0_GCLK_FREQ(n) \
UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \
ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen)), \
_FREQ_HZ)
#define ADC_SAM0_FREQ(n) \
.prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \
UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), \
.freq = ADC_SAM0_GCLK_FREQ(n) / DT_INST_PROP(n, prescaler)
#define ADC_SAM0_DEVICE(n) \
PINCTRL_DT_INST_DEFINE(n); \
static void adc_sam0_config_##n(const struct device *dev); \
static const struct adc_sam0_cfg adc_sam_cfg_##n = { \
.regs = (Adc *)DT_INST_REG_ADDR(n), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
ADC_SAM0_FREQ(n), \
.config_func = &adc_sam0_config_##n, \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
}; \
static struct adc_sam0_data adc_sam_data_##n = { \
ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \
ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \
ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \
}; \
DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \
&adc_sam_data_##n, \
&adc_sam_cfg_##n, POST_KERNEL, \
CONFIG_ADC_INIT_PRIORITY, \
&adc_sam0_api); \
static void adc_sam0_config_##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \
DT_INST_IRQ_BY_NAME(n, resrdy, priority), \
adc_sam0_isr, \
DEVICE_DT_INST_GET(n), 0); \
irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \
ADC_SAM0_CONFIGURE(n); \
}
DT_INST_FOREACH_STATUS_OKAY(ADC_SAM0_DEVICE)
/* clang-format on */

30
drivers/can/can_sam0.c

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
* Copyright (c) 2021 Alexander Wachter
* Copyright (c) 2022 Kamil Serwus
* Copyright (c) 2023 Sebastian Schlupp
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +18,8 @@ @@ -17,6 +18,8 @@
LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL);
/* clang-format off */
#define DT_DRV_COMPAT atmel_sam0_can
struct can_sam0_config {
@ -26,7 +29,8 @@ struct can_sam0_config { @@ -26,7 +29,8 @@ struct can_sam0_config {
const struct pinctrl_dev_config *pcfg;
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint16_t gclk_core_id;
uint32_t gclk_gen;
uint16_t gclk_id;
int divider;
};
@ -109,6 +113,11 @@ static int can_sam0_get_core_clock(const struct device *dev, uint32_t *rate) @@ -109,6 +113,11 @@ static int can_sam0_get_core_clock(const struct device *dev, uint32_t *rate)
static void can_sam0_clock_enable(const struct can_sam0_config *cfg)
{
*cfg->mclk |= cfg->mclk_mask;
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
/* Enable the GLCK7 with DIV*/
#if defined(CONFIG_SOC_SERIES_SAME51) || defined(CONFIG_SOC_SERIES_SAME54)
/*DFFL has to be used as clock source for the ATSAME51/54 family of SoCs*/
@ -121,13 +130,6 @@ static void can_sam0_clock_enable(const struct can_sam0_config *cfg) @@ -121,13 +130,6 @@ static void can_sam0_clock_enable(const struct can_sam0_config *cfg)
| GCLK_GENCTRL_DIV(cfg->divider)
| GCLK_GENCTRL_GENEN;
#endif
/* Route channel */
GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK7
| GCLK_PCHCTRL_CHEN;
/* Enable CAN clock in MCLK */
*cfg->mclk |= cfg->mclk_mask;
}
static int can_sam0_init(const struct device *dev)
@ -204,6 +206,9 @@ static void config_can_##inst##_irq(void) \ @@ -204,6 +206,9 @@ static void config_can_##inst##_irq(void) \
irq_enable(DT_INST_IRQ_BY_NAME(inst, int0, irq)); \
}
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define CAN_SAM0_CFG_INST(inst) \
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \
CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \
@ -211,9 +216,10 @@ static void config_can_##inst##_irq(void) \ @@ -211,9 +216,10 @@ static void config_can_##inst##_irq(void) \
static const struct can_sam0_config can_sam0_cfg_##inst = { \
.base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \
.mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \
.divider = DT_INST_PROP(inst, divider), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.config_irq = config_can_##inst##_irq, \
@ -243,3 +249,5 @@ static void config_can_##inst##_irq(void) \ @@ -243,3 +249,5 @@ static void config_can_##inst##_irq(void) \
CAN_SAM0_DEVICE_INST(inst)
DT_INST_FOREACH_STATUS_OKAY(CAN_SAM0_INST)
/* clang-format on */

128
drivers/counter/counter_sam0_tc32.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -15,6 +16,8 @@ @@ -15,6 +16,8 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(counter_sam0_tc32, CONFIG_COUNTER_LOG_LEVEL);
/* clang-format off */
struct counter_sam0_tc32_ch_data {
counter_alarm_callback_t callback;
void *user_data;
@ -31,16 +34,11 @@ struct counter_sam0_tc32_config { @@ -31,16 +34,11 @@ struct counter_sam0_tc32_config {
struct counter_config_info info;
TcCount32 *regs;
const struct pinctrl_dev_config *pcfg;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint32_t gclk_gen;
uint16_t gclk_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
uint16_t prescaler;
void (*irq_config_func)(const struct device *dev);
};
@ -336,20 +334,15 @@ static int counter_sam0_tc32_initialize(const struct device *dev) @@ -336,20 +334,15 @@ static int counter_sam0_tc32_initialize(const struct device *dev)
TcCount32 *tc = cfg->regs;
int retval;
#ifdef MCLK
/* Enable the GCLK */
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_GEN_GCLK0 |
GCLK_PCHCTRL_CHEN;
/* Enable TC clock in MCLK */
*cfg->mclk |= cfg->mclk_mask;
#else
/* Enable the GCLK */
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
/* Enable clock in PM */
PM->APBCMASK.reg |= cfg->pm_apbcmask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
/*
@ -403,60 +396,57 @@ static DEVICE_API(counter, counter_sam0_tc32_driver_api) = { @@ -403,60 +396,57 @@ static DEVICE_API(counter, counter_sam0_tc32_driver_api) = {
};
#ifdef MCLK
#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),
#else
#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),
#endif
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define SAM0_TC32_PRESCALER(n) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \
#define SAM0_TC32_PRESCALER(n) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \
(DT_INST_PROP(n, prescaler)), (1))
#define COUNTER_SAM0_TC32_DEVICE(n) \
PINCTRL_DT_INST_DEFINE(n); \
static void counter_sam0_tc32_config_##n(const struct device *dev); \
static const struct counter_sam0_tc32_config \
\
counter_sam0_tc32_dev_config_##n = { \
.info = { \
.max_top_value = UINT32_MAX, \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \
SAM0_TC32_PRESCALER(n), \
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
.channels = 1 \
}, \
.regs = (TcCount32 *)DT_INST_REG_ADDR(n), \
COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \
.prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \
SAM0_TC32_PRESCALER(n)), \
.irq_config_func = &counter_sam0_tc32_config_##n, \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
}; \
\
static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n;\
\
DEVICE_DT_INST_DEFINE(n, \
&counter_sam0_tc32_initialize, \
NULL, \
&counter_sam0_tc32_dev_data_##n, \
&counter_sam0_tc32_dev_config_##n, \
PRE_KERNEL_1, \
CONFIG_COUNTER_INIT_PRIORITY, \
&counter_sam0_tc32_driver_api); \
\
static void counter_sam0_tc32_config_##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQN(n), \
DT_INST_IRQ(n, priority), \
counter_sam0_tc32_isr, \
DEVICE_DT_INST_GET(n), 0); \
irq_enable(DT_INST_IRQN(n)); \
#define COUNTER_SAM0_TC32_DEVICE(n) \
PINCTRL_DT_INST_DEFINE(n); \
static void counter_sam0_tc32_config_##n(const struct device *dev); \
static const struct counter_sam0_tc32_config \
\
counter_sam0_tc32_dev_config_##n = { \
.info = { \
.max_top_value = UINT32_MAX, \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \
SAM0_TC32_PRESCALER(n), \
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
.channels = 1 \
}, \
.regs = (TcCount32 *)DT_INST_REG_ADDR(n), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \
SAM0_TC32_PRESCALER(n)), \
.irq_config_func = &counter_sam0_tc32_config_##n, \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
}; \
\
static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n; \
\
DEVICE_DT_INST_DEFINE(n, \
&counter_sam0_tc32_initialize, \
NULL, \
&counter_sam0_tc32_dev_data_##n, \
&counter_sam0_tc32_dev_config_##n, \
PRE_KERNEL_1, \
CONFIG_COUNTER_INIT_PRIORITY, \
&counter_sam0_tc32_driver_api); \
\
static void counter_sam0_tc32_config_##n(const struct device *dev) \
{ \
IRQ_CONNECT(DT_INST_IRQN(n), \
DT_INST_IRQ(n, priority), \
counter_sam0_tc32_isr, \
DEVICE_DT_INST_GET(n), 0); \
irq_enable(DT_INST_IRQN(n)); \
}
DT_INST_FOREACH_STATUS_OKAY(COUNTER_SAM0_TC32_DEVICE)
/* clang-format on */

63
drivers/dac/dac_sam0.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -14,6 +15,8 @@ @@ -14,6 +15,8 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL);
/* clang-format off */
/*
* Maps between the DTS reference property names and register values. Note that
* the ASF uses the 09/2015 names which differ from the 03/2020 datasheet.
@ -27,8 +30,10 @@ LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL); @@ -27,8 +30,10 @@ LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL);
struct dac_sam0_cfg {
Dac *regs;
const struct pinctrl_dev_config *pcfg;
uint8_t pm_apbc_bit;
uint8_t gclk_clkctrl_id;
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint32_t gclk_gen;
uint16_t gclk_id;
uint8_t refsel;
};
@ -77,18 +82,22 @@ static int dac_sam0_init(const struct device *dev) @@ -77,18 +82,22 @@ static int dac_sam0_init(const struct device *dev)
Dac *regs = cfg->regs;
int retval;
/* Enable the GCLK */
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
*cfg->mclk |= cfg->mclk_mask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
if (retval < 0) {
return retval;
}
/* Enable the clock in PM */
PM->APBCMASK.reg |= 1 << cfg->pm_apbc_bit;
/* Reset then configure the DAC */
regs->CTRLA.bit.SWRST = 1;
while (regs->STATUS.bit.SYNCBUSY) {
@ -110,24 +119,30 @@ static DEVICE_API(dac, api_sam0_driver_api) = { @@ -110,24 +119,30 @@ static DEVICE_API(dac, api_sam0_driver_api) = {
.write_value = dac_sam0_write_value
};
#define SAM0_DAC_REFSEL(n) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define SAM0_DAC_REFSEL(n) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \
(DT_INST_ENUM_IDX(n, reference)), (0))
#define SAM0_DAC_INIT(n) \
PINCTRL_DT_INST_DEFINE(n); \
static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \
.regs = (Dac *)DT_INST_REG_ADDR(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.pm_apbc_bit = DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit), \
.gclk_clkctrl_id = \
DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id), \
.refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \
}; \
\
DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \
&dac_sam0_cfg_##n, POST_KERNEL, \
CONFIG_DAC_INIT_PRIORITY, \
#define SAM0_DAC_INIT(n) \
PINCTRL_DT_INST_DEFINE(n); \
static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \
.regs = (Dac *)DT_INST_REG_ADDR(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \
}; \
\
DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \
&dac_sam0_cfg_##n, POST_KERNEL, \
CONFIG_DAC_INIT_PRIORITY, \
&api_sam0_driver_api)
DT_INST_FOREACH_STATUS_OKAY(SAM0_DAC_INIT);
/* clang-format on */

52
drivers/i2c/i2c_sam0.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,6 +19,8 @@ @@ -18,6 +19,8 @@
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL);
/* clang-format off */
#include "i2c-priv.h"
#ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER
@ -34,14 +37,10 @@ struct i2c_sam0_dev_config { @@ -34,14 +37,10 @@ struct i2c_sam0_dev_config {
SercomI2cm *regs;
const struct pinctrl_dev_config *pcfg;
uint32_t bitrate;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint16_t gclk_core_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
uint32_t gclk_gen;
uint16_t gclk_id;
void (*irq_config_func)(const struct device *dev);
#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
@ -711,20 +710,17 @@ static int i2c_sam0_initialize(const struct device *dev) @@ -711,20 +710,17 @@ static int i2c_sam0_initialize(const struct device *dev)
SercomI2cm *i2c = cfg->regs;
int retval;
#ifdef MCLK
/* Enable the GCLK */
GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 |
GCLK_PCHCTRL_CHEN;
/* Enable SERCOM clock in MCLK */
*cfg->mclk |= cfg->mclk_mask;
#else
/* Enable the GCLK */
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
/* Enable SERCOM clock in PM */
PM->APBCMASK.reg |= cfg->pm_apbcmask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
/* Disable all I2C interrupts */
i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
@ -801,7 +797,7 @@ static DEVICE_API(i2c, i2c_sam0_driver_api) = { @@ -801,7 +797,7 @@ static DEVICE_API(i2c, i2c_sam0_driver_api) = {
#if DT_INST_IRQ_HAS_IDX(0, 3)
#define I2C_SAM0_IRQ_HANDLER(n) \
static void i2c_sam0_irq_config_##n(const struct device *dev) \
static void i2c_sam0_irq_config_##n(const struct device *dev) \
{ \
SAM0_I2C_IRQ_CONNECT(n, 0); \
SAM0_I2C_IRQ_CONNECT(n, 1); \
@ -810,21 +806,25 @@ static void i2c_sam0_irq_config_##n(const struct device *dev) \ @@ -810,21 +806,25 @@ static void i2c_sam0_irq_config_##n(const struct device *dev) \
}
#else
#define I2C_SAM0_IRQ_HANDLER(n) \
static void i2c_sam0_irq_config_##n(const struct device *dev) \
static void i2c_sam0_irq_config_##n(const struct device *dev) \
{ \
SAM0_I2C_IRQ_CONNECT(n, 0); \
}
#endif
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#ifdef MCLK
#define I2C_SAM0_CONFIG(n) \
static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
.regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.bitrate = DT_INST_PROP(n, clock_frequency), \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.irq_config_func = &i2c_sam0_irq_config_##n, \
I2C_SAM0_DMA_CHANNELS(n) \
}
@ -834,8 +834,10 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ @@ -834,8 +834,10 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
.regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.bitrate = DT_INST_PROP(n, clock_frequency), \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.irq_config_func = &i2c_sam0_irq_config_##n, \
I2C_SAM0_DMA_CHANNELS(n) \
}
@ -856,3 +858,5 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ @@ -856,3 +858,5 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
I2C_SAM0_IRQ_HANDLER(n)
DT_INST_FOREACH_STATUS_OKAY(I2C_SAM0_DEVICE)
/* clang-format on */

78
drivers/pwm/pwm_sam0_tc.c

@ -28,6 +28,8 @@ @@ -28,6 +28,8 @@
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>
/* clang-format off */
/* Static configuration */
struct pwm_sam0_config {
Tc *regs;
@ -36,15 +38,10 @@ struct pwm_sam0_config { @@ -36,15 +38,10 @@ struct pwm_sam0_config {
uint8_t counter_size;
uint16_t prescaler;
uint32_t freq;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint32_t gclk_gen;
uint16_t gclk_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
};
#define COUNTER_8BITS 8U
@ -133,19 +130,19 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3 @@ -133,19 +130,19 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3
static int pwm_sam0_init(const struct device *dev)
{
const struct pwm_sam0_config *const cfg = dev->config;
int retval;
Tc *regs = cfg->regs;
uint8_t counter_size = cfg->counter_size;
Tc *regs = cfg->regs;
int retval;
/* Enable the clocks */
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg =
GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;
*cfg->mclk |= cfg->mclk_mask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
PM->APBCMASK.reg |= cfg->pm_apbcmask;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
@ -185,30 +182,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = { @@ -185,30 +182,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = {
.get_cycles_per_sec = pwm_sam0_get_cycles_per_sec,
};
#ifdef MCLK
#define PWM_SAM0_INIT_CLOCKS(inst) \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch)
#else
#define PWM_SAM0_INIT_CLOCKS(inst) \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id)
#endif
#define PWM_SAM0_INIT(inst) \
PINCTRL_DT_INST_DEFINE(inst); \
static const struct pwm_sam0_config pwm_sam0_config_##inst = { \
.regs = (Tc *)DT_INST_REG_ADDR(inst), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.channels = DT_INST_PROP(inst, channels), \
.counter_size = DT_INST_PROP(inst, counter_size), \
.prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, DT_INST_PROP(inst, prescaler)), \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / DT_INST_PROP(inst, prescaler), \
PWM_SAM0_INIT_CLOCKS(inst), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, NULL, &pwm_sam0_config_##inst, \
POST_KERNEL, CONFIG_PWM_TC_INIT_PRIORITY, &pwm_sam0_driver_api);
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define PWM_SAM0_INIT(inst) \
PINCTRL_DT_INST_DEFINE(inst) \
static const struct pwm_sam0_config pwm_sam0_config_##inst = { \
.regs = (Tc *)DT_INST_REG_ADDR(inst), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.channels = DT_INST_PROP(inst, channels), \
.counter_size = DT_INST_PROP(inst, counter_size), \
.prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \
DT_INST_PROP(inst, prescaler)), \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \
DT_INST_PROP(inst, prescaler), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \
NULL, &pwm_sam0_config_##inst, \
POST_KERNEL, CONFIG_PWM_TC_INIT_PRIORITY, \
&pwm_sam0_driver_api);
DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT)
/* clang-format on */

79
drivers/pwm/pwm_sam0_tcc.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +18,8 @@ @@ -17,6 +18,8 @@
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>
/* clang-format off */
/* Static configuration */
struct pwm_sam0_config {
Tcc *regs;
@ -25,15 +28,10 @@ struct pwm_sam0_config { @@ -25,15 +28,10 @@ struct pwm_sam0_config {
uint8_t counter_size;
uint16_t prescaler;
uint32_t freq;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint32_t gclk_gen;
uint16_t gclk_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
};
/* Wait for the peripheral to finish all commands */
@ -106,15 +104,15 @@ static int pwm_sam0_init(const struct device *dev) @@ -106,15 +104,15 @@ static int pwm_sam0_init(const struct device *dev)
Tcc *regs = cfg->regs;
int retval;
/* Enable the clocks */
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg =
GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;
*cfg->mclk |= cfg->mclk_mask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
PM->APBCMASK.reg |= cfg->pm_apbcmask;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
@ -140,34 +138,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = { @@ -140,34 +138,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = {
.get_cycles_per_sec = pwm_sam0_get_cycles_per_sec,
};
#ifdef MCLK
#define PWM_SAM0_INIT_CLOCKS(inst) \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch)
#else
#define PWM_SAM0_INIT_CLOCKS(inst) \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id)
#endif
#define PWM_SAM0_INIT(inst) \
PINCTRL_DT_INST_DEFINE(inst); \
static const struct pwm_sam0_config pwm_sam0_config_##inst = { \
.regs = (Tcc *)DT_INST_REG_ADDR(inst), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.channels = DT_INST_PROP(inst, channels), \
.counter_size = DT_INST_PROP(inst, counter_size), \
.prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \
DT_INST_PROP(inst, prescaler)), \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \
DT_INST_PROP(inst, prescaler), \
PWM_SAM0_INIT_CLOCKS(inst), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \
NULL, &pwm_sam0_config_##inst, \
POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
&pwm_sam0_driver_api);
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define PWM_SAM0_INIT(inst) \
PINCTRL_DT_INST_DEFINE(inst); \
static const struct pwm_sam0_config pwm_sam0_config_##inst = { \
.regs = (Tcc *)DT_INST_REG_ADDR(inst), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.channels = DT_INST_PROP(inst, channels), \
.counter_size = DT_INST_PROP(inst, counter_size), \
.prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \
DT_INST_PROP(inst, prescaler)), \
.freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \
DT_INST_PROP(inst, prescaler), \
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \
NULL, &pwm_sam0_config_##inst, \
POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
&pwm_sam0_driver_api);
DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT)
/* clang-format on */

58
drivers/serial/uart_sam0.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +18,8 @@ @@ -17,6 +18,8 @@
#include <string.h>
#include <zephyr/irq.h>
/* clang-format off */
#ifndef SERCOM_USART_CTRLA_MODE_USART_INT_CLK
#define SERCOM_USART_CTRLA_MODE_USART_INT_CLK SERCOM_USART_CTRLA_MODE(0x1)
#endif
@ -35,14 +38,11 @@ struct uart_sam0_dev_cfg { @@ -35,14 +38,11 @@ struct uart_sam0_dev_cfg {
uint32_t baudrate;
uint32_t pads;
bool collision_detect;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint16_t gclk_core_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
uint32_t gclk_gen;
uint16_t gclk_id;
#if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_SAM0_ASYNC
void (*irq_config_func)(const struct device *dev);
#endif
@ -510,20 +510,15 @@ static int uart_sam0_init(const struct device *dev) @@ -510,20 +510,15 @@ static int uart_sam0_init(const struct device *dev)
SercomUsart * const usart = cfg->regs;
#ifdef MCLK
/* Enable the GCLK */
GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 |
GCLK_PCHCTRL_CHEN;
/* Enable SERCOM clock in MCLK */
*cfg->mclk |= cfg->mclk_mask;
#else
/* Enable the GCLK */
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
/* Enable SERCOM clock in PM */
PM->APBCMASK.reg |= cfg->pm_apbcmask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
/* Disable all USART interrupts */
@ -1272,34 +1267,23 @@ static void uart_sam0_irq_config_##n(const struct device *dev) \ @@ -1272,34 +1267,23 @@ static void uart_sam0_irq_config_##n(const struct device *dev) \
#define UART_SAM0_SERCOM_COLLISION_DETECT(n) \
(DT_INST_PROP(n, collision_detection))
#ifdef MCLK
#define UART_SAM0_CONFIG_DEFN(n) \
static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \
.regs = (SercomUsart *)DT_INST_REG_ADDR(n), \
.baudrate = DT_INST_PROP(n, current_speed), \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\
.pads = UART_SAM0_SERCOM_PADS(n), \
.collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
UART_SAM0_IRQ_HANDLER_FUNC(n) \
UART_SAM0_DMA_CHANNELS(n) \
}
#else
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#define UART_SAM0_CONFIG_DEFN(n) \
static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \
.regs = (SercomUsart *)DT_INST_REG_ADDR(n), \
.baudrate = DT_INST_PROP(n, current_speed), \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.pads = UART_SAM0_SERCOM_PADS(n), \
.collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
UART_SAM0_IRQ_HANDLER_FUNC(n) \
UART_SAM0_DMA_CHANNELS(n) \
}
#endif
#define UART_SAM0_DEVICE_INIT(n) \
PINCTRL_DT_INST_DEFINE(n); \
@ -1314,3 +1298,5 @@ DEVICE_DT_INST_DEFINE(n, uart_sam0_init, NULL, \ @@ -1314,3 +1298,5 @@ DEVICE_DT_INST_DEFINE(n, uart_sam0_init, NULL, \
UART_SAM0_IRQ_HANDLER(n)
DT_INST_FOREACH_STATUS_OKAY(UART_SAM0_DEVICE_INIT)
/* clang-format on */

50
drivers/spi/spi_sam0.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,6 +10,8 @@ @@ -9,6 +10,8 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(spi_sam0);
/* clang-format off */
#include "spi_context.h"
#include <errno.h>
#include <zephyr/device.h>
@ -27,14 +30,12 @@ struct spi_sam0_config { @@ -27,14 +30,12 @@ struct spi_sam0_config {
SercomSpi *regs;
uint32_t pads;
const struct pinctrl_dev_config *pcfg;
#ifdef MCLK
volatile uint32_t *mclk;
uint32_t mclk_mask;
uint16_t gclk_core_id;
#else
uint32_t pm_apbcmask;
uint16_t gclk_clkctrl_id;
#endif
uint32_t gclk_gen;
uint16_t gclk_id;
#ifdef CONFIG_SPI_ASYNC
const struct device *dma_dev;
uint8_t tx_dma_request;
@ -645,20 +646,15 @@ static int spi_sam0_init(const struct device *dev) @@ -645,20 +646,15 @@ static int spi_sam0_init(const struct device *dev)
struct spi_sam0_data *data = dev->data;
SercomSpi *regs = cfg->regs;
#ifdef MCLK
/* Enable the GCLK */
GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 |
GCLK_PCHCTRL_CHEN;
/* Enable the MCLK */
*cfg->mclk |= cfg->mclk_mask;
#else
/* Enable the GCLK */
GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
GCLK_CLKCTRL_CLKEN;
/* Enable SERCOM clock in PM */
PM->APBCMASK.reg |= cfg->pm_apbcmask;
#ifdef MCLK
GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN
| GCLK_PCHCTRL_GEN(cfg->gclk_gen);
#else
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(cfg->gclk_gen)
| GCLK_CLKCTRL_ID(cfg->gclk_id);
#endif
/* Disable all SPI interrupts */
@ -717,13 +713,17 @@ static DEVICE_API(spi, spi_sam0_driver_api) = { @@ -717,13 +713,17 @@ static DEVICE_API(spi, spi_sam0_driver_api) = {
SERCOM_SPI_CTRLA_DIPO(DT_INST_PROP(n, dipo)) | \
SERCOM_SPI_CTRLA_DOPO(DT_INST_PROP(n, dopo))
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
#ifdef MCLK
#define SPI_SAM0_DEFINE_CONFIG(n) \
static const struct spi_sam0_config spi_sam0_config_##n = { \
.regs = (SercomSpi *)DT_INST_REG_ADDR(n), \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.pads = SPI_SAM0_SERCOM_PADS(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
SPI_SAM0_DMA_CHANNELS(n) \
@ -732,8 +732,10 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ @@ -732,8 +732,10 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \
#define SPI_SAM0_DEFINE_CONFIG(n) \
static const struct spi_sam0_config spi_sam0_config_##n = { \
.regs = (SercomSpi *)DT_INST_REG_ADDR(n), \
.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \
.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\
.gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \
.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \
.mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \
.mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \
.pads = SPI_SAM0_SERCOM_PADS(n), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
SPI_SAM0_DMA_CHANNELS(n) \
@ -755,3 +757,5 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ @@ -755,3 +757,5 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \
&spi_sam0_driver_api);
DT_INST_FOREACH_STATUS_OKAY(SPI_SAM0_DEVICE_INIT)
/* clang-format on */

31
drivers/timer/sam0_rtc_timer.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 omSquare s.r.o.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -25,6 +26,8 @@ @@ -25,6 +26,8 @@
#include <zephyr/irq.h>
#include <zephyr/sys/util.h>
/* clang-format off */
/* RTC registers. */
#define RTC0 ((RtcMode0 *) DT_INST_REG_ADDR(0))
@ -66,10 +69,6 @@ BUILD_ASSERT(CYCLES_PER_TICK > 1, @@ -66,10 +69,6 @@ BUILD_ASSERT(CYCLES_PER_TICK > 1,
#endif /* CONFIG_TICKLESS_KERNEL */
/* Helper macro to get the correct GCLK GEN based on configuration. */
#define GCLK_GEN(n) GCLK_EVAL(n)
#define GCLK_EVAL(n) GCLK_CLKCTRL_GEN_GCLK##n
/* Tick/cycle count of the last announce call. */
static volatile uint32_t rtc_last;
@ -245,29 +244,35 @@ uint32_t sys_clock_cycle_get_32(void) @@ -245,29 +244,35 @@ uint32_t sys_clock_cycle_get_32(void)
return rtc_count();
}
#define ASSIGNED_CLOCKS_CELL_BY_NAME \
ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME
static int sys_clock_driver_init(void)
{
int retval;
volatile uint32_t *mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(0);
uint32_t mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(0, bit);
*cfg->mclk |= cfg->mclk_mask;
#ifdef MCLK
MCLK->APBAMASK.reg |= MCLK_APBAMASK_RTC;
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K;
#else
/* Set up bus clock and GCLK generator. */
PM->APBAMASK.reg |= PM_APBAMASK_RTC;
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) | GCLK_CLKCTRL_CLKEN
| GCLK_GEN(DT_INST_PROP(0, clock_generator));
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN(ASSIGNED_CLOCKS_CELL_BY_NAME(0, gclk, gen))
| GCLK_CLKCTRL_ID(DT_INST_CLOCKS_CELL_BY_NAME(0, gclk, id));
/* Synchronize GCLK. */
while (GCLK->STATUS.bit.SYNCBUSY) {
}
#endif
retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT);
if (retval < 0) {
#ifndef CONFIG_TICKLESS_KERNEL
int retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT);
if (retval < 0 && retval != -ENOENT) {
return retval;
}
#endif
/* Reset module to hardware defaults. */
rtc_reset();
@ -330,3 +335,5 @@ static int sys_clock_driver_init(void) @@ -330,3 +335,5 @@ static int sys_clock_driver_init(void)
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
/* clang-format on */

12
dts/arm/atmel/samc21.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2022 Kamil Serwus
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,11 +23,12 @@ @@ -22,11 +23,12 @@
interrupt-names = "resrdy";
clocks = <&gclk 34>, <&mclk 0x1c 18>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
#io-channel-cells = <1>;
gclk = <0>;
prescaler = <4>;
};
@ -36,6 +38,8 @@ @@ -36,6 +38,8 @@
interrupts = <13 0>;
clocks = <&gclk 23>, <&mclk 0x1c 5>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -45,6 +49,8 @@ @@ -45,6 +49,8 @@
interrupts = <14 0>;
clocks = <&gclk 25>, <&mclk 0x1c 6>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -55,6 +61,8 @@ @@ -55,6 +61,8 @@
interrupt-names = "int0";
clocks = <&gclk 26>, <&mclk 0x10 8>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
@ -68,6 +76,8 @@ @@ -68,6 +76,8 @@
interrupt-names = "int0";
clocks = <&gclk 27>, <&mclk 0x10 9>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;

41
dts/arm/atmel/samc2x.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2022 Kamil Serwus
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -64,7 +65,6 @@ @@ -64,7 +65,6 @@
compatible = "atmel,sam0-nvmctrl";
reg = <0x41004000 0x22>;
interrupts = <6 0>;
#address-cells = <1>;
#size-cells = <1>;
@ -78,17 +78,25 @@ @@ -78,17 +78,25 @@
};
mclk: mclk@40000800 {
compatible = "atmel,samc2x-mclk";
compatible = "atmel,sam0-mclk";
reg = <0x40000800 0x400>;
#clock-cells = <2>;
};
osc32kctrl: osc32kctrl@40001400 {
compatible = "atmel,sam0-osc32kctrl";
reg = <0x40001400 0x400>;
#clock-cells = <0>;
#atmel,assigned-clock-cells = <1>;
};
gclk: gclk@40001c00 {
compatible = "atmel,samc2x-gclk";
compatible = "atmel,sam0-gclk";
reg = <0x40001c00 0x400>;
#clock-cells = <1>;
#atmel,assigned-clock-cells = <1>;
};
eic: eic@40002800 {
@ -124,11 +132,12 @@ @@ -124,11 +132,12 @@
interrupt-names = "resrdy";
clocks = <&gclk 33>, <&mclk 0x1c 17>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
#io-channel-cells = <1>;
gclk = <0>;
prescaler = <4>;
};
@ -138,6 +147,8 @@ @@ -138,6 +147,8 @@
interrupts = <9 0>;
clocks = <&gclk 19>, <&mclk 0x1c 1>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -147,6 +158,8 @@ @@ -147,6 +158,8 @@
interrupts = <10 0>;
clocks = <&gclk 20>, <&mclk 0x1c 2>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -156,6 +169,8 @@ @@ -156,6 +169,8 @@
interrupts = <11 0>;
clocks = <&gclk 21>, <&mclk 0x1c 3>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -165,6 +180,8 @@ @@ -165,6 +180,8 @@
interrupts = <12 0>;
clocks = <&gclk 22>, <&mclk 0x1c 4>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -174,6 +191,8 @@ @@ -174,6 +191,8 @@
interrupts = <17 0>;
clocks = <&gclk 28>, <&mclk 0x1c 9>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -186,6 +205,8 @@ @@ -186,6 +205,8 @@
interrupts = <18 0>;
clocks = <&gclk 28>, <&mclk 0x1c 10>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -198,6 +219,8 @@ @@ -198,6 +219,8 @@
interrupts = <19 0>;
clocks = <&gclk 29>, <&mclk 0x1c 11>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;
@ -244,11 +267,13 @@ @@ -244,11 +267,13 @@
rtc: rtc@40002400 {
compatible = "atmel,sam0-rtc";
reg = <0x40002400 0x1C>;
interrupts = <3 0>;
reg = <0x40002400 0x24>;
interrupts = <2 0>;
clocks = <&osc32kctrl>, <&mclk 0x14 9>;
clock-names = "OSC32KCTRL", "MCLK";
atmel,assigned-clocks = <&osc32kctrl 0>;
atmel,assigned-clock-names = "OSC32KCTRL";
status = "disabled";
clock-generator = <0>;
};
};
};

37
dts/arm/atmel/samd20.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 Sean Nyekjaer
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,6 +21,8 @@ @@ -20,6 +21,8 @@
interrupts = <13 0>;
clocks = <&gclk 0x13>, <&pm 0x20 8>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -29,6 +32,8 @@ @@ -29,6 +32,8 @@
interrupts = <15 0>;
clocks = <&gclk 0x14>, <&pm 0x20 10>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -38,6 +43,8 @@ @@ -38,6 +43,8 @@
interrupts = <19 0>;
clocks = <&gclk 0x16>, <&pm 0x20 14>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
};
@ -47,48 +54,71 @@ @@ -47,48 +54,71 @@
interrupts = <23 0>;
clocks = <&gclk 26>, <&pm 0x20 18>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&rtc {
clocks = <&gclk 2>, <&pm 0x18 5>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 4>;
atmel,assigned-clock-names = "GCLK";
};
&sercom0 {
interrupts = <7 0>;
clocks = <&gclk 0xd>, <&pm 0x20 2>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom1 {
interrupts = <8 0>;
clocks = <&gclk 0xe>, <&pm 0x20 3>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom2 {
interrupts = <9 0>;
clocks = <&gclk 0xf>, <&pm 0x20 4>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom3 {
interrupts = <10 0>;
clocks = <&gclk 0x10>, <&pm 0x20 5>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom4 {
interrupts = <11 0>;
clocks = <&gclk 0x11>, <&pm 0x20 6>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom5 {
interrupts = <12 0>;
clocks = <&gclk 0x12>, <&pm 0x20 7>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&tc4 {
interrupts = <17 0>;
clocks = <&gclk 0x15>, <&pm 0x20 12>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&adc {
@ -96,4 +126,11 @@ @@ -96,4 +126,11 @@
interrupt-names = "resrdy";
clocks = <&gclk 0x17>, <&pm 0x20 16>;
clock-names = "GCLK", "PM";
/*
* 2.1 MHz is ADC max clock
* 8 MHz GCLK / 4 = 2 MHz
* Generator 3: DFLL48M / 8MHz
*/
atmel,assigned-clocks = <&gclk 3>;
atmel,assigned-clock-names = "GCLK";
};

43
dts/arm/atmel/samd21.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -40,6 +41,8 @@ @@ -40,6 +41,8 @@
interrupts = <21 0>;
clocks = <&gclk 0x1d>, <&pm 0x20 14>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -49,6 +52,8 @@ @@ -49,6 +52,8 @@
interrupts = <15 0>;
clocks = <&gclk 26>, <&pm 0x20 8>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -61,6 +66,8 @@ @@ -61,6 +66,8 @@
interrupts = <16 0>;
clocks = <&gclk 26>, <&pm 0x20 9>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;
@ -73,6 +80,8 @@ @@ -73,6 +80,8 @@
interrupts = <17 0>;
clocks = <&gclk 27>, <&pm 0x20 10>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;
@ -85,53 +94,83 @@ @@ -85,53 +94,83 @@
interrupts = <25 0>;
clocks = <&gclk 33>, <&pm 0x20 18>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&rtc {
clocks = <&gclk 4>, <&pm 0x18 5>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 4>;
atmel,assigned-clock-names = "GCLK";
};
&sercom0 {
interrupts = <9 0>;
clocks = <&gclk 0x14>, <&pm 0x20 2>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom1 {
interrupts = <10 0>;
clocks = <&gclk 0x15>, <&pm 0x20 3>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom2 {
interrupts = <11 0>;
clocks = <&gclk 0x16>, <&pm 0x20 4>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom3 {
interrupts = <12 0>;
clocks = <&gclk 0x17>, <&pm 0x20 5>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom4 {
interrupts = <13 0>;
clocks = <&gclk 0x18>, <&pm 0x20 6>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom5 {
interrupts = <14 0>;
clocks = <&gclk 0x19>, <&pm 0x20 7>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&tc4 {
interrupts = <19 0>;
clocks = <&gclk 0x1c>, <&pm 0x20 12>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&adc {
clocks = <&gclk 0x1e>, <&pm 0x20 16>;
clock-names = "GCLK", "PM";
interrupts = <23 0>;
interrupt-names = "resrdy";
clocks = <&gclk 0x1e>, <&pm 0x20 16>;
clock-names = "GCLK", "PM";
/*
* 2.1 MHz is ADC max clock
* 8 MHz GCLK / 4 = 2 MHz
* Generator 3: DFLL48M / 8MHz
*/
atmel,assigned-clocks = <&gclk 3>;
atmel,assigned-clock-names = "GCLK";
};

13
dts/arm/atmel/samd2x.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Google LLC.
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -77,7 +78,7 @@ @@ -77,7 +78,7 @@
};
pm: pm@40000400 {
compatible = "atmel,samd2x-pm";
compatible = "atmel,sam0-mclk";
reg = <0x40000400 0x400>;
interrupts = <0 0>;
@ -85,10 +86,11 @@ @@ -85,10 +86,11 @@
};
gclk: gclk@40000c00 {
compatible = "atmel,samd2x-gclk";
compatible = "atmel,sam0-gclk";
reg = <0x40000c00 0x400>;
#clock-cells = <1>;
#atmel,assigned-clock-cells = <1>;
};
eic: eic@40001800 {
@ -188,8 +190,6 @@ @@ -188,8 +190,6 @@
reg = <0x40001400 0x1C>;
interrupts = <3 0>;
status = "disabled";
clock-generator = <0>;
};
adc: adc@42004000 {
@ -199,11 +199,6 @@ @@ -199,11 +199,6 @@
#io-channel-cells = <1>;
/*
* 2.1 MHz max, so clock it with the
* 8 MHz GCLK / 4 = 2 MHz
*/
gclk = <3>;
prescaler = <4>;
};

88
dts/arm/atmel/samd5x.dtsi

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
/*
* Copyright (c) 2019 ML!PA Consulting GmbH
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -88,17 +89,25 @@ @@ -88,17 +89,25 @@
};
mclk: mclk@40000800 {
compatible = "atmel,samd5x-mclk";
compatible = "atmel,sam0-mclk";
reg = <0x40000800 0x400>;
#clock-cells = <2>;
};
osc32kctrl: osc32kctrl@40001400 {
compatible = "atmel,sam0-osc32kctrl";
reg = <0x40001400 0x400>;
#clock-cells = <0>;
#atmel,assigned-clock-cells = <1>;
};
gclk: gclk@40001c00 {
compatible = "atmel,samd5x-gclk";
compatible = "atmel,sam0-gclk";
reg = <0x40001c00 0x400>;
#clock-cells = <1>;
#atmel,assigned-clock-cells = <1>;
};
nvmctrl: nvmctrl@41004000 {
@ -168,6 +177,8 @@ @@ -168,6 +177,8 @@
interrupts = <46 0>, <47 0>, <48 0>, <49 0>;
clocks = <&gclk 7>, <&mclk 0x14 12>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -177,6 +188,8 @@ @@ -177,6 +188,8 @@
interrupts = <50 0>, <51 0>, <52 0>, <53 0>;
clocks = <&gclk 8>, <&mclk 0x14 13>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -186,6 +199,8 @@ @@ -186,6 +199,8 @@
interrupts = <54 0>, <55 0>, <56 0>, <57 0>;
clocks = <&gclk 23>, <&mclk 0x18 9>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -195,6 +210,8 @@ @@ -195,6 +210,8 @@
interrupts = <58 0>, <59 0>, <60 0>, <61 0>;
clocks = <&gclk 24>, <&mclk 0x18 10>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -204,6 +221,8 @@ @@ -204,6 +221,8 @@
interrupts = <62 0>, <63 0>, <64 0>, <65 0>;
clocks = <&gclk 34>, <&mclk 0x20 0>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -213,6 +232,8 @@ @@ -213,6 +232,8 @@
interrupts = <66 0>, <67 0>, <68 0>, <69 0>;
clocks = <&gclk 35>, <&mclk 0x20 1>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -222,6 +243,8 @@ @@ -222,6 +243,8 @@
interrupts = <70 0>, <71 0>, <72 0>, <73 0>;
clocks = <&gclk 36>, <&mclk 0x20 2>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -231,6 +254,8 @@ @@ -231,6 +254,8 @@
interrupts = <74 0>, <75 0>, <76 0>, <77 0>;
clocks = <&gclk 37>, <&mclk 0x20 3>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -299,11 +324,13 @@ @@ -299,11 +324,13 @@
rtc: rtc@40002400 {
compatible = "atmel,sam0-rtc";
reg = <0x40002400 0x1C>;
reg = <0x40002400 0x40>;
interrupts = <11 0>;
clocks = <&osc32kctrl>, <&mclk 0x14 9>;
clock-names = "OSC32KCTRL", "MCLK";
atmel,assigned-clocks = <&osc32kctrl 0>;
atmel,assigned-clock-names = "OSC32KCTRL";
status = "disabled";
clock-generator = <0>;
};
adc0: adc@43001c00 {
@ -313,17 +340,20 @@ @@ -313,17 +340,20 @@
interrupt-names = "overrun", "resrdy";
clocks = <&gclk 40>, <&mclk 0x20 7>;
clock-names = "GCLK", "MCLK";
status = "disabled";
#io-channel-cells = <1>;
/*
* 16 MHz max, source clock must not exceed 100 MHz.
* 16 MHz is ADC max clock, source clock must not exceed 100 MHz.
* - table 54-8, section 54.6, page 2020
* - table 54-24, section 54.10.4, page 2031
* -> 48 MHz GCLK(2) / 4 = 12 MHz
* 48 MHz GCLK / 4 = 12 MHz
* Generator 2: DFLL48M / 4
*/
gclk = <2>;
atmel,assigned-clocks = <&gclk 2>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
#io-channel-cells = <1>;
prescaler = <4>;
calib-offset = <0>;
};
@ -335,17 +365,19 @@ @@ -335,17 +365,19 @@
interrupt-names = "overrun", "resrdy";
clocks = <&gclk 41>, <&mclk 0x20 8>;
clock-names = "GCLK", "MCLK";
status = "disabled";
#io-channel-cells = <1>;
/*
* 16 MHz max, source clock must not exceed 100 MHz.
* 16 MHz is ADC max clock, source clock must not exceed 100 MHz.
* - table 54-8, section 54.6, page 2020
* - table 54-24, section 54.10.4, page 2031
* -> 48 MHz GCLK(2) / 4 = 12 MHz
* 48 MHz GCLK / 4 = 12 MHz
* Generator 2: DFLL48M / 4
*/
gclk = <2>;
atmel,assigned-clocks = <&gclk 2>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
#io-channel-cells = <1>;
prescaler = <4>;
calib-offset = <14>;
};
@ -356,6 +388,8 @@ @@ -356,6 +388,8 @@
interrupts = <107 0>;
clocks = <&gclk 9>, <&mclk 0x14 14>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -365,6 +399,8 @@ @@ -365,6 +399,8 @@
interrupts = <109 0>;
clocks = <&gclk 26>, <&mclk 0x18 13>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -374,6 +410,8 @@ @@ -374,6 +410,8 @@
interrupts = <111 0>;
clocks = <&gclk 30>, <&mclk 0x1c 5>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -383,6 +421,8 @@ @@ -383,6 +421,8 @@
interrupts = <113 0>;
clocks = <&gclk 39>, <&mclk 0x20 5>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
};
@ -393,6 +433,8 @@ @@ -393,6 +433,8 @@
<90 0>, <91 0>;
clocks = <&gclk 25>, <&mclk 0x18 11>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <6>;
@ -405,6 +447,8 @@ @@ -405,6 +447,8 @@
interrupts = <92 0>, <93 0>, <94 0>, <95 0>, <96 0>;
clocks = <&gclk 25>, <&mclk 0x18 12>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -417,6 +461,8 @@ @@ -417,6 +461,8 @@
interrupts = <97 0>, <98 0>, <99 0>, <100 0>;
clocks = <&gclk 29>, <&mclk 0x1c 3>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <3>;
@ -429,6 +475,8 @@ @@ -429,6 +475,8 @@
interrupts = <101 0>, <102 0>, <103 0>;
clocks = <&gclk 29>, <&mclk 0x1c 4>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;
@ -441,6 +489,8 @@ @@ -441,6 +489,8 @@
interrupts = <104 0>, <105 0>, <106 0>;
clocks = <&gclk 38>, <&mclk 0x20 4>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;

5
dts/arm/atmel/same5x.dtsi

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/*
* Copyright (c) 2020 Stephanos Ioannidis <root@stephanos.io>
* Copyright (c) 2023 Sebastian Schlupp
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -36,6 +37,8 @@ @@ -36,6 +37,8 @@
interrupt-names = "int0", "int1";
clocks = <&gclk 27>, <&mclk 0x10 17>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
@ -49,6 +52,8 @@ @@ -49,6 +52,8 @@
interrupt-names = "int0", "int1";
clocks = <&gclk 28>, <&mclk 0x10 18>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;

29
dts/arm/atmel/saml21.dtsi

@ -21,6 +21,8 @@ @@ -21,6 +21,8 @@
interrupts = <14 0>;
clocks = <&gclk 25>, <&mclk 0x1c 5>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -33,6 +35,8 @@ @@ -33,6 +35,8 @@
interrupts = <15 0>;
clocks = <&gclk 25>, <&mclk 0x1c 6>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <4>;
@ -45,6 +49,8 @@ @@ -45,6 +49,8 @@
interrupts = <16 0>;
clocks = <&gclk 26>, <&mclk 0x1c 7>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
status = "disabled";
channels = <2>;
@ -57,48 +63,64 @@ @@ -57,48 +63,64 @@
interrupts = <24 0>;
clocks = <&gclk 32>, <&mclk 0x1c 12>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom0 {
interrupts = <8 0>;
clocks = <&gclk 18>, <&mclk 0x1c 0>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom1 {
interrupts = <9 0>;
clocks = <&gclk 19>, <&mclk 0x1c 1>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom2 {
interrupts = <10 0>;
clocks = <&gclk 20>, <&mclk 0x1c 2>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom3 {
interrupts = <11 0>;
clocks = <&gclk 21>, <&mclk 0x1c 3>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom4 {
interrupts = <12 0>;
clocks = <&gclk 22>, <&mclk 0x1c 4>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&sercom5 {
interrupts = <13 0>;
clocks = <&gclk 24>, <&mclk 0x20 1>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&tc4 {
interrupts = <21 0>;
clocks = <&gclk 29>, <&mclk 0x20 2>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 0>;
atmel,assigned-clock-names = "GCLK";
};
&adc {
@ -106,4 +128,11 @@ @@ -106,4 +128,11 @@
interrupt-names = "resrdy";
clocks = <&gclk 30>, <&mclk 0x20 3>;
clock-names = "GCLK", "MCLK";
/*
* 16 MHz is ADC max clock
* 48 MHz DFLL / 2 / 2 = 12 MHz
* Generator 3: 48MHz
*/
atmel,assigned-clocks = <&gclk 3>;
atmel,assigned-clock-names = "GCLK";
};

32
dts/arm/atmel/saml2x.dtsi

@ -32,8 +32,8 @@ @@ -32,8 +32,8 @@
};
chosen {
zephyr,flash-controller = &nvmctrl;
zephyr,entropy = &trng;
zephyr,flash-controller = &nvmctrl;
};
cpus {
@ -80,26 +80,27 @@ @@ -80,26 +80,27 @@
};
};
pm: pm@40000400 {
compatible = "atmel,saml2x-pm";
mclk: mclk@40000400 {
compatible = "atmel,sam0-mclk";
reg = <0x40000400 0x400>;
interrupts = <0 0>;
#clock-cells = <2>;
};
mclk: mclk@40000400 {
compatible = "atmel,saml2x-mclk";
reg = <0x40000400 0x400>;
osc32kctrl: osc32kctrl@40001000 {
compatible = "atmel,sam0-osc32kctrl";
reg = <0x40001000 0x400>;
#clock-cells = <2>;
#clock-cells = <0>;
#atmel,assigned-clock-cells = <1>;
};
gclk: gclk@40001800 {
compatible = "atmel,saml2x-gclk";
compatible = "atmel,sam0-gclk";
reg = <0x40001800 0x400>;
#clock-cells = <1>;
#atmel,assigned-clock-cells = <1>;
};
dmac: dmac@44000400 {
@ -195,11 +196,13 @@ @@ -195,11 +196,13 @@
rtc: rtc@40002000 {
compatible = "atmel,sam0-rtc";
reg = <0x40002000 0x1c>;
reg = <0x40002000 0x44>;
interrupts = <2 0>;
clocks = <&osc32kctrl>, <&mclk 0x14 8>;
clock-names = "OSC32KCTRL", "MCLK";
atmel,assigned-clocks = <&osc32kctrl 0>;
atmel,assigned-clock-names = "OSC32KCTRL";
status = "disabled";
clock-generator = <0>;
};
adc: adc@43000c00 {
@ -209,11 +212,6 @@ @@ -209,11 +212,6 @@
#io-channel-cells = <1>;
/*
* 16 MHz max, so clock it with the
* 48 MHz DFLL / 2 / 2 = 12 MHz
*/
gclk = <3>;
prescaler = <2>;
};

1
dts/arm/atmel/samr34.dtsi

@ -28,6 +28,7 @@ @@ -28,6 +28,7 @@
#atmel,pin-cells = <2>;
#gpio-cells = <2>;
gpio-controller;
};
};

9
dts/bindings/adc/atmel,sam0-adc.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 family ADC
@ -8,6 +9,7 @@ compatible: "atmel,sam0-adc" @@ -8,6 +9,7 @@ compatible: "atmel,sam0-adc"
include:
- name: adc-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -22,10 +24,11 @@ properties: @@ -22,10 +24,11 @@ properties:
clock-names:
required: true
gclk:
type: int
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
description: generic clock generator source
prescaler:
type: int

7
dts/bindings/arm/atmel,sam0-sercom.yaml

@ -1,8 +1,13 @@ @@ -1,8 +1,13 @@
# Copyright (c) 2024, Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 multi-protocol (UART, SPI, I2C) SERCOM unit
compatible: "atmel,sam0-sercom"
include: base.yaml
include:
- name: base.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:

19
dts/bindings/arm/atmel,samd2x-pm.yaml

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
# Copyright (c) 2020, Linaro Limited
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMD2x Power Manager (PM)
compatible: "atmel,samd2x-pm"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 2
clock-cells:
- offset
- bit

10
dts/bindings/can/atmel,sam0-can.yaml

@ -1,3 +1,6 @@ @@ -1,3 +1,6 @@
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Specialization of Bosch m_can CAN FD controller for Atmel SAM0
compatible: "atmel,sam0-can"
@ -5,6 +8,7 @@ compatible: "atmel,sam0-can" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-can"
include:
- name: bosch,m_can-base.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -22,6 +26,12 @@ properties: @@ -22,6 +26,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
divider:
type: int
required: true

66
dts/bindings/clock/atmel,sam0-gclk.yaml

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMD0 Generic Clock Controller (GCLK)
compatible: "atmel,sam0-gclk"
include:
- base.yaml
- clock-controller.yaml
- atmel,assigned-clocks.yaml
properties:
reg:
required: true
"#clock-cells":
const: 1
description: |
- The ID cell is the peripheral identification.
These information are used on GCLK->CLKCTRL register to select the
clock for an specific peripheral.
Example 1: Connect the XOSC32K to RTC on SAMD2x
Assuming that generator 2 have the following configuration:
GLKC->GENCTRL:
SRC: 5 (XOSC32K)
ID: 2 (Generator 2)
Then to enable the clock to the peripheral
Generator: 2
Identificator: 4 (GCLK_RTC)
&rtc {
/* The peripheral is fixed and it is defined at soc devictree
* clocks property
*/
clocks = <&gclk 4>, <&pm 0x18 5>;
clock-names = "GCLK", "PM";
/* The generator is user selectable and because of that it is
* defined at board
*/
atmel,assigned-clocks = <&gclk 2>;
atmel,assigned-clock-names = "GCLK";
};
Example 2: Connect the XOSC32K to RTC on SAMD5x
In the SAMD5x the RTC is direct connected on the OSC32KCTRL and no
generator is used. See atmel,sam0-osc32kctrl.yaml for reference.
"#atmel,assigned-clock-cells":
required: true
type: int
const: 1
description: |
- The GEN cell is an integer number that represents the index of
the generic clock generator. It is usually a number between 0~8
but could be more depending of the SoC.
clock-cells:
- id
atmel,assigned-clock-cells:
- gen

48
dts/bindings/clock/atmel,sam0-mclk.yaml

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 Main Clock Controller (MCLK)
compatible: "atmel,sam0-mclk"
include:
- base.yaml
- clock-controller.yaml
properties:
reg:
required: true
"#clock-cells":
const: 2
description: |
- The OFFSET cell is an address of a bus mask. The buses can be
AHB and APB[A-D]. Each bus mask can enable a paripheral clock
selecting the BIT position in the mask.
- The BIT cell is the peripheral bit mask.
These information are used on PM and MCLK register to select the
clock for an specific peripheral. The generator 2 is used on this
example and can be defined by the user at board.
Example: Enable SERCOM0 on SAMD21
&sercom0 {
clocks = <&gclk 0x14>, <&pm 0x20 2>;
clock-names = "GCLK", "PM";
atmel,assigned-clocks = <&gclk 2>;
atmel,assigned-clock-names = "GCLK";
};
Example: Enable SERCOM0 on SAME54
&sercom0 {
clocks = <&gclk 7>, <&mclk 0x14 12>;
clock-names = "GCLK", "MCLK";
atmel,assigned-clocks = <&gclk 2>;
atmel,assigned-clock-names = "GCLK";
};
clock-cells:
- offset
- bit

38
dts/bindings/clock/atmel,sam0-osc32kctrl.yaml

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 32kHz Oscillator Controller (OSC32KCTRL)
compatible: "atmel,sam0-osc32kctrl"
include:
- base.yaml
- clock-controller.yaml
- atmel,assigned-clocks.yaml
properties:
reg:
required: true
"#clock-cells":
const: 0
"#atmel,assigned-clock-cells":
required: true
type: int
const: 1
description: |
It selects the OSC32CTRL clock to be routed to RTC peripheral
Example: Connect the XOSC32K to RTC on SAMD5x
&rtc {
clocks = <&mclk 0x14 9 &osc32kctrl>;
clock-names = "MCLK", "OSC32KCTRL";
atmel,assigned-clocks = <&osc32kctrl 4>;
atmel,assigned-clock-names = "OSC32KCTRL";
};
atmel,assigned-clock-cells:
- src

18
dts/bindings/clock/atmel,samc2x-gclk.yaml

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
# Copyright (c) 2022 Kamil Serwus
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMC2x Generic Clock Controller (GCLK)
compatible: "atmel,samc2x-gclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 1
clock-cells:
- periph_ch

19
dts/bindings/clock/atmel,samc2x-mclk.yaml

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
# Copyright (c) 2022, Kamil Serwus
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMC2x Generic Clock Controller (MCLK)
compatible: "atmel,samc2x-mclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 2
clock-cells:
- offset
- bit

18
dts/bindings/clock/atmel,samd2x-gclk.yaml

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
# Copyright (c) 2020, Linaro Limited
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMD2x Generic Clock Controller (GCLK)
compatible: "atmel,samd2x-gclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 1
clock-cells:
- clkctrl_id

18
dts/bindings/clock/atmel,samd5x-gclk.yaml

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
# Copyright (c) 2020, Linaro Limited
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMD5x Generic Clock Controller (GCLK)
compatible: "atmel,samd5x-gclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 1
clock-cells:
- periph_ch

19
dts/bindings/clock/atmel,samd5x-mclk.yaml

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
# Copyright (c) 2020, Linaro Limited
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAMD5x Generic Clock Controller (MCLK)
compatible: "atmel,samd5x-mclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 2
clock-cells:
- offset
- bit

18
dts/bindings/clock/atmel,saml2x-gclk.yaml

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
# Copyright (c) 2021 Argentum Systems Ltd.
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAML2x Generic Clock Controller (GCLK)
compatible: "atmel,saml2x-gclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 1
clock-cells:
- periph_ch

19
dts/bindings/clock/atmel,saml2x-mclk.yaml

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
# Copyright (c) 2021 Argentum Systems Ltd.
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAML2x Generic Clock Controller (MCLK)
compatible: "atmel,saml2x-mclk"
include: [clock-controller.yaml, base.yaml]
properties:
reg:
required: true
"#clock-cells":
const: 2
clock-cells:
- offset
- bit

8
dts/bindings/counter/atmel,sam0-tc32.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 basic timer counter (TC) operating in 32-bit wide mode
@ -8,6 +9,7 @@ compatible: "atmel,sam0-tc32" @@ -8,6 +9,7 @@ compatible: "atmel,sam0-tc32"
include:
- name: base.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -22,6 +24,12 @@ properties: @@ -22,6 +24,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
prescaler:
type: int
description: Timer prescaler

8
dts/bindings/dac/atmel,sam0-dac.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2020 Google LLC.
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 family DAC
@ -8,6 +9,7 @@ compatible: "atmel,sam0-dac" @@ -8,6 +9,7 @@ compatible: "atmel,sam0-dac"
include:
- name: dac-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -19,6 +21,12 @@ properties: @@ -19,6 +21,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
reference:
type: string
description: Reference voltage source

8
dts/bindings/i2c/atmel,sam0-i2c.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 series SERCOM I2C node
@ -8,6 +9,7 @@ compatible: "atmel,sam0-i2c" @@ -8,6 +9,7 @@ compatible: "atmel,sam0-i2c"
include:
- name: i2c-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -22,6 +24,12 @@ properties: @@ -22,6 +24,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
dmas:
description: |
Optional TX & RX dma specifiers. Each specifier will have a phandle

8
dts/bindings/pwm/atmel,sam0-tc-pwm.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2020 Google LLC.
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 TC in PWM mode
@ -9,6 +10,7 @@ include: @@ -9,6 +10,7 @@ include:
- name: base.yaml
- name: pwm-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -23,6 +25,12 @@ properties: @@ -23,6 +25,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
channels:
type: int
required: true

8
dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2020 Google LLC.
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 TCC in PWM mode
@ -9,6 +10,7 @@ include: @@ -9,6 +10,7 @@ include:
- name: base.yaml
- name: pwm-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -23,6 +25,12 @@ properties: @@ -23,6 +25,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
channels:
type: int
required: true

15
dts/bindings/rtc/atmel,sam0-rtc.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2018 omSquare s.r.o.
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 RTC
@ -8,12 +9,20 @@ compatible: "atmel,sam0-rtc" @@ -8,12 +9,20 @@ compatible: "atmel,sam0-rtc"
include:
- name: rtc.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
required: true
clock-generator:
type: int
description: clock generator index
clocks:
required: true
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true

10
dts/bindings/serial/atmel,sam0-uart.yaml

@ -1,3 +1,6 @@ @@ -1,3 +1,6 @@
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 SERCOM UART driver
compatible: "atmel,sam0-uart"
@ -5,6 +8,7 @@ compatible: "atmel,sam0-uart" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-uart"
include:
- name: uart-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -19,6 +23,12 @@ properties: @@ -19,6 +23,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
rxpo:
type: int
required: true

8
dts/bindings/spi/atmel,sam0-spi.yaml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
# Copyright (c) 2018, Google LLC.
# Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
description: Atmel SAM0 SERCOM SPI controller
@ -8,6 +9,7 @@ compatible: "atmel,sam0-spi" @@ -8,6 +9,7 @@ compatible: "atmel,sam0-spi"
include:
- name: spi-controller.yaml
- name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties:
reg:
@ -19,6 +21,12 @@ properties: @@ -19,6 +21,12 @@ properties:
clock-names:
required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
dipo:
type: int
required: true

26
soc/atmel/sam0/common/atmel_sam0_dt.h

@ -14,12 +14,28 @@ @@ -14,12 +14,28 @@
/* clang-format off */
/* Helper macro to get MCLK register address for corresponding
* that has corresponding clock enable bit.
#define ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, cell) \
(volatile uint32_t *) \
(DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, cell)) + \
DT_INST_CLOCKS_CELL_BY_NAME(n, cell, offset))
#define ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, name, cell) \
BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, name, cell))
/* Helper macro to get register address that control peripheral clock
* enable bit.
*/
#define ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \
(ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, mclk)), \
(ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, pm)))
/* Helper macro to get peripheral clock bit mask.
*/
#define MCLK_MASK_DT_INT_REG_ADDR(n) \
(DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, mclk)) + \
DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, offset))
#define ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, cell) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \
(ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, mclk, cell)), \
(ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, pm, cell)))
/* Helper macros for use with ATMEL SAM0 DMAC controller
* return 0xff as default value if there is no 'dmas' property

8
tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay

@ -1,18 +1,26 @@ @@ -1,18 +1,26 @@
/*
* Copyright (c) 2020 Stephanos Ioannidis <root@stephanos.io>
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
&dmac {
status = "okay";
};
&sercom4 {
/* Internally connect MOSI to MISO for loop-back operation */
dipo = <3>;
dopo = <2>;
/* Assign a CS pin */
cs-gpios = <&portb 28 GPIO_ACTIVE_LOW>;
/* Configure DMA */
dmas = <&dmac 0 12>, <&dmac 1 13>;
dma-names = "rx", "tx";
slow@0 {
compatible = "test-spi-loopback-slow";
reg = <0>;

Loading…
Cancel
Save