From 238a59b5fd049a6ba3271c65600477d6f9113da7 Mon Sep 17 00:00:00 2001 From: Richard Wheatley Date: Tue, 18 Feb 2025 15:20:15 -0600 Subject: [PATCH 1/5] driver: pwm: create ambiq pwm driver Restructured counter and timer. CTimer/Timer is now parent to pwm and counter. Created PWM driver and tied to pwm and pwm-led Signed-off-by: Richard Wheatley --- .../apollo3_evb/apollo3_evb-pinctrl.dtsi | 6 + boards/ambiq/apollo3_evb/apollo3_evb.dts | 27 +- .../apollo3p_evb/apollo3p_evb-pinctrl.dtsi | 6 + boards/ambiq/apollo3p_evb/apollo3p_evb.dts | 27 +- .../apollo4p_blue_kxr_evb-pinctrl.dtsi | 7 + .../apollo4p_blue_kxr_evb.dts | 25 +- .../apollo4p_evb/apollo4p_evb-pinctrl.dtsi | 7 + boards/ambiq/apollo4p_evb/apollo4p_evb.dts | 24 +- boards/rakwireless/rak11720/rak11720.dts | 42 ++- drivers/counter/counter_ambiq_timer.c | 168 ++++++++++- drivers/pwm/CMakeLists.txt | 2 + drivers/pwm/Kconfig | 2 + drivers/pwm/Kconfig.ambiq_timer | 20 ++ drivers/pwm/pwm_ambiq_ctimer.c | 244 ++++++++++++++++ drivers/pwm/pwm_ambiq_timer.c | 195 +++++++++++++ dts/arm/ambiq/ambiq_apollo3_blue.dtsi | 99 +++++-- dts/arm/ambiq/ambiq_apollo3p_blue.dtsi | 99 +++++-- dts/arm/ambiq/ambiq_apollo4p.dtsi | 276 +++++++++++++++++- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 276 +++++++++++++++++- dts/bindings/counter/ambiq,counter.yaml | 17 -- dts/bindings/pwm/ambiq,ctimer-pwm.yaml | 89 ++++++ dts/bindings/pwm/ambiq,timer-pwm.yaml | 66 +++++ dts/bindings/timer/ambiq,ctimer.yaml | 20 ++ dts/bindings/timer/ambiq,timer.yaml | 20 ++ .../blinky_pwm/boards/apollo3_evb.overlay | 13 + .../blinky_pwm/boards/apollo3p_evb.overlay | 13 + .../boards/apollo4p_blue_kxr_evb.overlay | 13 + .../blinky_pwm/boards/apollo4p_evb.overlay | 13 + .../counter/alarm/boards/apollo3_evb.overlay | 6 +- .../counter/alarm/boards/apollo3p_evb.overlay | 6 +- .../boards/apollo4p_blue_kxr_evb.overlay | 6 +- .../counter/alarm/boards/apollo4p_evb.overlay | 6 +- .../led/pwm/boards/apollo3_evb.overlay | 21 ++ .../led/pwm/boards/apollo3p_evb.overlay | 21 ++ .../pwm/boards/apollo4p_blue_kxr_evb.overlay | 21 ++ .../led/pwm/boards/apollo4p_evb.overlay | 21 ++ .../boards/apollo3_evb.overlay | 6 +- .../boards/apollo3p_evb.overlay | 6 +- .../boards/apollo4p_blue_kxr_evb.overlay | 6 +- .../boards/apollo4p_evb.overlay | 6 +- .../pwm/pwm_api/boards/apollo3_evb.overlay | 15 + .../pwm/pwm_api/boards/apollo3p_evb.overlay | 15 + .../boards/apollo4p_blue_kxr_evb.overlay | 15 + .../pwm/pwm_api/boards/apollo4p_evb.overlay | 15 + 44 files changed, 1888 insertions(+), 120 deletions(-) create mode 100644 drivers/pwm/Kconfig.ambiq_timer create mode 100644 drivers/pwm/pwm_ambiq_ctimer.c create mode 100644 drivers/pwm/pwm_ambiq_timer.c create mode 100644 dts/bindings/pwm/ambiq,ctimer-pwm.yaml create mode 100644 dts/bindings/pwm/ambiq,timer-pwm.yaml create mode 100644 dts/bindings/timer/ambiq,ctimer.yaml create mode 100644 dts/bindings/timer/ambiq,timer.yaml create mode 100644 samples/basic/blinky_pwm/boards/apollo3_evb.overlay create mode 100644 samples/basic/blinky_pwm/boards/apollo3p_evb.overlay create mode 100644 samples/basic/blinky_pwm/boards/apollo4p_blue_kxr_evb.overlay create mode 100644 samples/basic/blinky_pwm/boards/apollo4p_evb.overlay create mode 100644 samples/drivers/led/pwm/boards/apollo3_evb.overlay create mode 100644 samples/drivers/led/pwm/boards/apollo3p_evb.overlay create mode 100644 samples/drivers/led/pwm/boards/apollo4p_blue_kxr_evb.overlay create mode 100644 samples/drivers/led/pwm/boards/apollo4p_evb.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/apollo3_evb.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/apollo3p_evb.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/apollo4p_blue_kxr_evb.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/apollo4p_evb.overlay diff --git a/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi b/boards/ambiq/apollo3_evb/apollo3_evb-pinctrl.dtsi index 39db2783c37a9..87586b6a0d88b 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 ed7a0494a70af..1b24d68ee3aaa 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,21 @@ }; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + timer-segment = "SEGMENT_B"; + clock-select = "CLK_SELECT_HFRC_187_5KHZ"; + 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 f8821a4c2f83b..a6087b30843eb 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 8b3371389741d..8e088dfef03f0 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,21 @@ }; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + timer-segment = "SEGMENT_B"; + clock-select = "CLK_SELECT_HFRC_187_5KHZ"; + 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 2cf596eadcd9f..4d63b444bb73a 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 f33e454272e20..0182feae4f32c 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,19 @@ status = "okay"; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + clock-select = "CLK_SELECT_HFRC_DIV64"; + 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 ccfdfd72974ef..eb9a0502704a7 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 567ec2143fe91..dd5ecbef94937 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,19 @@ status = "disabled"; }; -&counter0 { - status = "disabled"; +&timer0 { + counter0: counter { + status = "disabled"; + }; +}; + +&timer2 { + pwm2: pwm { + clock-select = "CLK_SELECT_HFRC_DIV64"; + 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 12fc1d7966b92..b4156eebfa634 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 b9323c5f5a3dc..d110719a6aeb1 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) +#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) + 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,29 @@ 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) \ 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_PROP(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 46191a38ea4e8..f244e1a782d02 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 7bc9251c1310d..1f7f8dcbf0fe4 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 0000000000000..1b962b535c8ea --- /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 0000000000000..e34ffa524959b --- /dev/null +++ b/drivers/pwm/pwm_ambiq_ctimer.c @@ -0,0 +1,244 @@ +/* + * 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_timer_data { + uint32_t cycles; +}; + +struct pwm_ambiq_timer_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_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) { + 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_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; + } + + 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_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) \ + 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)) - CTIMER_BASE) / \ + DT_REG_SIZE(DT_INST_PARENT(n)), \ + .timer_seg = DT_INST_ENUM_IDX(n, timer_segment), \ + .clock_sel = DT_INST_ENUM_IDX(n, clock_select), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .pwm_type = DT_INST_ENUM_IDX(n, pwm_type)}; \ + \ + 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/drivers/pwm/pwm_ambiq_timer.c b/drivers/pwm/pwm_ambiq_timer.c new file mode 100644 index 0000000000000..ee09f524422cb --- /dev/null +++ b/drivers/pwm/pwm_ambiq_timer.c @@ -0,0 +1,195 @@ +/* + * 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) +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) \ + 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_INST_ENUM_IDX(n, clock_select), \ + .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 ba88b49833348..42f2dbff70b06 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,123 @@ 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>; 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>; 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>; 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>; 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>; 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>; 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>; 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 5d01e8171e536..7286c6fe0f52d 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,123 @@ 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>; 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>; 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>; 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>; 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>; 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>; 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>; 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 8f64ab04ff116..da01cfc191c21 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 f89bd1e4cf981..9ccd18f18ef37 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + 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 = <2>; + + counter { + compatible = "ambiq,counter"; + status = "disabled"; + }; + pwm { + compatible = "ambiq,timer-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; }; uart0: uart@4001c000 { diff --git a/dts/bindings/counter/ambiq,counter.yaml b/dts/bindings/counter/ambiq,counter.yaml index 63399c06cae7c..0c8b99f09945f 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 0000000000000..e2daf08ce8a10 --- /dev/null +++ b/dts/bindings/pwm/ambiq,ctimer-pwm.yaml @@ -0,0 +1,89 @@ +# 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 + + clock-select: + 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) + + 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 0000000000000..7a6e00fb9cab3 --- /dev/null +++ b/dts/bindings/pwm/ambiq,timer-pwm.yaml @@ -0,0 +1,66 @@ +# 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 + + clock-select: + 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 + + "#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 0000000000000..33ac527ce4038 --- /dev/null +++ b/dts/bindings/timer/ambiq,ctimer.yaml @@ -0,0 +1,20 @@ +# 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: int + required: true + description: Counter Clock Source diff --git a/dts/bindings/timer/ambiq,timer.yaml b/dts/bindings/timer/ambiq,timer.yaml new file mode 100644 index 0000000000000..8b302062be2cf --- /dev/null +++ b/dts/bindings/timer/ambiq,timer.yaml @@ -0,0 +1,20 @@ +# 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: int + required: true + description: Counter Clock Source 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 0000000000000..50c4fe189969c --- /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 0000000000000..50c4fe189969c --- /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 0000000000000..50c4fe189969c --- /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 0000000000000..50c4fe189969c --- /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/drivers/counter/alarm/boards/apollo3_evb.overlay b/samples/drivers/counter/alarm/boards/apollo3_evb.overlay index 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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/led/pwm/boards/apollo3_evb.overlay b/samples/drivers/led/pwm/boards/apollo3_evb.overlay new file mode 100644 index 0000000000000..1663aaa96f3e6 --- /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 0000000000000..1663aaa96f3e6 --- /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 0000000000000..1663aaa96f3e6 --- /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 0000000000000..1663aaa96f3e6 --- /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/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo3_evb.overlay index 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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 675247bc42d27..398a8b3524260 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/pwm/pwm_api/boards/apollo3_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo3_evb.overlay new file mode 100644 index 0000000000000..b2275d35fc08c --- /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 0000000000000..b2275d35fc08c --- /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 0000000000000..b2275d35fc08c --- /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 0000000000000..b2275d35fc08c --- /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"; +}; From eed8ae2baa1b52441c69e90977aa53243fb686e5 Mon Sep 17 00:00:00 2001 From: Richard Wheatley Date: Wed, 19 Feb 2025 10:36:57 -0600 Subject: [PATCH 2/5] dts: bindings: move clk-source to parent Move clk-source from pwm to timer change associated files to match Signed-off-by: Richard Wheatley --- boards/ambiq/apollo3_evb/apollo3_evb.dts | 1 - boards/ambiq/apollo3p_evb/apollo3p_evb.dts | 1 - .../apollo4p_blue_kxr_evb.dts | 1 - boards/ambiq/apollo4p_evb/apollo4p_evb.dts | 1 - drivers/counter/counter_ambiq_timer.c | 2 +- drivers/pwm/pwm_ambiq_ctimer.c | 2 +- drivers/pwm/pwm_ambiq_timer.c | 2 +- dts/arm/ambiq/ambiq_apollo3_blue.dtsi | 31 +++++++++--- dts/arm/ambiq/ambiq_apollo3p_blue.dtsi | 31 +++++++++--- dts/arm/ambiq/ambiq_apollo4p.dtsi | 32 ++++++------- dts/arm/ambiq/ambiq_apollo4p_blue.dtsi | 32 ++++++------- dts/bindings/pwm/ambiq,ctimer-pwm.yaml | 47 ------------------- dts/bindings/pwm/ambiq,timer-pwm.yaml | 43 ----------------- dts/bindings/timer/ambiq,ctimer.yaml | 46 +++++++++++++++++- dts/bindings/timer/ambiq,timer.yaml | 42 ++++++++++++++++- 15 files changed, 167 insertions(+), 147 deletions(-) diff --git a/boards/ambiq/apollo3_evb/apollo3_evb.dts b/boards/ambiq/apollo3_evb/apollo3_evb.dts index 1b24d68ee3aaa..37f8b9f813359 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb.dts +++ b/boards/ambiq/apollo3_evb/apollo3_evb.dts @@ -178,7 +178,6 @@ &timer2 { pwm2: pwm { timer-segment = "SEGMENT_B"; - clock-select = "CLK_SELECT_HFRC_187_5KHZ"; pwm-type = "PWM_REPEAT"; pinctrl-0 = <&pwm2_default>; pinctrl-names = "default"; diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts index 8e088dfef03f0..3226891636650 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts @@ -156,7 +156,6 @@ &timer2 { pwm2: pwm { timer-segment = "SEGMENT_B"; - clock-select = "CLK_SELECT_HFRC_187_5KHZ"; pwm-type = "PWM_REPEAT"; pinctrl-0 = <&pwm2_default>; pinctrl-names = "default"; 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 0182feae4f32c..f701b27d8d78a 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 @@ -93,7 +93,6 @@ &timer2 { pwm2: pwm { - clock-select = "CLK_SELECT_HFRC_DIV64"; pinctrl-0 = <&pwm2_default>; pinctrl-names = "default"; status = "disabled"; diff --git a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts index dd5ecbef94937..66ecf4e5f863d 100644 --- a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts +++ b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts @@ -97,7 +97,6 @@ &timer2 { pwm2: pwm { - clock-select = "CLK_SELECT_HFRC_DIV64"; pinctrl-0 = <&pwm2_default>; pinctrl-names = "default"; status = "disabled"; diff --git a/drivers/counter/counter_ambiq_timer.c b/drivers/counter/counter_ambiq_timer.c index d110719a6aeb1..56d28a80ea7cb 100644 --- a/drivers/counter/counter_ambiq_timer.c +++ b/drivers/counter/counter_ambiq_timer.c @@ -443,7 +443,7 @@ static void counter_ambiq_isr(void *arg) static const struct counter_ambiq_config counter_config_##idx = { \ .instance = (DT_REG_ADDR(DT_INST_PARENT(idx)) - SOC_TIMER_BASE) / \ DT_REG_SIZE(DT_INST_PARENT(idx)), \ - .clk_src = DT_PROP(DT_INST_PARENT(idx), clk_source), \ + .clk_src = DT_ENUM_IDX(DT_INST_PARENT(idx), clk_source), \ .counter_info = {.max_top_value = UINT32_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ diff --git a/drivers/pwm/pwm_ambiq_ctimer.c b/drivers/pwm/pwm_ambiq_ctimer.c index e34ffa524959b..c44e304674719 100644 --- a/drivers/pwm/pwm_ambiq_ctimer.c +++ b/drivers/pwm/pwm_ambiq_ctimer.c @@ -233,7 +233,7 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { .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_INST_ENUM_IDX(n, clock_select), \ + .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)}; \ \ diff --git a/drivers/pwm/pwm_ambiq_timer.c b/drivers/pwm/pwm_ambiq_timer.c index ee09f524422cb..00e10cd22fe57 100644 --- a/drivers/pwm/pwm_ambiq_timer.c +++ b/drivers/pwm/pwm_ambiq_timer.c @@ -185,7 +185,7 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { 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_INST_ENUM_IDX(n, clock_select), \ + .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, \ diff --git a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi index 42f2dbff70b06..ea570f82cbb82 100644 --- a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi @@ -102,7 +102,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008000 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -119,7 +119,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008020 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -136,7 +136,24 @@ compatible = "ambiq,ctimer"; reg = <0x40008040 0x20>; interrupts = <14 0>; - 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"; @@ -153,7 +170,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008080 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -170,7 +187,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080A0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -187,7 +204,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080C0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -204,7 +221,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080E0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; diff --git a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi index 7286c6fe0f52d..5f6417a6e1b1a 100644 --- a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi @@ -120,7 +120,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008000 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -137,7 +137,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008020 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -154,7 +154,24 @@ compatible = "ambiq,ctimer"; reg = <0x40008040 0x20>; interrupts = <14 0>; - 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"; @@ -171,7 +188,7 @@ compatible = "ambiq,ctimer"; reg = <0x40008080 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -188,7 +205,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080A0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -205,7 +222,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080C0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; @@ -222,7 +239,7 @@ compatible = "ambiq,ctimer"; reg = <0x400080E0 0x20>; interrupts = <14 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_3MHZ"; status = "disabled"; counter { compatible = "ambiq,counter"; diff --git a/dts/arm/ambiq/ambiq_apollo4p.dtsi b/dts/arm/ambiq/ambiq_apollo4p.dtsi index da01cfc191c21..435cc94505ea8 100644 --- a/dts/arm/ambiq/ambiq_apollo4p.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p.dtsi @@ -104,7 +104,7 @@ compatible = "ambiq,timer"; reg = <0x40008000 0x20>; interrupts = <67 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -121,7 +121,7 @@ compatible = "ambiq,timer"; reg = <0x40008020 0x20>; interrupts = <68 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -138,7 +138,7 @@ compatible = "ambiq,timer"; reg = <0x40008040 0x20>; interrupts = <69 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -155,7 +155,7 @@ compatible = "ambiq,timer"; reg = <0x40008060 0x20>; interrupts = <70 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -172,7 +172,7 @@ compatible = "ambiq,timer"; reg = <0x40008080 0x20>; interrupts = <71 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -189,7 +189,7 @@ compatible = "ambiq,timer"; reg = <0x400080A0 0x20>; interrupts = <72 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -206,7 +206,7 @@ compatible = "ambiq,timer"; reg = <0x400080C0 0x20>; interrupts = <73 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -223,7 +223,7 @@ compatible = "ambiq,timer"; reg = <0x400080E0 0x20>; interrupts = <74 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -240,7 +240,7 @@ compatible = "ambiq,timer"; reg = <0x40008100 0x20>; interrupts = <75 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -257,7 +257,7 @@ compatible = "ambiq,timer"; reg = <0x40008120 0x20>; interrupts = <76 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -274,7 +274,7 @@ compatible = "ambiq,timer"; reg = <0x40008140 0x20>; interrupts = <77 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -291,7 +291,7 @@ compatible = "ambiq,timer"; reg = <0x40008160 0x20>; interrupts = <78 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -308,7 +308,7 @@ compatible = "ambiq,timer"; reg = <0x40008180 0x20>; interrupts = <79 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -325,7 +325,7 @@ compatible = "ambiq,timer"; reg = <0x400081A0 0x20>; interrupts = <80 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -342,7 +342,7 @@ compatible = "ambiq,timer"; reg = <0x400081C0 0x20>; interrupts = <81 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -359,7 +359,7 @@ compatible = "ambiq,timer"; reg = <0x400081E0 0x20>; interrupts = <82 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 9ccd18f18ef37..80da05c20a82c 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -85,7 +85,7 @@ compatible = "ambiq,timer"; reg = <0x40008000 0x20>; interrupts = <67 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -102,7 +102,7 @@ compatible = "ambiq,timer"; reg = <0x40008020 0x20>; interrupts = <68 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -119,7 +119,7 @@ compatible = "ambiq,timer"; reg = <0x40008040 0x20>; interrupts = <69 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -136,7 +136,7 @@ compatible = "ambiq,timer"; reg = <0x40008060 0x20>; interrupts = <70 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -153,7 +153,7 @@ compatible = "ambiq,timer"; reg = <0x40008080 0x20>; interrupts = <71 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -170,7 +170,7 @@ compatible = "ambiq,timer"; reg = <0x400080A0 0x20>; interrupts = <72 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -187,7 +187,7 @@ compatible = "ambiq,timer"; reg = <0x400080C0 0x20>; interrupts = <73 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -204,7 +204,7 @@ compatible = "ambiq,timer"; reg = <0x400080E0 0x20>; interrupts = <74 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -221,7 +221,7 @@ compatible = "ambiq,timer"; reg = <0x40008100 0x20>; interrupts = <75 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -238,7 +238,7 @@ compatible = "ambiq,timer"; reg = <0x40008120 0x20>; interrupts = <76 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -255,7 +255,7 @@ compatible = "ambiq,timer"; reg = <0x40008140 0x20>; interrupts = <77 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -272,7 +272,7 @@ compatible = "ambiq,timer"; reg = <0x40008160 0x20>; interrupts = <78 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -289,7 +289,7 @@ compatible = "ambiq,timer"; reg = <0x40008180 0x20>; interrupts = <79 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -306,7 +306,7 @@ compatible = "ambiq,timer"; reg = <0x400081A0 0x20>; interrupts = <80 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -323,7 +323,7 @@ compatible = "ambiq,timer"; reg = <0x400081C0 0x20>; interrupts = <81 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; @@ -340,7 +340,7 @@ compatible = "ambiq,timer"; reg = <0x400081E0 0x20>; interrupts = <82 0>; - clk-source = <2>; + clk-source = "CLK_SELECT_HFRC_DIV64"; counter { compatible = "ambiq,counter"; diff --git a/dts/bindings/pwm/ambiq,ctimer-pwm.yaml b/dts/bindings/pwm/ambiq,ctimer-pwm.yaml index e2daf08ce8a10..ab50d39de4aaf 100644 --- a/dts/bindings/pwm/ambiq,ctimer-pwm.yaml +++ b/dts/bindings/pwm/ambiq,ctimer-pwm.yaml @@ -22,53 +22,6 @@ properties: - "SEGMENT_B" description: timer segment to use - clock-select: - 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) - pwm-type: type: string required: true diff --git a/dts/bindings/pwm/ambiq,timer-pwm.yaml b/dts/bindings/pwm/ambiq,timer-pwm.yaml index 7a6e00fb9cab3..46ebe04a1c1b3 100644 --- a/dts/bindings/pwm/ambiq,timer-pwm.yaml +++ b/dts/bindings/pwm/ambiq,timer-pwm.yaml @@ -14,49 +14,6 @@ properties: pinctrl-names: required: true - clock-select: - 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 - "#pwm-cells": const: 3 diff --git a/dts/bindings/timer/ambiq,ctimer.yaml b/dts/bindings/timer/ambiq,ctimer.yaml index 33ac527ce4038..b044023d73057 100644 --- a/dts/bindings/timer/ambiq,ctimer.yaml +++ b/dts/bindings/timer/ambiq,ctimer.yaml @@ -15,6 +15,48 @@ properties: required: true clk-source: - type: int + type: string required: true - description: Counter Clock Source + 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 index 8b302062be2cf..15da2fe728e74 100644 --- a/dts/bindings/timer/ambiq,timer.yaml +++ b/dts/bindings/timer/ambiq,timer.yaml @@ -15,6 +15,44 @@ properties: required: true clk-source: - type: int + type: string required: true - description: Counter Clock Source + 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 From 8c2fed1fd9802335931c77c309ace09b2b28a1a0 Mon Sep 17 00:00:00 2001 From: Richard Wheatley Date: Wed, 19 Feb 2025 22:09:54 -0600 Subject: [PATCH 3/5] drivers: add assert to check for max children in timer check for max number of children in timer. Signed-off-by: Richard Wheatley --- drivers/counter/counter_ambiq_timer.c | 4 +++- drivers/pwm/pwm_ambiq_ctimer.c | 4 +++- drivers/pwm/pwm_ambiq_timer.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/counter/counter_ambiq_timer.c b/drivers/counter/counter_ambiq_timer.c index 56d28a80ea7cb..41895ae10df8f 100644 --- a/drivers/counter/counter_ambiq_timer.c +++ b/drivers/counter/counter_ambiq_timer.c @@ -438,12 +438,14 @@ static void counter_ambiq_isr(void *arg) #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_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), \ + .clk_src = DT_ENUM_IDX(DT_INST_PARENT(idx), clk_source), \ .counter_info = {.max_top_value = UINT32_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ diff --git a/drivers/pwm/pwm_ambiq_ctimer.c b/drivers/pwm/pwm_ambiq_ctimer.c index c44e304674719..ee0039f475b6a 100644 --- a/drivers/pwm/pwm_ambiq_ctimer.c +++ b/drivers/pwm/pwm_ambiq_ctimer.c @@ -225,6 +225,8 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { }; #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, \ @@ -233,7 +235,7 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { .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), \ + .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)}; \ \ diff --git a/drivers/pwm/pwm_ambiq_timer.c b/drivers/pwm/pwm_ambiq_timer.c index 00e10cd22fe57..0142fa9073458 100644 --- a/drivers/pwm/pwm_ambiq_timer.c +++ b/drivers/pwm/pwm_ambiq_timer.c @@ -178,6 +178,8 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { }; #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, \ @@ -185,7 +187,7 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { 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), \ + .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, \ From ffe92c871902e83544ce08ea8b9e630441b0286a Mon Sep 17 00:00:00 2001 From: Hao Luo Date: Fri, 27 Jun 2025 17:16:55 +0800 Subject: [PATCH 4/5] drivers: pwm: changed ambiq ctimer variable names changed variable names from timer to ctimer Signed-off-by: Hao Luo --- drivers/pwm/pwm_ambiq_ctimer.c | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/pwm/pwm_ambiq_ctimer.c b/drivers/pwm/pwm_ambiq_ctimer.c index ee0039f475b6a..34b2e13e07c04 100644 --- a/drivers/pwm/pwm_ambiq_ctimer.c +++ b/drivers/pwm/pwm_ambiq_ctimer.c @@ -16,11 +16,11 @@ LOG_MODULE_REGISTER(ambiq_ctimer_pwm, CONFIG_PWM_LOG_LEVEL); -struct pwm_ambiq_timer_data { +struct pwm_ambiq_ctimer_data { uint32_t cycles; }; -struct pwm_ambiq_timer_config { +struct pwm_ambiq_ctimer_config { uint32_t timer_num; uint32_t timer_seg; uint32_t pwm_type; @@ -126,11 +126,11 @@ static void start_clock(uint32_t clock_sel) } } -static int ambiq_timer_pwm_set_cycles(const struct device *dev, uint32_t channel, +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_timer_config *config = dev->config; + const struct pwm_ambiq_ctimer_config *config = dev->config; if (period_cycles == 0) { LOG_ERR("period_cycles can not be set to zero"); @@ -171,10 +171,10 @@ static int ambiq_timer_pwm_set_cycles(const struct device *dev, uint32_t channel return 0; } -static int ambiq_timer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, +static int ambiq_ctimer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles) { - struct pwm_ambiq_timer_data *data = dev->data; + struct pwm_ambiq_ctimer_data *data = dev->data; /* cycles of the timer clock */ *cycles = (uint64_t)data->cycles; @@ -182,10 +182,10 @@ static int ambiq_timer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t return 0; } -static int ambiq_timer_pwm_init(const struct device *dev) +static int ambiq_ctimer_pwm_init(const struct device *dev) { - const struct pwm_ambiq_timer_config *config = dev->config; - struct pwm_ambiq_timer_data *data = dev->data; + 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); @@ -219,19 +219,19 @@ static int ambiq_timer_pwm_init(const struct device *dev) 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, +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_TIMER_DEVICE_INIT(n) \ +#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_timer_data pwm_ambiq_timer_data_##n = { \ + static struct pwm_ambiq_ctimer_data pwm_ambiq_ctimer_data_##n = { \ .cycles = 0, \ }; \ - static const struct pwm_ambiq_timer_config pwm_ambiq_timer_config_##n = { \ + 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), \ @@ -239,8 +239,8 @@ static DEVICE_API(pwm, pwm_ambiq_timer_driver_api) = { .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .pwm_type = DT_INST_ENUM_IDX(n, pwm_type)}; \ \ - 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); + 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_TIMER_DEVICE_INIT) +DT_INST_FOREACH_STATUS_OKAY(PWM_AMBIQ_CTIMER_DEVICE_INIT) From cfaf1a2a028f0913969ca382547292560648c881 Mon Sep 17 00:00:00 2001 From: Hao Luo Date: Thu, 26 Jun 2025 15:36:27 +0800 Subject: [PATCH 5/5] drivers: pwm: Add support for Apollo510 pwm This commit adds support for Apollo510 pwm driver Signed-off-by: Hao Luo --- .../apollo510_evb/apollo510_evb-pinctrl.dtsi | 8 + boards/ambiq/apollo510_evb/apollo510_evb.dts | 24 +- drivers/counter/counter_ambiq_timer.c | 4 +- drivers/pwm/pwm_ambiq_timer.c | 2 +- dts/arm/ambiq/ambiq_apollo510.dtsi | 281 ++++++++++++------ .../blinky_pwm/boards/apollo510_evb.overlay | 13 + .../alarm/boards/apollo510_evb.overlay | 6 +- .../led/pwm/boards/apollo510_evb.overlay | 21 ++ .../boards/apollo510_evb.overlay | 6 +- .../pwm/pwm_api/boards/apollo510_evb.overlay | 15 + 10 files changed, 287 insertions(+), 93 deletions(-) create mode 100644 samples/basic/blinky_pwm/boards/apollo510_evb.overlay create mode 100644 samples/drivers/led/pwm/boards/apollo510_evb.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/apollo510_evb.overlay diff --git a/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi b/boards/ambiq/apollo510_evb/apollo510_evb-pinctrl.dtsi index 797ce0b96d196..df06023b66faa 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 3ed5e7859cd9a..e099b90aef1b7 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/drivers/counter/counter_ambiq_timer.c b/drivers/counter/counter_ambiq_timer.c index 41895ae10df8f..169bed7ce5717 100644 --- a/drivers/counter/counter_ambiq_timer.c +++ b/drivers/counter/counter_ambiq_timer.c @@ -18,7 +18,7 @@ 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) +#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); @@ -120,7 +120,7 @@ static uint32_t get_clock_cycles(uint32_t clock_sel) case 18: ret = 1024; break; -#elif defined(CONFIG_SOC_SERIES_APOLLO4X) +#elif defined(CONFIG_SOC_SERIES_APOLLO4X) || defined(CONFIG_SOC_SERIES_APOLLO5X) case 0: ret = 24000000; break; diff --git a/drivers/pwm/pwm_ambiq_timer.c b/drivers/pwm/pwm_ambiq_timer.c index 0142fa9073458..0c1339c045f43 100644 --- a/drivers/pwm/pwm_ambiq_timer.c +++ b/drivers/pwm/pwm_ambiq_timer.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(ambiq_timer_pwm, CONFIG_PWM_LOG_LEVEL); -#if defined(CONFIG_SOC_SERIES_APOLLO4X) +#if defined(CONFIG_SOC_SERIES_APOLLO4X) || defined(CONFIG_SOC_SERIES_APOLLO5X) typedef am_hal_timer_config_t pwm_timer_config_t; #endif diff --git a/dts/arm/ambiq/ambiq_apollo510.dtsi b/dts/arm/ambiq/ambiq_apollo510.dtsi index e5a7a558332bb..247f0d38e8b65 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/samples/basic/blinky_pwm/boards/apollo510_evb.overlay b/samples/basic/blinky_pwm/boards/apollo510_evb.overlay new file mode 100644 index 0000000000000..50c4fe189969c --- /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/apollo510_evb.overlay b/samples/drivers/counter/alarm/boards/apollo510_evb.overlay index 675247bc42d27..398a8b3524260 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/apollo510_evb.overlay b/samples/drivers/led/pwm/boards/apollo510_evb.overlay new file mode 100644 index 0000000000000..1663aaa96f3e6 --- /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/apollo510_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/apollo510_evb.overlay index 675247bc42d27..398a8b3524260 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/apollo510_evb.overlay b/tests/drivers/pwm/pwm_api/boards/apollo510_evb.overlay new file mode 100644 index 0000000000000..b2275d35fc08c --- /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"; +};