OrangePi3 LTS 驱动开发- PWM

OrangePi3 LTS PWM的使用

kernel版本:orange-pi-5.10-media
根据使用手册,26pin中的pwm0默认是不开启的,需要开机后修改/boot/orangepiEnv.txt,在其中添加overlays=pwm字样,才可以启用。
如果不添加字样,如何默认开启pwm0 呢,修改dts配置文件。
pwm0对应的管脚pd22,在pinctrl默认将pmux配置成了uart2。
1、修改pinctrl节点,注释掉uart的pinctrl配置

// uart2_rts_cts_pins: uart2-rts-cts-pins {
// 	pins = "PD21", "PD22";
// 	function = "uart2";
// };

2、添加pwm0的pinctrl配置

pwm0_pin: pwm0-pin {
	pins = "PD22";
	function = "pwm";
};	

在这里插入图片描述
3、修改驱动使用的节点
在这里插入图片描述

驱动文件

/**
* dts config
* 
 * 	sys_fans{

	compatible = "max, fans";
	pwms = <&pwm 0 1000000 1>;
	};

	*/

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/err.h>

#include <linux/pwm.h>
#include <linux/printk.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/delay.h>
#include <linux/kthread.h>

#include "../type.h"
#include "pwm_test.h"


static ssize_t name_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	return sprintf(buf, "%s\n", DRIVER_NAME);
}
static DEVICE_ATTR(name, 0444, name_show,NULL);

static struct attribute *attrs[] = {
	&dev_attr_name.attr,
	NULL,	/* need to NULL terminate the list of attributes */
};

static struct attribute_group attr_group = {
	.attrs = attrs,
};

static int dts_parse(struct platform_device *pdev)
{

int ret = 0;
struct device_node * node;
const char *str;
max_pwms_driver * max_pwms = (max_pwms_driver *)platform_get_drvdata(pdev); 
struct pwm_state        pstate;

node = pdev->dev.of_node;
if (!node) 
{
	max_error("failed to find node for %s\n",DEVICE_NAME);
	return -ENODEV;
}
max_pwms->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL);
if (IS_ERR(max_pwms->pwm)) 
{
	dev_err(&pdev->dev, "Could not get PWM\n");
}
else
{
	max_info("devm_of_pwm_get pwm success\n");
}
// pwm_init_state( max_pwms->pwm, &pstate);

// pr_info("pstate->period===%d\n",pstate.period);
// pr_info("pstate->duty_cycle===%d\n",pstate.duty_cycle);
// pr_info("pstate->polarity===%d\n",pstate.polarity);
max_info("devm_of_pwm_get pwm success\n");

pwm_config(max_pwms->pwm, 500000, 1000000);
//pwm_set_polarity(max_pwms->pwm, PWM_POLARITY_INVERSED);
pwm_enable(max_pwms->pwm);

return 0;
 error:
	return -EINVAL;    
}

static int max_pwm_probe(struct platform_device *pdev)
{
    int ret = 0;
	struct class 			*pwms_class;
	max_pwms_driver      	*max_pwms;

max_pwms = kzalloc(sizeof(max_pwms_driver), GFP_KERNEL);
if (!max_pwms) {
	max_error("kzalloc max_pwms error\n");
	return -ENOMEM;
}

mutex_init(&max_pwms->mutex);

platform_set_drvdata(pdev, max_pwms);
ret = dts_parse(pdev);
if (ret){
	max_error("dts parse error\n");
	goto malloc_error;
}

pwms_class = class_create(THIS_MODULE, DRIVER_NAME);
if (IS_ERR(pwms_class)) {
	ret= PTR_ERR(pwms_class);
	max_error("pwms_class: class create failed\n");
	goto malloc_error;
}

max_pwms->dev = device_create(pwms_class,
		 &pdev->dev, 0, NULL, DEVICE_NAME);
if (unlikely(IS_ERR(max_pwms->dev))) {
	ret = PTR_ERR(max_pwms->dev);
	max_pwms->dev = NULL;
	goto destory_class;
}

ret = sysfs_create_group(&max_pwms->dev->kobj, &attr_group);
if(ret){
	max_error("sysfs_create_group in leds driver\n");
	goto destory_device;
}

dev_set_drvdata(max_pwms->dev,max_pwms);
max_info("max_pwm_probe success \n");
return 0;


destory_device:
	device_destroy(pwms_class,0);
destory_class:
	class_destroy(pwms_class);
malloc_error:
	kfree(max_pwms);
	return -ENODEV;
}

static int max_pwm_remove(struct platform_device *pdev)
{
	max_pwms_driver * max_pwms = (max_pwms_driver *)platform_get_drvdata(pdev); 
	platform_set_drvdata(pdev, NULL);
	kfree(max_pwms);
	return 0;
}

static const struct of_device_id max_pwm_dt_match[] = {
	{
		.compatible = "max, fans",
	},
	{},
};

static struct platform_driver pwm_driver = {
	.driver = {
		.name =  DEVICE_NAME,
		.owner = THIS_MODULE,
		.of_match_table = max_pwm_dt_match,
	},
	.probe = max_pwm_probe,
	.remove = max_pwm_remove,
};

static int __init orange_pwm_init(void)
{
    if (platform_driver_register(&pwm_driver)) {
		max_error("failed to register driver\n");
		return -ENODEV;
	}
	max_info("orange_pwm_init:module init\n");
	return 0;
}

static void __exit orange_pwm_exit(void)
{
	max_info("orange_pwm_exit module exit\n");
}

module_init(orange_pwm_init);
module_exit(orange_pwm_exit);

MODULE_DESCRIPTION("Max Pwm Test Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("738270732@qq.com");

.h文件

#ifndef __PWM_TEST_H__
#define __PWM_TEST_H__


#define DRIVER_NAME     "max_pwm"
#define DEVICE_NAME     "pwms"

typedef struct  pwm_driver
{
	struct mutex 		mutex;
    struct device     	*dev;
    struct pwm_device   *pwm;
    unsigned int period;
	unsigned int enable;
	unsigned int duty;

}max_pwms_driver;

#endif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值