首先看设备树的pwm节点:
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输出例子:
pwm_demo: pwm_demo {
status = "okay";
compatible = "firefly,rk3399-pwm";
pwm_id = <0>; //使用pwm0通道
min_period = <0>;
max_period = <10000>;
duty_ns = <5000>;
};
......
#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"); //索引值index = 0;即使用pwm0
ret = pwm_config(pwm_device, 500000, 1000000); //没有用设备树的,直接写死占空比50%
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");