#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");
04-22
3583
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
12-01
2949
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-24
1232
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)