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>
This commit is contained in:
Gerson Fernando Budke 2024-12-14 11:56:38 +01:00 committed by Benjamin Cabé
commit ea7922195b
44 changed files with 882 additions and 574 deletions

View file

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

View file

@ -3,6 +3,7 @@
* Copyright (c) 2021 Alexander Wachter * Copyright (c) 2021 Alexander Wachter
* Copyright (c) 2022 Kamil Serwus * Copyright (c) 2022 Kamil Serwus
* Copyright (c) 2023 Sebastian Schlupp * Copyright (c) 2023 Sebastian Schlupp
* Copyright (c) 2024 Gerson Fernando Budke <nandojve@gmail.com>
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -17,6 +18,8 @@
LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL); LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL);
/* clang-format off */
#define DT_DRV_COMPAT atmel_sam0_can #define DT_DRV_COMPAT atmel_sam0_can
struct can_sam0_config { struct can_sam0_config {
@ -26,7 +29,8 @@ struct can_sam0_config {
const struct pinctrl_dev_config *pcfg; const struct pinctrl_dev_config *pcfg;
volatile uint32_t *mclk; volatile uint32_t *mclk;
uint32_t mclk_mask; uint32_t mclk_mask;
uint16_t gclk_core_id; uint32_t gclk_gen;
uint16_t gclk_id;
int divider; int divider;
}; };
@ -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) 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*/ /* Enable the GLCK7 with DIV*/
#if defined(CONFIG_SOC_SERIES_SAME51) || defined(CONFIG_SOC_SERIES_SAME54) #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*/ /*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)
| GCLK_GENCTRL_DIV(cfg->divider) | GCLK_GENCTRL_DIV(cfg->divider)
| GCLK_GENCTRL_GENEN; | GCLK_GENCTRL_GENEN;
#endif #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) static int can_sam0_init(const struct device *dev)
@ -204,6 +206,9 @@ static void config_can_##inst##_irq(void) \
irq_enable(DT_INST_IRQ_BY_NAME(inst, int0, irq)); \ 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) \ #define CAN_SAM0_CFG_INST(inst) \
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \ CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \
CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \ CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \
@ -211,9 +216,10 @@ static void config_can_##inst##_irq(void) \
static const struct can_sam0_config can_sam0_cfg_##inst = { \ static const struct can_sam0_config can_sam0_cfg_##inst = { \
.base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \ .base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \
.mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \ .mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \ .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), \ .divider = DT_INST_PROP(inst, divider), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
.config_irq = config_can_##inst##_irq, \ .config_irq = config_can_##inst##_irq, \
@ -243,3 +249,5 @@ static void config_can_##inst##_irq(void) \
CAN_SAM0_DEVICE_INST(inst) CAN_SAM0_DEVICE_INST(inst)
DT_INST_FOREACH_STATUS_OKAY(CAN_SAM0_INST) DT_INST_FOREACH_STATUS_OKAY(CAN_SAM0_INST)
/* clang-format on */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 description: Atmel SAM0 multi-protocol (UART, SPI, I2C) SERCOM unit
compatible: "atmel,sam0-sercom" compatible: "atmel,sam0-sercom"
include: base.yaml include:
- name: base.yaml
- name: atmel,assigned-clocks.yaml
properties: properties:
reg: reg:

View file

@ -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

View file

@ -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 description: Specialization of Bosch m_can CAN FD controller for Atmel SAM0
compatible: "atmel,sam0-can" compatible: "atmel,sam0-can"
@ -5,6 +8,7 @@ compatible: "atmel,sam0-can"
include: include:
- name: bosch,m_can-base.yaml - name: bosch,m_can-base.yaml
- name: pinctrl-device.yaml - name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties: properties:
reg: reg:
@ -22,6 +26,12 @@ properties:
clock-names: clock-names:
required: true required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
divider: divider:
type: int type: int
required: true required: true

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 description: Atmel SAM0 SERCOM UART driver
compatible: "atmel,sam0-uart" compatible: "atmel,sam0-uart"
@ -5,6 +8,7 @@ compatible: "atmel,sam0-uart"
include: include:
- name: uart-controller.yaml - name: uart-controller.yaml
- name: pinctrl-device.yaml - name: pinctrl-device.yaml
- name: atmel,assigned-clocks.yaml
properties: properties:
reg: reg:
@ -19,6 +23,12 @@ properties:
clock-names: clock-names:
required: true required: true
atmel,assigned-clocks:
required: true
atmel,assigned-clock-names:
required: true
rxpo: rxpo:
type: int type: int
required: true required: true

View file

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

View file

@ -14,12 +14,28 @@
/* clang-format off */ /* clang-format off */
/* Helper macro to get MCLK register address for corresponding #define ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, cell) \
* that has corresponding clock enable bit. (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 MCLK_MASK_DT_INT_REG_ADDR(n) \ #define ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n) \
(DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, mclk)) + \ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \
DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, offset)) (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 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 /* Helper macros for use with ATMEL SAM0 DMAC controller
* return 0xff as default value if there is no 'dmas' property * return 0xff as default value if there is no 'dmas' property

View file

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