Skip to content

drivers: pwm: rts5912: port pwm driver on Zephyr #86275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/pwm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZ_GPT pwm_renesas_rz_gpt.c)
zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c)
zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c)
zephyr_library_sources_ifdef(CONFIG_PWM_SHELL pwm_shell.c)
zephyr_library_sources_ifdef(CONFIG_PWM_REALTEK_RTS5912 pwm_realtek_rts5912.c)
2 changes: 2 additions & 0 deletions drivers/pwm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,6 @@ source "drivers/pwm/Kconfig.fake"

source "drivers/pwm/Kconfig.renesas_rz"

source "drivers/pwm/Kconfig.rts5912"

endif # PWM
9 changes: 9 additions & 0 deletions drivers/pwm/Kconfig.rts5912
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025, Realtek, SIBG-SD7
# SPDX-License-Identifier: Apache-2.0

config PWM_REALTEK_RTS5912
bool "Realtek RTS5912 PWM Driver"
default y
depends on DT_HAS_REALTEK_RTS5912_PWM_ENABLED
help
Enable PWM driver for Realtek RTS5912 EC.
125 changes: 125 additions & 0 deletions drivers/pwm/pwm_realtek_rts5912.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2025 Realtek, SIBG-SD7
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT realtek_rts5912_pwm

#include <zephyr/drivers/pwm.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/clock_control_rts5912.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Titan-Realtek ,

please remove unused header.

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


#include "reg/reg_pwm.h"

LOG_MODULE_REGISTER(pwm, CONFIG_PWM_LOG_LEVEL);

#define PWM_CYCLE_PER_SEC MHZ(50)

struct pwm_rts5912_config {
volatile struct pwm_regs *pwm_regs;
uint32_t pwm_clk_grp;
uint32_t pwm_clk_idx;
const struct device *clk_dev;
const struct pinctrl_dev_config *pcfg;
};

static int pwm_rts5912_set_cycles(const struct device *dev, uint32_t channel,
uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags)
{
const struct pwm_rts5912_config *const pwm_config = dev->config;
volatile struct pwm_regs *pwm_regs = pwm_config->pwm_regs;

uint32_t pwm_div, pwm_duty;

if (channel > 0) {
return -EIO;
}

pwm_div = period_cycles;
pwm_duty = pulse_cycles;

pwm_regs->div = pwm_div;
pwm_regs->duty = pwm_duty;

LOG_DBG("period_cycles=%d, pulse_cycles=%d, pwm_div=%d, pwm_duty=%d", period_cycles,
pulse_cycles, pwm_div, pwm_duty);

if (flags == PWM_POLARITY_INVERTED) {
pwm_regs->ctrl |= PWM_CTRL_INVT;
}
pwm_regs->ctrl |= PWM_CTRL_EN;

return 0;
}

static int pwm_rts5912_get_cycles_per_sec(const struct device *dev, uint32_t channel,
uint64_t *cycles)
{
ARG_UNUSED(dev);

if (channel > 0) {
return -EIO;
}

if (cycles) {
*cycles = PWM_CYCLE_PER_SEC;
}

return 0;
}

static DEVICE_API(pwm, pwm_rts5912_driver_api) = {
.set_cycles = pwm_rts5912_set_cycles,
.get_cycles_per_sec = pwm_rts5912_get_cycles_per_sec,
};

static int pwm_rts5912_init(const struct device *dev)
{
const struct pwm_rts5912_config *const pwm_config = dev->config;
struct rts5912_sccon_subsys sccon;

int rc = 0;
#ifdef CONFIG_PINCTRL
rc = pinctrl_apply_state(pwm_config->pcfg, PINCTRL_STATE_DEFAULT);
if (rc < 0) {
LOG_ERR("PWM pinctrl setup failed (%d)", rc);
return rc;
}
#endif
#ifdef CONFIG_CLOCK_CONTROL
if (!device_is_ready(pwm_config->clk_dev)) {
return -ENODEV;
}

sccon.clk_grp = pwm_config->pwm_clk_grp;
sccon.clk_idx = pwm_config->pwm_clk_idx;
rc = clock_control_on(pwm_config->clk_dev, (clock_control_subsys_t)&sccon);
if (rc != 0) {
return rc;
}
#endif
return rc;
}

