实现gpio风扇控制分5档转速,用hrtimer实现

#include <linux/module.h>		// module_init  module_exit
#include <linux/init.h>			// __init   __exit
#include <asm/gpio.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/hrtimer.h>

#define SYNWAY_FAN_GPIO	40

static unsigned char fan_gear = 5;
struct hrtimer gpio_pwm_timer;
ktime_t fan_kt;

extern int check_synway_hardid(void);


static ssize_t pwm_fan_show(struct kobject *kobj,
        struct kobj_attribute *attr, char *buf)
{
        sprintf(buf,"风扇档位为:%d. (档位0~5)\n", fan_gear);

        return strlen(buf);
}

static ssize_t pwm_fan_store(struct kobject *kobj,
        struct kobj_attribute *attr, const char *buf, size_t count)
{
	char tmp[128] = { 0 };
	memcpy(tmp, buf, count - 1);
	printk("synway pwm_fan = %s \n", tmp);

	fan_gear = simple_strtol(tmp, NULL, 10);
	

	return count;
}

static struct kobject pwm_fan_kobj;

static struct kobj_attribute pwm_fan_attribute = __ATTR(pwm_fan,
                0664, pwm_fan_show, pwm_fan_store);

int fan_pwm_kobj_init(void)
{
        int err = -1;
        pwm_fan_kobj = *(kobject_create_and_add("pwm_fan", kernel_kobj));
        err = sysfs_create_file(&pwm_fan_kobj, &pwm_fan_attribute.attr);
        if (err) {
        	kobject_put(&pwm_fan_kobj);
                printk("+ sysfs create fail .\n");
	}
	return err;
}

#if 1
static enum hrtimer_restart fan_pwm_fun(struct hrtimer *timer)
{	
	if (gpio_get_value(SYNWAY_FAN_GPIO) == 0) {
		gpio_set_value(SYNWAY_FAN_GPIO, 1);
		fan_kt = ktime_set(0, fan_gear * 2000000);

	}
	else {
		gpio_set_value(SYNWAY_FAN_GPIO, 0);
		fan_kt = ktime_set(0, (10000000 - fan_gear * 2000000));
	}
	
	hrtimer_forward_now(&gpio_pwm_timer, fan_kt);
	return HRTIMER_RESTART;
}
#endif


static int __init pwm_init(void)
{	
	int err = -1;
	printk(KERN_INFO "dummy pwm_init init HZ = %d\n", HZ);
	err = check_synway_hardid();
	if (err < 3)
		return 0;
	err = 0;
	err = gpio_request_one(SYNWAY_FAN_GPIO, GPIOF_OUT_INIT_HIGH, "fan_gpio");
	if (err){
		gpio_free(SYNWAY_FAN_GPIO);
                return -1;
	}
	fan_pwm_kobj_init();


	hrtimer_init(&gpio_pwm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        gpio_pwm_timer.function = fan_pwm_fun;
	hrtimer_start(&gpio_pwm_timer, ktime_set(0, 10000000), HRTIMER_MODE_REL);//ktime_set第一个参数是秒,第二个是纳秒

	return 0;
}


static void __exit pwm_exit(void)
{
	int err = -1;
	printk(KERN_INFO "dummy pwm_exit exit\n");
	
	err = check_synway_hardid();
        if (err > 3)   
                return ;
     
	hrtimer_cancel(&gpio_pwm_timer);
	kobject_put(&pwm_fan_kobj);
	gpio_free(SYNWAY_FAN_GPIO);
}


module_init(pwm_init);
module_exit(pwm_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("synway");
MODULE_DESCRIPTION("module test gpio to dummy pwm");













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值