设备树的pwm节点:

1
2
3
4
5
6
7
8
9
10
11
// vi rk3399.dtsi:
pwm0: pwm@ff420000 {
compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
reg = <0x0 0xff420000 0x0 0x10>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm0_pin>;
clocks = <&pmucru PCLK_RKPWM_PMU>;
clock-names = "pwm";
status = "okay";
};

这个设备树节点会和pwm-rockchip.c匹配,调用probe函数:

根据设备树的信息,配置pwm的底层寄存器,把每个pwm通道都编一个index索引值都放入一个链表。以后我们要用某个pwm端口的时候就直接request端口就行了。

pwm使用实例:

修改设备树:

1
2
3
4
5
6
7
8
 pwm_demo: pwm_demo {
status = "okay";
compatible = "firefly,rk3399-pwm";
pwm_id = <0>; //使用pwm0通道
min_period = <0>;
max_period = <10000>;
duty_ns = <5000>;
};

编写驱动程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <linux/iio/types.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/iio/consumer.h>
#include <linux/interrupt.h>
#include <linux/pinctrl/consumer.h>

#include <linux/pwm.h>

static struct pwm_device * pwm_device = NULL;

static int firefly_pwm_probe(struct platform_device *pdev)
{
int ret;

printk("firefly_pwm_probe!\n");
pwm_device = pwm_request(0, "firefly-pwm");
ret = pwm_config(pwm_device, 500000, 1000000);
ret = pwm_enable(pwm_device);

return 0;
}

static int firefly_pwm_remove(struct platform_device *pdev)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

pwm_disable(pwm_device);
return 0;
}

static const struct of_device_id firefly_pwm_match[] = {
{ .compatible = "firefly,rk3399-pwm" },
{},
};

static struct platform_driver firefly_pwm_driver = {
.probe = firefly_pwm_probe,
.remove = firefly_pwm_remove,
.driver = {
.name = "firefly_pwm",
.owner = THIS_MODULE,
.of_match_table = firefly_pwm_match,
},
};

static int __init firefly_pwm_init(void)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return platform_driver_register(&firefly_pwm_driver);
}

static void __exit firefly_pwm_exit(void)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
platform_driver_unregister(&firefly_pwm_driver);
}

module_init(firefly_pwm_init);
module_exit(firefly_pwm_exit);

MODULE_LICENSE("GPL");