drivers: clock_control: Add PWM clock device
Adds a clock control device for a PWM node, allowing the PWM to be controlled using the clock control API. It is a similar idea to the device driver in linux: linux/Documentation/devicetree/bindings/clock/pwm-clock.yaml Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
This commit is contained in:
parent
b485cd717b
commit
0d1fa268bb
13 changed files with 411 additions and 0 deletions
7
tests/drivers/clock_control/pwm_clock/CMakeLists.txt
Normal file
7
tests/drivers/clock_control/pwm_clock/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(pwm_clock)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Andriy Gelman
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
pwmclock: pwmclock {
|
||||
status = "okay";
|
||||
compatible = "pwm-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <1000000>;
|
||||
pwms = <&pwm0 0 PWM_KHZ(1000) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
|
||||
samplenode: samplenode {
|
||||
status = "okay";
|
||||
compatible = "test-clock-control-pwm-clock";
|
||||
clocks = <&pwmclock 0>;
|
||||
};
|
||||
};
|
||||
|
||||
&pwm0 {
|
||||
prescaler = <1>;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Andriy Gelman
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
pwmclock: pwmclock {
|
||||
status = "okay";
|
||||
compatible = "pwm-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <1000000>;
|
||||
pwms = <&pwm_ccu40 2 PWM_KHZ(1000) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
|
||||
samplenode: samplenode {
|
||||
status = "okay";
|
||||
compatible = "test-clock-control-pwm-clock";
|
||||
clocks = <&pwmclock 0>;
|
||||
};
|
||||
};
|
||||
|
||||
&pwm_ccu40 {
|
||||
status = "okay";
|
||||
slice-prescaler = <0 0 0 0>;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Andriy Gelman
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
pwmclock: pwmclock {
|
||||
status = "okay";
|
||||
compatible = "pwm-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <1000000>;
|
||||
pwms = <&pwm_ccu80 0 PWM_KHZ(1000) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
|
||||
samplenode: samplenode {
|
||||
status = "okay";
|
||||
compatible = "test-clock-control-pwm-clock";
|
||||
clocks = <&pwmclock 0>;
|
||||
};
|
||||
};
|
||||
|
||||
&pwm_ccu80 {
|
||||
status = "okay";
|
||||
slice-prescaler = <0 0 0 0>;
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
description: Example binding for a node using a PWM clock
|
||||
|
||||
compatible: "test-clock-control-pwm-clock"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
clocks:
|
||||
required: true
|
||||
description: Clock phandle array
|
2
tests/drivers/clock_control/pwm_clock/prj.conf
Normal file
2
tests/drivers/clock_control/pwm_clock/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_CLOCK_CONTROL=y
|
74
tests/drivers/clock_control/pwm_clock/src/main.c
Normal file
74
tests/drivers/clock_control/pwm_clock/src/main.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Andriy Gelman <andriy.gelman@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#define NODELABEL DT_NODELABEL(samplenode)
|
||||
static const struct device *clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(NODELABEL));
|
||||
|
||||
static void *pwm_clock_setup(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t clock_rate;
|
||||
uint32_t clock_rate_dt = DT_PROP_BY_PHANDLE(NODELABEL, clocks, clock_frequency);
|
||||
|
||||
zassert_equal(device_is_ready(clk_dev), true, "%s: PWM clock device is not ready",
|
||||
clk_dev->name);
|
||||
|
||||
ret = clock_control_get_rate(clk_dev, 0, &clock_rate);
|
||||
zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate",
|
||||
clk_dev->name, ret);
|
||||
|
||||
zassert_equal(clock_rate_dt, clock_rate,
|
||||
"%s: devicetree clock rate mismatch. Expected %dHz Fetched %dHz",
|
||||
clk_dev->name, clock_rate_dt, clock_rate);
|
||||
|
||||
ret = clock_control_on(clk_dev, 0);
|
||||
zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_on", clk_dev->name, ret);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZTEST(pwm_clock, test_clock_control_get_rate)
|
||||
{
|
||||
int ret;
|
||||
uint32_t clock_rate;
|
||||
|
||||
ret = clock_control_get_rate(clk_dev, 0, &clock_rate);
|
||||
zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate",
|
||||
clk_dev->name, ret);
|
||||
}
|
||||
|
||||
ZTEST(pwm_clock, test_clock_control_set_rate)
|
||||
{
|
||||
int ret;
|
||||
uint32_t clock_rate, clock_rate_new;
|
||||
|
||||
ret = clock_control_get_rate(clk_dev, 0, &clock_rate);
|
||||
zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate",
|
||||
clk_dev->name, ret);
|
||||
|
||||
clock_rate /= 2;
|
||||
|
||||
ret = clock_control_set_rate(clk_dev, 0, (clock_control_subsys_rate_t)clock_rate);
|
||||
zassert_equal(0, ret, "%s: unexpected err (%d) from clock_control_set_rate",
|
||||
clk_dev->name, ret);
|
||||
|
||||
ret = clock_control_get_rate(clk_dev, 0, &clock_rate_new);
|
||||
zassert_equal(0, ret, "%s: Unexpected err (%d) from clock_control_get_rate",
|
||||
clk_dev->name, ret);
|
||||
|
||||
zassert_equal(clock_rate, clock_rate_new,
|
||||
"%s: Clock rate mismatch. Expected %dHz Fetched %dHz", clk_dev->name,
|
||||
clock_rate, clock_rate_new);
|
||||
}
|
||||
|
||||
ZTEST_SUITE(pwm_clock, NULL, pwm_clock_setup, NULL, NULL, NULL);
|
7
tests/drivers/clock_control/pwm_clock/testcase.yaml
Normal file
7
tests/drivers/clock_control/pwm_clock/testcase.yaml
Normal file
|
@ -0,0 +1,7 @@
|
|||
tests:
|
||||
drivers.clock.pwm_clock:
|
||||
filter: dt_compat_enabled("pwm-clock") and dt_compat_enabled("test-clock-control-pwm-clock")
|
||||
tags:
|
||||
- drivers
|
||||
- clock
|
||||
- pwm
|
Loading…
Add table
Add a link
Reference in a new issue