#define RTS5912_PWM_PINCTRL_DEF(inst) PINCTRL_DT_INST_DEFINE(inst)

#define RTS5912_PWM_CONFIG(inst) \
static struct pwm_rts5912_config pwm_rts5912_config_##inst = { \
.pwm_regs = (struct pwm_regs *)DT_INST_REG_ADDR(inst), \
.pwm_clk_grp = DT_INST_CLOCKS_CELL(inst, clk_grp), \
.pwm_clk_idx = DT_INST_CLOCKS_CELL(inst, clk_idx), \
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
};

#define RTS5912_PWM_DEVICE_INIT(index) \
RTS5912_PWM_PINCTRL_DEF(index); \
RTS5912_PWM_CONFIG(index); \
DEVICE_DT_INST_DEFINE(index, &pwm_rts5912_init, NULL, NULL, &pwm_rts5912_config_##index, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&pwm_rts5912_driver_api);

DT_INST_FOREACH_STATUS_OKAY(RTS5912_PWM_DEVICE_INIT)
65 changes: 65 additions & 0 deletions dts/arm/realtek/ec/rts5912.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <arm/armv8-m.dtsi>
#include <zephyr/dt-bindings/clock/rts5912_clock.h>
#include <zephyr/dt-bindings/gpio/realtek-gpio.h>
#include <zephyr/dt-bindings/pwm/pwm.h>

/ {
cpus {
Expand Down Expand Up @@ -276,6 +277,70 @@
interrupts = <192 0>;
status = "disabled";
};

pwm0: pwm@4000f000 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM0_CLKPWR>;
reg = <0x4000f000 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm1: pwm@4000f00c {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM1_CLKPWR>;
reg = <0x4000f00c 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm2: pwm@4000f018 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM2_CLKPWR>;
reg = <0x4000f018 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm3: pwm@4000f024 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM3_CLKPWR>;
reg = <0x4000f024 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm4: pwm@4000f030 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM4_CLKPWR>;
reg = <0x4000f030 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm5: pwm@4000f03c {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM5_CLKPWR>;
reg = <0x4000f03c 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm6: pwm@4000f048 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM6_CLKPWR>;
reg = <0x4000f048 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};

pwm7: pwm@4000f054 {
compatible = "realtek,rts5912-pwm";
clocks = <&sccon RTS5912_SCCON_PERIPH_GRP0 PERIPH_GRP0_PWM7_CLKPWR>;
reg = <0x4000f054 0x0c>;
status = "disabled";
#pwm-cells = <3>;
};
};

swj_port: swj-port {
Expand Down
20 changes: 20 additions & 0 deletions dts/bindings/pwm/realtek,rts5912-pwm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2025, Realtek, SIBG-SD7
# SPDX-License-Identifier: Apache-2.0

description: Realtek RTS5912 PWM

include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml]

compatible: "realtek,rts5912-pwm"

properties:
reg:
required: true

"#pwm-cells":
const: 3

pwm-cells:
- channel
- period
- flags
26 changes: 26 additions & 0 deletions soc/realtek/ec/rts5912/reg/reg_pwm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2025 Realtek, SIBG-SD7
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_SOC_REALTEK_RTS5912_REG_PWM_H
#define ZEPHYR_SOC_REALTEK_RTS5912_REG_PWM_H

/*
* @brief PWM Controller (PWM)
*/

struct pwm_regs {
uint32_t duty;
uint32_t div;
uint32_t ctrl;
};

/* CTRL */
#define PWM_CTRL_CLKSRC BIT(28)
#define PWM_CTRL_INVT BIT(29)
#define PWM_CTRL_RST BIT(30)
#define PWM_CTRL_EN BIT(31)

#endif /* ZEPHYR_SOC_REALTEK_RTS5912_REG_PWM_H */
15 changes: 15 additions & 0 deletions tests/drivers/build_all/pwm/boards/rts5912_evb.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2025 Realtek Corporation. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
aliases {
pwm-0 = &pwm0;
};
};

&pwm0 {
status = "okay";
};
2 changes: 2 additions & 0 deletions tests/drivers/build_all/pwm/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ tests:
drivers.pwm.max31790.build:
platform_allow: nucleo_f429zi
extra_args: DTC_OVERLAY_FILE=max31790.overlay
drivers.pwm.rts5912.build:
platform_allow: rts5912_evb