diff --git a/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi b/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi index 39db2783c37a..87586b6a0d88 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi +++ b/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi @@ -140,4 +140,10 @@ ; }; }; + + pwm2_default: pwm2_default{ + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/ambiq/apollo3_evb/apollo3_evb.dts b/boards/ambiq/apollo3_evb/apollo3_evb.dts index ed7a0494a70a..37f8b9f81335 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb.dts +++ b/boards/ambiq/apollo3_evb/apollo3_evb.dts @@ -30,6 +30,7 @@ sw1 = &button1; bootloader-led0 = &led0; mcuboot-led0 = &led0; + pwm-led0 = &pwm_led0; }; leds { @@ -74,6 +75,15 @@ zephyr,code = ; }; }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; }; &flash0 { @@ -159,8 +169,20 @@ }; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + timer-segment = "SEGMENT_B"; + pwm-type = "PWM_REPEAT"; + pinctrl-0 = <&pwm2_default>; + pinctrl-names = "default"; + status = "disabled"; + }; }; &rtc0 { diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb-pinctrl.dtsi b/boards/ambiq/apollo3p_evb/apollo3p_evb-pinctrl.dtsi index f8821a4c2f83..a6087b30843e 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb-pinctrl.dtsi +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb-pinctrl.dtsi @@ -179,4 +179,10 @@ ; }; }; + + pwm2_default: pwm2_default{ + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts index 8b3371389741..322689163665 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts @@ -26,6 +26,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + pwm-led0 = &pwm_led0; }; leds { @@ -70,6 +71,15 @@ zephyr,code = ; }; }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; }; &flash0 { @@ -137,8 +147,20 @@ }; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + timer-segment = "SEGMENT_B"; + pwm-type = "PWM_REPEAT"; + pinctrl-0 = <&pwm2_default>; + pinctrl-names = "default"; + status = "disabled"; + }; }; &rtc0 { diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi index 2cf596eadcd9..4d63b444bb73 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi +++ b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb-pinctrl.dtsi @@ -170,4 +170,11 @@ drive-strength = "0.1"; }; }; + pwm2_default: pwm2_default{ + group1 { + pinmux = ; + drive-open-drain; + drive-strength = "0.5"; + }; + }; }; diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index f33e454272e2..f701b27d8d78 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -26,6 +26,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + pwm-led0 = &pwm_led0; }; leds { @@ -60,6 +61,15 @@ status = "okay"; }; }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; }; &uart0 { @@ -75,8 +85,18 @@ status = "okay"; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + pinctrl-0 = <&pwm2_default>; + pinctrl-names = "default"; + status = "disabled"; + }; }; &rtc0 { diff --git a/boards/ambiq/apollo4p_evb/apollo4p_evb-pinctrl.dtsi b/boards/ambiq/apollo4p_evb/apollo4p_evb-pinctrl.dtsi index ccfdfd72974e..eb9a0502704a 100644 --- a/boards/ambiq/apollo4p_evb/apollo4p_evb-pinctrl.dtsi +++ b/boards/ambiq/apollo4p_evb/apollo4p_evb-pinctrl.dtsi @@ -192,4 +192,11 @@ ambiq,pull-up-ohms = <12000>; }; }; + pwm2_default: pwm2_default{ + group1 { + pinmux = ; + drive-open-drain; + drive-strength = "0.5"; + }; + }; }; diff --git a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts index 567ec2143fe9..66ecf4e5f863 100644 --- a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts +++ b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts @@ -25,6 +25,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + pwm-led0 = &pwm_led0; }; leds { @@ -59,6 +60,14 @@ status = "okay"; }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; }; &uart0 { @@ -80,8 +89,18 @@ status = "disabled"; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + pinctrl-0 = <&pwm2_default>; + pinctrl-names = "default"; + status = "disabled"; + }; }; &rtc0 { diff --git a/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi b/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi index 797ce0b96d19..df06023b66fa 100644 --- a/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi +++ b/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi @@ -380,4 +380,12 @@ drive-strength = "0.5"; }; }; + + pwm2_default: pwm2_default{ + group1 { + pinmux = ; + drive-open-drain; + drive-strength = "0.5"; + }; + }; }; diff --git a/boards/ambiq/apollo510_evb/apollo510_evb.dts b/boards/ambiq/apollo510_evb/apollo510_evb.dts index 3ed5e7859cd9..e099b90aef1b 100644 --- a/boards/ambiq/apollo510_evb/apollo510_evb.dts +++ b/boards/ambiq/apollo510_evb/apollo510_evb.dts @@ -27,6 +27,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + pwm-led0 = &pwm_led0; }; sram0: memory@SSRAM_BASE_NAME { @@ -78,6 +79,15 @@ status = "okay"; }; }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; }; &xo32m_xtal { @@ -95,8 +105,18 @@ status = "disabled"; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + pinctrl-0 = <&pwm2_default>; + pinctrl-names = "default"; + status = "disabled"; + }; }; &rtc0 { diff --git a/boards/rakwireless/rak11720/rak11720.dts b/boards/rakwireless/rak11720/rak11720.dts index 12fc1d7966b9..b4156eebfa63 100644 --- a/boards/rakwireless/rak11720/rak11720.dts +++ b/boards/rakwireless/rak11720/rak11720.dts @@ -150,32 +150,46 @@ }; }; -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; -&counter1 { - status = "okay"; +&timer1 { + counter1: counter { + status = "okay"; + }; }; -&counter2 { - status = "okay"; +&timer2 { + counter2: counter { + status = "okay"; + }; }; -&counter4 { - status = "okay"; +&timer4 { + counter4: counter { + status = "okay"; + }; }; -&counter5 { - status = "okay"; +&timer5 { + counter5: counter { + status = "okay"; + }; }; -&counter6 { - status = "okay"; +&timer6 { + counter6: counter { + status = "okay"; + }; }; -&counter7 { - status = "okay"; +&timer7 { + counter7: counter { + status = "okay"; + }; }; &gpio0_31 { diff --git a/drivers/counter/counter_ambiq_timer.c b/drivers/counter/counter_ambiq_timer.c index b9323c5f5a3d..169bed7ce571 100644 --- a/drivers/counter/counter_ambiq_timer.c +++ b/drivers/counter/counter_ambiq_timer.c @@ -16,6 +16,11 @@ LOG_MODULE_REGISTER(ambiq_counter, CONFIG_COUNTER_LOG_LEVEL); +#if defined(CONFIG_SOC_SERIES_APOLLO3X) +#define SOC_TIMER_BASE CTIMER_BASE +#elif defined(CONFIG_SOC_SERIES_APOLLO4X) || defined(CONFIG_SOC_SERIES_APOLLO5X) +#define SOC_TIMER_BASE TIMER_BASE +#endif static void counter_ambiq_isr(void *arg); struct counter_ambiq_config { @@ -27,6 +32,7 @@ struct counter_ambiq_config { struct counter_ambiq_data { counter_alarm_callback_t callback; + uint32_t freq; void *user_data; }; @@ -48,16 +54,141 @@ static void counter_irq_config_func(void) /* Shared irq config default to ctimer0. */ NVIC_ClearPendingIRQ(CTIMER_IRQn); - IRQ_CONNECT(CTIMER_IRQn, DT_INST_IRQ(0, priority), counter_ambiq_isr, DEVICE_DT_INST_GET(0), - 0); + IRQ_CONNECT(CTIMER_IRQn, DT_IRQ(DT_INST_PARENT(0), priority), counter_ambiq_isr, + DEVICE_DT_INST_GET(0), 0); irq_enable(CTIMER_IRQn); }; #endif +static uint32_t get_clock_cycles(uint32_t clock_sel) +{ + uint32_t ret = 0; + + switch (clock_sel) { +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + case 1: + ret = 12000000; + break; + case 2: + ret = 3000000; + break; + case 3: + ret = 187500; + break; + case 4: + ret = 47000; + break; + case 5: + ret = 12000; + break; + case 6: + ret = 32768; + break; + case 7: + ret = 16384; + break; + case 8: + ret = 2048; + break; + case 9: + ret = 256; + break; + case 10: + ret = 512; + break; + case 11: + ret = 32; + break; + case 12: + ret = 1000; + break; + case 13: + ret = 116; + break; + case 14: + ret = 100; + break; + case 15: /* todo: check on value */ + ret = 0; + break; + case 16: + ret = 8192; + break; + case 17: + ret = 4096; + break; + case 18: + ret = 1024; + break; +#elif defined(CONFIG_SOC_SERIES_APOLLO4X) || defined(CONFIG_SOC_SERIES_APOLLO5X) + case 0: + ret = 24000000; + break; + case 1: + ret = 6000000; + break; + case 2: + ret = 1500000; + break; + case 3: + ret = 375000; + break; + case 4: + ret = 93750; + break; + case 5: + ret = 1000; + break; + case 6: + ret = 500; + break; + case 7: + ret = 31; + break; + case 8: + ret = 1; + break; + case 9: + ret = 256; + break; + case 10: + ret = 32768; + break; + case 11: + ret = 16384; + break; + case 12: + ret = 8192; + break; + case 13: + ret = 4096; + break; + case 14: + ret = 2048; + break; + case 15: + ret = 1024; + break; + case 16: + ret = 256; + break; + case 17: + ret = 100; + break; +#endif + default: + ret = 32768; + break; + } + + return ret; +} + static int counter_ambiq_init(const struct device *dev) { k_spinlock_key_t key = k_spin_lock(&lock); const struct counter_ambiq_config *cfg = dev->config; + struct counter_ambiq_data *data = dev->data; #if defined(CONFIG_SOC_SERIES_APOLLO3X) /* Timer configuration */ @@ -72,6 +203,8 @@ static int counter_ambiq_init(const struct device *dev) am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); + data->freq = get_clock_cycles(cfg->clk_src); + am_hal_ctimer_clear(cfg->instance, AM_HAL_CTIMER_BOTH); am_hal_ctimer_config(cfg->instance, &sContTimer); counter_irq_config_func(); @@ -83,6 +216,8 @@ static int counter_ambiq_init(const struct device *dev) tc.eFunction = AM_HAL_TIMER_FN_UPCOUNT; tc.ui32PatternLimit = 0; + data->freq = get_clock_cycles(cfg->clk_src); + am_hal_timer_config(cfg->instance, &tc); cfg->irq_config_func(); #endif @@ -229,6 +364,13 @@ static uint32_t counter_ambiq_get_top_value(const struct device *dev) return config->counter_info.max_top_value; } +static uint32_t counter_ambiq_get_freq(const struct device *dev) +{ + const struct counter_ambiq_data *data = dev->data; + + return data->freq; +} + static DEVICE_API(counter, counter_api) = { .start = counter_ambiq_start, .stop = counter_ambiq_stop, @@ -238,6 +380,7 @@ static DEVICE_API(counter, counter_api) = { .set_top_value = counter_ambiq_set_top_value, .get_pending_int = counter_ambiq_get_pending_int, .get_top_value = counter_ambiq_get_top_value, + .get_freq = counter_ambiq_get_freq, }; #define APOLLO3_HANDLE_SHARED_TIMER_IRQ(n) \ @@ -279,26 +422,31 @@ static void counter_ambiq_isr(void *arg) /* Apollo3 counters share the same irq number, connect irq here will cause build error, so we * leave this function blank here and do it in counter_irq_config_func */ -#define AMBIQ_COUNTER_CONFIG_FUNC(idx) static void counter_irq_config_func_##idx(void){}; +#define AMBIQ_COUNTER_CONFIG_FUNC(idx) \ + static void counter_irq_config_func_##idx(void) \ + { \ + } #else #define AMBIQ_COUNTER_CONFIG_FUNC(idx) \ static void counter_irq_config_func_##idx(void) \ { \ - NVIC_ClearPendingIRQ(DT_INST_IRQN(idx)); \ - IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), counter_ambiq_isr, \ - DEVICE_DT_INST_GET(idx), 0); \ - irq_enable(DT_INST_IRQN(idx)); \ - }; + NVIC_ClearPendingIRQ(DT_IRQN(DT_INST_PARENT(idx))); \ + IRQ_CONNECT(DT_IRQN(DT_INST_PARENT(idx)), DT_IRQ(DT_INST_PARENT(idx), priority), \ + counter_ambiq_isr, DEVICE_DT_INST_GET(idx), 0); \ + irq_enable(DT_IRQN(DT_INST_PARENT(idx))); \ + } #endif #define AMBIQ_COUNTER_INIT(idx) \ + BUILD_ASSERT(DT_CHILD_NUM_STATUS_OKAY(DT_INST_PARENT(idx)) == 1, \ + "Too many children for Timer!"); \ static void counter_irq_config_func_##idx(void); \ static struct counter_ambiq_data counter_data_##idx; \ static const struct counter_ambiq_config counter_config_##idx = { \ - .instance = (DT_INST_REG_ADDR(idx) - DT_INST_REG_ADDR(0)) / DT_INST_REG_SIZE(idx), \ - .clk_src = DT_INST_PROP(idx, clk_source), \ + .instance = (DT_REG_ADDR(DT_INST_PARENT(idx)) - SOC_TIMER_BASE) / \ + DT_REG_SIZE(DT_INST_PARENT(idx)), \ + .clk_src = DT_ENUM_IDX(DT_INST_PARENT(idx), clk_source), \ .counter_info = {.max_top_value = UINT32_MAX, \ - .freq = DT_INST_PROP(idx, clock_frequency), \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ .irq_config_func = counter_irq_config_func_##idx, \ diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 46191a38ea4e..f244e1a782d0 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -57,6 +57,8 @@ zephyr_library_sources_ifdef(CONFIG_PWM_FAKE pwm_fake.c) zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZ_GPT pwm_renesas_rz_gpt.c) zephyr_library_sources_ifdef(CONFIG_PWM_NEORV32 pwm_neorv32.c) zephyr_library_sources_ifdef(CONFIG_PWM_WCH_GPTM pwm_wch_gptm.c) +zephyr_library_sources_ifdef(CONFIG_PWM_AMBIQ_TIMER pwm_ambiq_timer.c) +zephyr_library_sources_ifdef(CONFIG_PWM_AMBIQ_CTIMER pwm_ambiq_ctimer.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c) zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 7bc9251c1310..1f7f8dcbf0fe 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -134,4 +134,6 @@ source "drivers/pwm/Kconfig.neorv32" source "drivers/pwm/Kconfig.wch" +source "drivers/pwm/Kconfig.ambiq_timer" + endif # PWM diff --git a/drivers/pwm/Kconfig.ambiq_timer b/drivers/pwm/Kconfig.ambiq_timer new file mode 100644 index 000000000000..1b962b535c8e --- /dev/null +++ b/drivers/pwm/Kconfig.ambiq_timer @@ -0,0 +1,20 @@ +# Copyright (c) 2025, Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +config PWM_AMBIQ_TIMER + bool "Ambiq Timer PWM driver" + default y + depends on DT_HAS_AMBIQ_TIMER_PWM_ENABLED + select AMBIQ_HAL + select AMBIQ_HAL_USE_TIMER + help + Enable timer based pwm driver. + +config PWM_AMBIQ_CTIMER + bool "Ambiq CTimer PWM driver" + default y + depends on DT_HAS_AMBIQ_CTIMER_PWM_ENABLED + select AMBIQ_HAL + select AMBIQ_HAL_USE_TIMER + help + Enable ctimer based pwm driver. diff --git a/drivers/pwm/pwm_ambiq_ctimer.c b/drivers/pwm/pwm_ambiq_ctimer.c new file mode 100644 index 000000000000..34b2e13e07c0 --- /dev/null +++ b/drivers/pwm/pwm_ambiq_ctimer.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ambiq_ctimer_pwm + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(ambiq_ctimer_pwm, CONFIG_PWM_LOG_LEVEL); + +struct pwm_ambiq_ctimer_data { + uint32_t cycles; +}; + +struct pwm_ambiq_ctimer_config { + uint32_t timer_num; + uint32_t timer_seg; + uint32_t pwm_type; + uint32_t clock_sel; + const struct pinctrl_dev_config *pincfg; +}; + +static uint32_t get_clock_cycles(uint32_t clock_sel) +{ + uint32_t ret = 0; + + switch (clock_sel) { + case 1: + ret = 12000000; + break; + case 2: + ret = 3000000; + break; + case 3: + ret = 187500; + break; + case 4: + ret = 47000; + break; + case 5: + ret = 12000; + break; + case 6: + ret = 32768; + break; + case 7: + ret = 16384; + break; + case 8: + ret = 2048; + break; + case 9: + ret = 256; + break; + case 10: + ret = 512; + break; + case 11: + ret = 32; + break; + case 12: + ret = 1000; + break; + case 13: + ret = 116; + break; + case 14: + ret = 100; + break; + case 15: /* todo: check on value */ + ret = 0; + break; + case 16: + ret = 8192; + break; + case 17: + ret = 4096; + break; + case 18: + ret = 1024; + break; + default: + ret = 12000000; + break; + } + + return ret; +} + +static void start_clock(uint32_t clock_sel) +{ + switch (clock_sel) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0); + break; + case 6: + case 7: + case 8: + case 9: + case 14: /* RTC will assume XTAL since LFRC isn't as accurate */ + case 16: + case 17: + case 18: + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START, 0); + break; + case 10: + case 11: + case 12: + case 13: + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0); + break; + } +} + +static int ambiq_ctimer_pwm_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_ambiq_ctimer_config *config = dev->config; + + if (period_cycles == 0) { + LOG_ERR("period_cycles can not be set to zero"); + return -ENOTSUP; + } + + if (flags & PWM_POLARITY_INVERTED) { + if (pulse_cycles == 0) { + /* make pulse cycles greater than period so event never occurs */ + pulse_cycles = period_cycles + 1; + } else { + pulse_cycles = period_cycles - pulse_cycles; + } + } else { + if (pulse_cycles == period_cycles) { + --pulse_cycles; + } else if (pulse_cycles == 0) { + period_cycles = 0; + pulse_cycles = 1; + } + } + + uint32_t seg = 0; + + if (config->timer_seg == 0) { + seg = 0x0000FFFF; + } else if (config->timer_seg == 1) { + seg = 0xFFFF0000U; + } else { + seg = 0xFFFFFFFFU; + } + + /* todo: need to check if all of this is required */ + am_hal_ctimer_clear(config->timer_num, seg); + am_hal_ctimer_period_set(config->timer_num, seg, period_cycles, pulse_cycles); + am_hal_ctimer_start(config->timer_num, seg); + + return 0; +} + +static int ambiq_ctimer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + struct pwm_ambiq_ctimer_data *data = dev->data; + + /* cycles of the timer clock */ + *cycles = (uint64_t)data->cycles; + + return 0; +} + +static int ambiq_ctimer_pwm_init(const struct device *dev) +{ + const struct pwm_ambiq_ctimer_config *config = dev->config; + struct pwm_ambiq_ctimer_data *data = dev->data; + int err; + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + uint32_t seg = 0; + + if (config->timer_seg == 0) { + seg = 0x0000FFFF; + } else if (config->timer_seg == 1) { + seg = 0xFFFF0000U; + } else { + seg = 0xFFFFFFFFU; + } + + data->cycles = get_clock_cycles(config->clock_sel); + + start_clock(config->clock_sel); + + am_hal_ctimer_output_config(config->timer_num, seg, config->pincfg->states->pins->pin_num, + AM_HAL_CTIMER_OUTPUT_NORMAL, + AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA); + + am_hal_ctimer_config_single(config->timer_num, seg, + (_VAL2FLD(CTIMER_CTRL0_TMRA0FN, config->pwm_type + 2) | + _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, config->clock_sel) | + AM_HAL_CTIMER_INT_ENABLE)); + + return 0; +} + +static DEVICE_API(pwm, pwm_ambiq_ctimer_driver_api) = { + .set_cycles = ambiq_ctimer_pwm_set_cycles, + .get_cycles_per_sec = ambiq_ctimer_pwm_get_cycles_per_sec, +}; + +#define PWM_AMBIQ_CTIMER_DEVICE_INIT(n) \ + BUILD_ASSERT(DT_CHILD_NUM_STATUS_OKAY(DT_INST_PARENT(n)) == 1, \ + "Too many children for Timer!"); \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct pwm_ambiq_ctimer_data pwm_ambiq_ctimer_data_##n = { \ + .cycles = 0, \ + }; \ + static const struct pwm_ambiq_ctimer_config pwm_ambiq_ctimer_config_##n = { \ + .timer_num = (DT_REG_ADDR(DT_INST_PARENT(n)) - CTIMER_BASE) / \ + DT_REG_SIZE(DT_INST_PARENT(n)), \ + .timer_seg = DT_INST_ENUM_IDX(n, timer_segment), \ + .clock_sel = DT_ENUM_IDX(DT_INST_PARENT(n), clk_source), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .pwm_type = DT_INST_ENUM_IDX(n, pwm_type)}; \ + \ + DEVICE_DT_INST_DEFINE(n, ambiq_ctimer_pwm_init, NULL, &pwm_ambiq_ctimer_data_##n, \ + &pwm_ambiq_ctimer_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_ambiq_ctimer_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_AMBIQ_CTIMER_DEVICE_INIT) diff --git a/drivers/pwm/pwm_ambiq_timer.c b/drivers/pwm/pwm_ambiq_timer.c new file mode 100644 index 000000000000..0c1339c045f4 --- /dev/null +++ b/drivers/pwm/pwm_ambiq_timer.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ambiq_timer_pwm + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(ambiq_timer_pwm, CONFIG_PWM_LOG_LEVEL); + +#if defined(CONFIG_SOC_SERIES_APOLLO4X) || defined(CONFIG_SOC_SERIES_APOLLO5X) +typedef am_hal_timer_config_t pwm_timer_config_t; +#endif + +struct pwm_ambiq_timer_data { + uint32_t cycles; +}; + +struct pwm_ambiq_timer_config { + uint32_t timer_num; + uint32_t clock_sel; + const struct pinctrl_dev_config *pincfg; +}; + +static uint32_t get_clock_cycles(uint32_t clock_sel) +{ + uint32_t ret = 0; + + switch (clock_sel) { + case 0: + ret = 24000000; + break; + case 1: + ret = 6000000; + break; + case 2: + ret = 1500000; + break; + case 3: + ret = 375000; + break; + case 4: + ret = 93750; + break; + case 5: + ret = 1000; + break; + case 6: + ret = 500; + break; + case 7: + ret = 31; + break; + case 8: + ret = 1; + break; + case 9: + ret = 256; + break; + case 10: + ret = 32768; + break; + case 11: + ret = 16384; + break; + case 12: + ret = 8192; + break; + case 13: + ret = 4096; + break; + case 14: + ret = 2048; + break; + case 15: + ret = 1024; + break; + case 16: + ret = 256; + break; + case 17: + ret = 100; + break; + default: + ret = 24000000; + break; + } + + return ret; +} + +static int ambiq_timer_pwm_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_ambiq_timer_config *config = dev->config; + + if (period_cycles == 0) { + LOG_ERR("period_cycles can not be set to zero"); + return -ENOTSUP; + } + + if (flags & PWM_POLARITY_INVERTED) { + if (pulse_cycles == 0) { + /* make pulse cycles greater than period so event never occurs */ + pulse_cycles = period_cycles + 1; + } else { + pulse_cycles = period_cycles - pulse_cycles; + } + } else { + if (pulse_cycles == period_cycles) { + --pulse_cycles; + } else if (pulse_cycles == 0) { + pulse_cycles = 1; + } + } + + am_hal_timer_clear(config->timer_num); + am_hal_timer_compare0_set(config->timer_num, period_cycles); + am_hal_timer_compare1_set(config->timer_num, pulse_cycles); + + return 0; +} + +static int ambiq_timer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + struct pwm_ambiq_timer_data *data = dev->data; + + /* cycles of the timer clock */ + *cycles = (uint64_t)data->cycles; + + return 0; +} + +static int ambiq_timer_pwm_init(const struct device *dev) +{ + const struct pwm_ambiq_timer_config *config = dev->config; + struct pwm_ambiq_timer_data *data = dev->data; + int err; + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + pwm_timer_config_t pwm_timer_config; + + am_hal_timer_default_config_set(&pwm_timer_config); + + pwm_timer_config.eFunction = AM_HAL_TIMER_FN_PWM; + pwm_timer_config.eInputClock = config->clock_sel; + data->cycles = get_clock_cycles(config->clock_sel); + + am_hal_timer_output_config(config->pincfg->states->pins->pin_num, + AM_HAL_TIMER_OUTPUT_TMR0_OUT0 + config->timer_num * 2); + + am_hal_timer_config(config->timer_num, &pwm_timer_config); + + am_hal_timer_clear(config->timer_num); + am_hal_timer_compare0_set(config->timer_num, 0); + am_hal_timer_compare1_set(config->timer_num, 1); + + return 0; +} + +static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { + .set_cycles = ambiq_timer_pwm_set_cycles, + .get_cycles_per_sec = ambiq_timer_pwm_get_cycles_per_sec, +}; + +#define PWM_AMBIQ_TIMER_DEVICE_INIT(n) \ + BUILD_ASSERT(DT_CHILD_NUM_STATUS_OKAY(DT_INST_PARENT(n)) == 1, \ + "Too many children for Timer!"); \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct pwm_ambiq_timer_data pwm_ambiq_timer_data_##n = { \ + .cycles = 0, \ + }; \ + static const struct pwm_ambiq_timer_config pwm_ambiq_timer_config_##n = { \ + .timer_num = (DT_REG_ADDR(DT_INST_PARENT(n)) - TIMER_BASE) / \ + DT_REG_SIZE(DT_INST_PARENT(n)), \ + .clock_sel = DT_ENUM_IDX(DT_INST_PARENT(n), clk_source), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \ + \ + DEVICE_DT_INST_DEFINE(n, ambiq_timer_pwm_init, NULL, &pwm_ambiq_timer_data_##n, \ + &pwm_ambiq_timer_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_ambiq_timer_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_AMBIQ_TIMER_DEVICE_INIT) diff --git a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi index ba88b4983334..ea570f82cbb8 100644 --- a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { clocks { @@ -97,67 +98,140 @@ status = "okay"; }; - counter0: counter@40008000 { - compatible = "ambiq,counter"; + timer0: timer@40008000 { + compatible = "ambiq,ctimer"; reg = <0x40008000 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter1: counter@40008020 { - compatible = "ambiq,counter"; + timer1: timer@40008020 { + compatible = "ambiq,ctimer"; reg = <0x40008020 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter2: counter@40008040 { - compatible = "ambiq,counter"; + timer2: timer@40008040 { + compatible = "ambiq,ctimer"; reg = <0x40008040 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_187_5KHZ"; + status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer3: timer@40008060 { + compatible = "ambiq,ctimer"; + reg = <0x40008060 0x20>; + interrupts = <14 0>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter4: counter@40008080 { - compatible = "ambiq,counter"; + timer4: timer@40008080 { + compatible = "ambiq,ctimer"; reg = <0x40008080 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter5: counter@400080a0 { - compatible = "ambiq,counter"; + timer5: timer@400080a0 { + compatible = "ambiq,ctimer"; reg = <0x400080A0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter6: counter@400080c0 { - compatible = "ambiq,counter"; + timer6: timer@400080c0 { + compatible = "ambiq,ctimer"; reg = <0x400080C0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter7: counter@400080e0 { - compatible = "ambiq,counter"; + timer7: timer@400080e0 { + compatible = "ambiq,ctimer"; reg = <0x400080E0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; uart0: uart@4001c000 { diff --git a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi index 5d01e8171e53..5f6417a6e1b1 100644 --- a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { clocks { @@ -115,67 +116,140 @@ status = "okay"; }; - counter0: counter@40008000 { - compatible = "ambiq,counter"; + timer0: timer@40008000 { + compatible = "ambiq,ctimer"; reg = <0x40008000 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter1: counter@40008020 { - compatible = "ambiq,counter"; + timer1: timer@40008020 { + compatible = "ambiq,ctimer"; reg = <0x40008020 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter2: counter@40008040 { - compatible = "ambiq,counter"; + timer2: timer@40008040 { + compatible = "ambiq,ctimer"; reg = <0x40008040 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_187_5KHZ"; + status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer3: timer@40008060 { + compatible = "ambiq,ctimer"; + reg = <0x40008060 0x20>; + interrupts = <14 0>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter4: counter@40008080 { - compatible = "ambiq,counter"; + timer4: timer@40008080 { + compatible = "ambiq,ctimer"; reg = <0x40008080 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter5: counter@400080a0 { - compatible = "ambiq,counter"; + timer5: timer@400080a0 { + compatible = "ambiq,ctimer"; reg = <0x400080A0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter6: counter@400080c0 { - compatible = "ambiq,counter"; + timer6: timer@400080c0 { + compatible = "ambiq,ctimer"; reg = <0x400080C0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter7: counter@400080e0 { - compatible = "ambiq,counter"; + timer7: timer@400080e0 { + compatible = "ambiq,ctimer"; reg = <0x400080E0 0x20>; interrupts = <14 0>; - clock-frequency = ; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,ctimer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; uart0: uart@4001c000 { diff --git a/dts/arm/ambiq/ambiq_apollo4p.dtsi b/dts/arm/ambiq/ambiq_apollo4p.dtsi index 8f64ab04ff11..435cc94505ea 100644 --- a/dts/arm/ambiq/ambiq_apollo4p.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { clocks { @@ -99,13 +100,276 @@ status = "okay"; }; - counter0: counter@40008200 { - compatible = "ambiq,counter"; - reg = <0x40008200 0x20>; + timer0: timer@40008000 { + compatible = "ambiq,timer"; + reg = <0x40008000 0x20>; interrupts = <67 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer1: timer@40008020 { + compatible = "ambiq,timer"; + reg = <0x40008020 0x20>; + interrupts = <68 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer2: timer@40008040 { + compatible = "ambiq,timer"; + reg = <0x40008040 0x20>; + interrupts = <69 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer3: timer@40008060 { + compatible = "ambiq,timer"; + reg = <0x40008060 0x20>; + interrupts = <70 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer4: timer@40008080 { + compatible = "ambiq,timer"; + reg = <0x40008080 0x20>; + interrupts = <71 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer5: timer@400080a0 { + compatible = "ambiq,timer"; + reg = <0x400080A0 0x20>; + interrupts = <72 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer6: timer@400080c0 { + compatible = "ambiq,timer"; + reg = <0x400080C0 0x20>; + interrupts = <73 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer7: timer@400080e0 { + compatible = "ambiq,timer"; + reg = <0x400080E0 0x20>; + interrupts = <74 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer8: timer@40008100 { + compatible = "ambiq,timer"; + reg = <0x40008100 0x20>; + interrupts = <75 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer9: timer@40008120 { + compatible = "ambiq,timer"; + reg = <0x40008120 0x20>; + interrupts = <76 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer10: timer@40008140 { + compatible = "ambiq,timer"; + reg = <0x40008140 0x20>; + interrupts = <77 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer11: timer@40008160 { + compatible = "ambiq,timer"; + reg = <0x40008160 0x20>; + interrupts = <78 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer12: timer@40008180 { + compatible = "ambiq,timer"; + reg = <0x40008180 0x20>; + interrupts = <79 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer13: timer@400081a0 { + compatible = "ambiq,timer"; + reg = <0x400081A0 0x20>; + interrupts = <80 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer14: timer@400081c0 { + compatible = "ambiq,timer"; + reg = <0x400081C0 0x20>; + interrupts = <81 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer15: timer@400081e0 { + compatible = "ambiq,timer"; + reg = <0x400081E0 0x20>; + interrupts = <82 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; uart0: uart@4001c000 { diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index f89bd1e4cf98..80da05c20a82 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -5,6 +5,7 @@ #include #include #include +#include / { clocks { @@ -80,13 +81,276 @@ status = "okay"; }; - counter0: counter@40008200 { - compatible = "ambiq,counter"; - reg = <0x40008200 0x20>; + timer0: timer@40008000 { + compatible = "ambiq,timer"; + reg = <0x40008000 0x20>; interrupts = <67 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer1: timer@40008020 { + compatible = "ambiq,timer"; + reg = <0x40008020 0x20>; + interrupts = <68 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer2: timer@40008040 { + compatible = "ambiq,timer"; + reg = <0x40008040 0x20>; + interrupts = <69 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer3: timer@40008060 { + compatible = "ambiq,timer"; + reg = <0x40008060 0x20>; + interrupts = <70 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer4: timer@40008080 { + compatible = "ambiq,timer"; + reg = <0x40008080 0x20>; + interrupts = <71 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer5: timer@400080a0 { + compatible = "ambiq,timer"; + reg = <0x400080A0 0x20>; + interrupts = <72 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer6: timer@400080c0 { + compatible = "ambiq,timer"; + reg = <0x400080C0 0x20>; + interrupts = <73 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer7: timer@400080e0 { + compatible = "ambiq,timer"; + reg = <0x400080E0 0x20>; + interrupts = <74 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer8: timer@40008100 { + compatible = "ambiq,timer"; + reg = <0x40008100 0x20>; + interrupts = <75 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer9: timer@40008120 { + compatible = "ambiq,timer"; + reg = <0x40008120 0x20>; + interrupts = <76 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer10: timer@40008140 { + compatible = "ambiq,timer"; + reg = <0x40008140 0x20>; + interrupts = <77 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer11: timer@40008160 { + compatible = "ambiq,timer"; + reg = <0x40008160 0x20>; + interrupts = <78 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer12: timer@40008180 { + compatible = "ambiq,timer"; + reg = <0x40008180 0x20>; + interrupts = <79 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer13: timer@400081a0 { + compatible = "ambiq,timer"; + reg = <0x400081A0 0x20>; + interrupts = <80 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer14: timer@400081c0 { + compatible = "ambiq,timer"; + reg = <0x400081C0 0x20>; + interrupts = <81 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer15: timer@400081e0 { + compatible = "ambiq,timer"; + reg = <0x400081E0 0x20>; + interrupts = <82 0>; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; uart0: uart@4001c000 { diff --git a/dts/arm/ambiq/ambiq_apollo510.dtsi b/dts/arm/ambiq/ambiq_apollo510.dtsi index e5a7a558332b..247f0d38e8b6 100644 --- a/dts/arm/ambiq/ambiq_apollo510.dtsi +++ b/dts/arm/ambiq/ambiq_apollo510.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { clocks { @@ -143,130 +144,242 @@ status = "okay"; }; - counter0: counter@40008200 { - compatible = "ambiq,counter"; - reg = <0x40008200 0x20>; + timer0: timer@40008000 { + compatible = "ambiq,timer"; + reg = <0x40008000 0x20>; interrupts = <67 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter1: counter@40008220 { - compatible = "ambiq,counter"; - reg = <0x40008220 0x20>; + timer1: timer@40008020 { + compatible = "ambiq,timer"; + reg = <0x40008020 0x20>; interrupts = <68 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter2: counter@40008240 { - compatible = "ambiq,counter"; - reg = <0x40008240 0x20>; + timer2: timer@40008040 { + compatible = "ambiq,timer"; + reg = <0x40008040 0x20>; interrupts = <69 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter3: counter@40008260 { - compatible = "ambiq,counter"; - reg = <0x40008260 0x20>; + timer3: timer@40008060 { + compatible = "ambiq,timer"; + reg = <0x40008060 0x20>; interrupts = <70 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter4: counter@40008280 { - compatible = "ambiq,counter"; - reg = <0x40008280 0x20>; + timer4: timer@40008080 { + compatible = "ambiq,timer"; + reg = <0x40008080 0x20>; interrupts = <71 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter5: counter@400082a0 { - compatible = "ambiq,counter"; - reg = <0x400082a0 0x20>; + timer5: timer@400080a0 { + compatible = "ambiq,timer"; + reg = <0x400080a0 0x20>; interrupts = <72 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter6: counter@400082c0 { - compatible = "ambiq,counter"; - reg = <0x400082c0 0x20>; + timer6: timer@400080c0 { + compatible = "ambiq,timer"; + reg = <0x400080c0 0x20>; interrupts = <73 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter7: counter@400082e0 { - compatible = "ambiq,counter"; - reg = <0x400082e0 0x20>; + timer7: timer@400080e0 { + compatible = "ambiq,timer"; + reg = <0x400080e0 0x20>; interrupts = <74 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter8: counter@40008300 { - compatible = "ambiq,counter"; - reg = <0x40008300 0x20>; + timer8: timer@40008100 { + compatible = "ambiq,timer"; + reg = <0x40008100 0x20>; interrupts = <75 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter9: counter@40008320 { - compatible = "ambiq,counter"; - reg = <0x40008320 0x20>; + timer9: timer@40008120 { + compatible = "ambiq,timer"; + reg = <0x40008120 0x20>; interrupts = <76 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter10: counter@40008340 { - compatible = "ambiq,counter"; - reg = <0x40008340 0x20>; + timer10: timer@40008140 { + compatible = "ambiq,timer"; + reg = <0x40008140 0x20>; interrupts = <77 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter11: counter@40008360 { - compatible = "ambiq,counter"; - reg = <0x40008360 0x20>; + timer11: timer@40008160 { + compatible = "ambiq,timer"; + reg = <0x40008160 0x20>; interrupts = <78 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter12: counter@40008380 { - compatible = "ambiq,counter"; - reg = <0x40008380 0x20>; + timer12: timer@40008180 { + compatible = "ambiq,timer"; + reg = <0x40008180 0x20>; interrupts = <79 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; - counter13: counter@400083a0 { - compatible = "ambiq,counter"; - reg = <0x400083a0 0x20>; + timer13: timer@400081a0 { + compatible = "ambiq,timer"; + reg = <0x400081a0 0x20>; interrupts = <80 0>; - clock-frequency = ; - clk-source = <1>; - status = "disabled"; + clk-source = "CLK_SELECT_HFRC_DIV64"; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; rtc0: rtc@RTC_BASE_NAME { diff --git a/dts/bindings/counter/ambiq,counter.yaml b/dts/bindings/counter/ambiq,counter.yaml index 63399c06cae7..0c8b99f09945 100644 --- a/dts/bindings/counter/ambiq,counter.yaml +++ b/dts/bindings/counter/ambiq,counter.yaml @@ -6,20 +6,3 @@ description: Ambiq Timer/Counter compatible: "ambiq,counter" include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true - - clock-frequency: - type: int - required: true - description: Counter clock frequency - - clk-source: - type: int - required: true - description: Counter clock source diff --git a/dts/bindings/pwm/ambiq,ctimer-pwm.yaml b/dts/bindings/pwm/ambiq,ctimer-pwm.yaml new file mode 100644 index 000000000000..ab50d39de4aa --- /dev/null +++ b/dts/bindings/pwm/ambiq,ctimer-pwm.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2025, Ambiq +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq CTIMER PWM + +compatible: "ambiq,ctimer-pwm" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true + + timer-segment: + type: string + required: true + enum: + - "SEGMENT_A" + - "SEGMENT_B" + description: timer segment to use + + pwm-type: + type: string + required: true + enum: + - "PWM_ONCE" + - "PWM_REPEAT" + description: | + Mode selection + - AM_HAL_CTIMER_FN_PWM_ONCE + - AM_HAL_CTIMER_FN_PWM_REPEAT + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/ambiq,timer-pwm.yaml b/dts/bindings/pwm/ambiq,timer-pwm.yaml new file mode 100644 index 000000000000..46ebe04a1c1b --- /dev/null +++ b/dts/bindings/pwm/ambiq,timer-pwm.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025, Ambiq +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq TIMER PWM + +compatible: "ambiq,timer-pwm" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/timer/ambiq,ctimer.yaml b/dts/bindings/timer/ambiq,ctimer.yaml new file mode 100644 index 000000000000..b044023d7305 --- /dev/null +++ b/dts/bindings/timer/ambiq,ctimer.yaml @@ -0,0 +1,62 @@ +# Copyright (c) 2025 Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq CTIMER timer + +compatible: "ambiq,ctimer" + +include: [base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + clk-source: + type: string + required: true + enum: + - "CLK_SELECT_CLK_PIN" + - "CLK_SELECT_HFRC_12MHZ" + - "CLK_SELECT_HFRC_3MHZ" + - "CLK_SELECT_HFRC_187_5KHZ" + - "CLK_SELECT_HFRC_47KHZ" + - "CLK_SELECT_HFRC_12KHZ" + - "CLK_SELECT_XT_32_768KHZ" + - "CLK_SELECT_XT_16_384KHZ" + - "CLK_SELECT_XT_2_048KHZ" + - "CLK_SELECT_XT_256HZ" + - "CLK_SELECT_LFRC_512HZ" + - "CLK_SELECT_LFRC_32HZ" + - "CLK_SELECT_LFRC_1HZ" + - "CLK_SELECT_LFRC_1_16HZ" + - "CLK_SELECT_RTC_100HZ" + - "CLK_SELECT_HCLK_DIV4" + - "CLK_SELECT_XT_DIV4" + - "CLK_SELECT_XT_DIV8" + - "CLK_SELECT_XT_DIV32" + - "CLK_SELECT_RSVD" + description: | + Clock source selection: 32 KHz is available in deep sleep. + - AM_HAL_CTIMER_CLK_PIN _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x00) + - AM_HAL_CTIMER_HFRC_12MHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x01) + - AM_HAL_CTIMER_HFRC_3MHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x02) + - AM_HAL_CTIMER_HFRC_187_5KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x03) + - AM_HAL_CTIMER_HFRC_47KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x04) + - AM_HAL_CTIMER_HFRC_12KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x05) + - AM_HAL_CTIMER_XT_32_768KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x06) + - AM_HAL_CTIMER_XT_16_384KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x07) + - AM_HAL_CTIMER_XT_2_048KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x08) + - AM_HAL_CTIMER_XT_256HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x09) + - AM_HAL_CTIMER_LFRC_512HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0A) + - AM_HAL_CTIMER_LFRC_32HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0B) + - AM_HAL_CTIMER_LFRC_1HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0C) + - AM_HAL_CTIMER_LFRC_1_16HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0D) + - AM_HAL_CTIMER_RTC_100HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0E) + - AM_HAL_CTIMER_HCLK_DIV4 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0F) + - AM_HAL_CTIMER_XT_DIV4 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x10) + - AM_HAL_CTIMER_XT_DIV8 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x11) + - AM_HAL_CTIMER_XT_DIV32 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x12) + - AM_HAL_CTIMER_RSVD _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x13) diff --git a/dts/bindings/timer/ambiq,timer.yaml b/dts/bindings/timer/ambiq,timer.yaml new file mode 100644 index 000000000000..15da2fe728e7 --- /dev/null +++ b/dts/bindings/timer/ambiq,timer.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2025 Ambiq Micro Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Ambiq TIMER timer + +compatible: "ambiq,timer" + +include: [base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + clk-source: + type: string + required: true + enum: + - "CLK_SELECT_HFRC_DIV4" + - "CLK_SELECT_HFRC_DIV16" + - "CLK_SELECT_HFRC_DIV64" + - "CLK_SELECT_HFRC_DIV256" + - "CLK_SELECT_HFRC_DIV1024" + - "CLK_SELECT_HFRC_DIV4K" + - "CLK_SELECT_LFRC" + - "CLK_SELECT_LFRC_DIV2" + - "CLK_SELECT_LFRC_DIV32" + - "CLK_SELECT_LFRC_DIV1K" + - "CLK_SELECT_XT" + - "CLK_SELECT_XT_DIV2" + - "CLK_SELECT_XT_DIV4" + - "CLK_SELECT_XT_DIV8" + - "CLK_SELECT_XT_DIV16" + - "CLK_SELECT_XT_DIV32" + - "CLK_SELECT_XT_DIV128" + - "CLK_SELECT_RTC_100HZ" + description: | + Clock source selection: 32 KHz is available in deep sleep. + - AM_HAL_TIMER_CLOCK_HFRC_DIV4 + - AM_HAL_TIMER_CLOCK_HFRC_DIV16 + - AM_HAL_TIMER_CLOCK_HFRC_DIV64 + - AM_HAL_TIMER_CLOCK_HFRC_DIV256 + - AM_HAL_TIMER_CLOCK_HFRC_DIV1024 + - AM_HAL_TIMER_CLOCK_HFRC_DIV4K + - AM_HAL_TIMER_CLOCK_LFRC + - AM_HAL_TIMER_CLOCK_LFRC_DIV2 + - AM_HAL_TIMER_CLOCK_LFRC_DIV32 + - AM_HAL_TIMER_CLOCK_LFRC_DIV1K + - AM_HAL_TIMER_CLOCK_XT + - AM_HAL_TIMER_CLOCK_XT_DIV2 + - AM_HAL_TIMER_CLOCK_XT_DIV4 + - AM_HAL_TIMER_CLOCK_XT_DIV8 + - AM_HAL_TIMER_CLOCK_XT_DIV16 + - AM_HAL_TIMER_CLOCK_XT_DIV32 + - AM_HAL_TIMER_CLOCK_XT_DIV128 + - AM_HAL_TIMER_CLOCK_RTC_100HZ diff --git a/samples/basic/blinky_pwm/boards/apollo3_evb.overlay b/samples/basic/blinky_pwm/boards/apollo3_evb.overlay new file mode 100644 index 000000000000..50c4fe189969 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/apollo3_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwmleds { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/basic/blinky_pwm/boards/apollo3p_evb.overlay b/samples/basic/blinky_pwm/boards/apollo3p_evb.overlay new file mode 100644 index 000000000000..50c4fe189969 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/apollo3p_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwmleds { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/basic/blinky_pwm/boards/apollo4p_blue_kxr_evb.overlay b/samples/basic/blinky_pwm/boards/apollo4p_blue_kxr_evb.overlay new file mode 100644 index 000000000000..50c4fe189969 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/apollo4p_blue_kxr_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwmleds { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/basic/blinky_pwm/boards/apollo4p_evb.overlay b/samples/basic/blinky_pwm/boards/apollo4p_evb.overlay new file mode 100644 index 000000000000..50c4fe189969 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/apollo4p_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwmleds { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/basic/blinky_pwm/boards/apollo510_evb.overlay b/samples/basic/blinky_pwm/boards/apollo510_evb.overlay new file mode 100644 index 000000000000..50c4fe189969 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/apollo510_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pwmleds { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/apollo3_evb.overlay b/samples/drivers/counter/alarm/boards/apollo3_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/samples/drivers/counter/alarm/boards/apollo3_evb.overlay +++ b/samples/drivers/counter/alarm/boards/apollo3_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/samples/drivers/counter/alarm/boards/apollo3p_evb.overlay b/samples/drivers/counter/alarm/boards/apollo3p_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/samples/drivers/counter/alarm/boards/apollo3p_evb.overlay +++ b/samples/drivers/counter/alarm/boards/apollo3p_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/samples/drivers/counter/alarm/boards/apollo4p_blue_kxr_evb.overlay b/samples/drivers/counter/alarm/boards/apollo4p_blue_kxr_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/samples/drivers/counter/alarm/boards/apollo4p_blue_kxr_evb.overlay +++ b/samples/drivers/counter/alarm/boards/apollo4p_blue_kxr_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/samples/drivers/counter/alarm/boards/apollo4p_evb.overlay b/samples/drivers/counter/alarm/boards/apollo4p_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/samples/drivers/counter/alarm/boards/apollo4p_evb.overlay +++ b/samples/drivers/counter/alarm/boards/apollo4p_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/samples/drivers/counter/alarm/boards/apollo510_evb.overlay b/samples/drivers/counter/alarm/boards/apollo510_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/samples/drivers/counter/alarm/boards/apollo510_evb.overlay +++ b/samples/drivers/counter/alarm/boards/apollo510_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/samples/drivers/led/pwm/boards/apollo3_evb.overlay b/samples/drivers/led/pwm/boards/apollo3_evb.overlay new file mode 100644 index 000000000000..1663aaa96f3e --- /dev/null +++ b/samples/drivers/led/pwm/boards/apollo3_evb.overlay @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + /* do not define the led on the pa5 but a pwmleds */ + leds { + status = "disabled"; + }; +}; + +&pwmleds { + /* NOTE: enable here because it is disabled by default */ + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/drivers/led/pwm/boards/apollo3p_evb.overlay b/samples/drivers/led/pwm/boards/apollo3p_evb.overlay new file mode 100644 index 000000000000..1663aaa96f3e --- /dev/null +++ b/samples/drivers/led/pwm/boards/apollo3p_evb.overlay @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + /* do not define the led on the pa5 but a pwmleds */ + leds { + status = "disabled"; + }; +}; + +&pwmleds { + /* NOTE: enable here because it is disabled by default */ + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/drivers/led/pwm/boards/apollo4p_blue_kxr_evb.overlay b/samples/drivers/led/pwm/boards/apollo4p_blue_kxr_evb.overlay new file mode 100644 index 000000000000..1663aaa96f3e --- /dev/null +++ b/samples/drivers/led/pwm/boards/apollo4p_blue_kxr_evb.overlay @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + /* do not define the led on the pa5 but a pwmleds */ + leds { + status = "disabled"; + }; +}; + +&pwmleds { + /* NOTE: enable here because it is disabled by default */ + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/drivers/led/pwm/boards/apollo4p_evb.overlay b/samples/drivers/led/pwm/boards/apollo4p_evb.overlay new file mode 100644 index 000000000000..1663aaa96f3e --- /dev/null +++ b/samples/drivers/led/pwm/boards/apollo4p_evb.overlay @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + /* do not define the led on the pa5 but a pwmleds */ + leds { + status = "disabled"; + }; +}; + +&pwmleds { + /* NOTE: enable here because it is disabled by default */ + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/samples/drivers/led/pwm/boards/apollo510_evb.overlay b/samples/drivers/led/pwm/boards/apollo510_evb.overlay new file mode 100644 index 000000000000..1663aaa96f3e --- /dev/null +++ b/samples/drivers/led/pwm/boards/apollo510_evb.overlay @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + /* do not define the led on the pa5 but a pwmleds */ + leds { + status = "disabled"; + }; +}; + +&pwmleds { + /* NOTE: enable here because it is disabled by default */ + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/tests/drivers/counter/counter_basic_api/boards/apollo3p_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo3p_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/tests/drivers/counter/counter_basic_api/boards/apollo3p_evb.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/apollo3p_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/tests/drivers/counter/counter_basic_api/boards/apollo4p_blue_kxr_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo4p_blue_kxr_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/tests/drivers/counter/counter_basic_api/boards/apollo4p_blue_kxr_evb.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/apollo4p_blue_kxr_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/tests/drivers/counter/counter_basic_api/boards/apollo4p_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo4p_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/tests/drivers/counter/counter_basic_api/boards/apollo4p_evb.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/apollo4p_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/tests/drivers/counter/counter_basic_api/boards/apollo510_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo510_evb.overlay index 675247bc42d2..398a8b352426 100644 --- a/tests/drivers/counter/counter_basic_api/boards/apollo510_evb.overlay +++ b/tests/drivers/counter/counter_basic_api/boards/apollo510_evb.overlay @@ -1,3 +1,5 @@ -&counter0 { - status = "okay"; +&timer0 { + counter0: counter { + status = "okay"; + }; }; diff --git a/tests/drivers/pwm/pwm_api/boards/apollo3_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo3_evb.overlay new file mode 100644 index 000000000000..b2275d35fc08 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/apollo3_evb.overlay @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + aliases { + pwm-0 = &pwm2; + }; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/apollo3p_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo3p_evb.overlay new file mode 100644 index 000000000000..b2275d35fc08 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/apollo3p_evb.overlay @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + aliases { + pwm-0 = &pwm2; + }; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/apollo4p_blue_kxr_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo4p_blue_kxr_evb.overlay new file mode 100644 index 000000000000..b2275d35fc08 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/apollo4p_blue_kxr_evb.overlay @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + aliases { + pwm-0 = &pwm2; + }; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/apollo4p_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo4p_evb.overlay new file mode 100644 index 000000000000..b2275d35fc08 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/apollo4p_evb.overlay @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + aliases { + pwm-0 = &pwm2; + }; +}; + +&pwm2 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/apollo510_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo510_evb.overlay new file mode 100644 index 000000000000..b2275d35fc08 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/apollo510_evb.overlay @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Ambiq + */ + +/ { + aliases { + pwm-0 = &pwm2; + }; +}; + +&pwm2 { + status = "okay"; +};