#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "light_ring.h" #define DEVICE_NAME "fan" #define CLASS_NAME "fan_class" #define DRIVER_NAME "fan_driver" struct fan_dev { struct cdev cdev; dev_t devt; struct class *class; struct device *device; }; extern struct kobject *vfiec_kobj; static struct kobject *fan_kobj = NULL; static int major = 0; // 主设备号(0表示动态分配) static struct fan_dev *fan_dev_device = NULL; static dev_t dev_num; // 文件打开 static int fan_open(struct inode *inode, struct file *filp) { // 从inode获取cdev,再获取包含cdev的结构体 struct fan_dev *dev = container_of(inode->i_cdev, struct fan_dev, cdev); filp->private_data = dev; // 保存到file结构供其他函数使用 printk(KERN_INFO "fan: device opened\n"); return 0; } // 文件释放 static int fan_release(struct inode *inode, struct file *filp) { printk(KERN_INFO "fan: device closed\n"); return 0; } // 读操作 static ssize_t fan_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct fan_dev *dev = filp->private_data; return count; } // 写操作 static ssize_t fan_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct fan_dev *dev = filp->private_data; printk(KERN_INFO "fan: wrote %zu bytes\n", count); return count; } // 文件操作结构体 static struct file_operations fan_fops = { .owner = THIS_MODULE, .open = fan_open, .release = fan_release, .read = fan_read, .write = fan_write, }; static ssize_t fan1_input_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "fan1_input_show count=%d\n", count); } static ssize_t fan1_input_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("fan1_input_store kernel rev:%s\n", buf); return count; } static ssize_t fan2_input_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "fan2_input_show count=%d\n", count); } static ssize_t fan2_input_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("fan2_input_store kernel rev:%s\n", buf); return count; } static ssize_t pwm1_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "pwm1_show count=%d\n", count); } static ssize_t pwm1_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("pwm1_store kernel rev:%s\n", buf); return count; } static ssize_t pwm1_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "pwm1_enable_show count=%d\n", count); } static ssize_t pwm1_enable_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("pwm1_enable_store kernel rev:%s\n", buf); return count; } static ssize_t pwm2_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "pwm2_show count=%d\n", count); } static ssize_t pwm2_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("pwm2_store kernel rev:%s\n", buf); return count; } static ssize_t pwm2_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "pwm2_enable_show count=%d\n", count); } static ssize_t pwm2_enable_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("pwm2_enable_store kernel rev:%s\n", buf); return count; } static ssize_t voltage_5v_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "voltage_5v_show count=%d\n", count); } static ssize_t voltage_5v_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("voltage_5v_store kernel rev:%s\n", buf); return count; } static ssize_t voltage_12v_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "voltage_12v_show count=%d\n", count); } static ssize_t voltage_12v_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("voltage_12v_store kernel rev:%s\n", buf); return count; } static ssize_t voltage_vcore_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "voltage_vcore_show count=%d\n", count); } static ssize_t voltage_vcore_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("voltage_vcore_store kernel rev:%s\n", buf); return count; } static ssize_t ac_power_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "ac_power_show count=%d\n", count); } static ssize_t ac_power_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("ac_power_store kernel rev:%s\n", buf); return count; } static ssize_t power_flag_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { static int count = 0; count++; return sprintf(buf, "power_flag_show count=%d\n", count); } static ssize_t power_flag_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { printk("power_flag_store kernel rev:%s\n", buf); return count; } static struct kobj_attribute fan1_input = __ATTR(fan1_input, 0644, fan1_input_show, fan1_input_store); static struct kobj_attribute fan2_input = __ATTR(fan2_input, 0644, fan2_input_show, fan2_input_store); static struct kobj_attribute pwm1 = __ATTR(pwm1, 0644, pwm1_show, pwm1_store); static struct kobj_attribute pwm1_enable = __ATTR(pwm1_enable, 0644, pwm1_enable_show, pwm1_enable_store); static struct kobj_attribute pwm2 = __ATTR(pwm2, 0644, pwm2_show, pwm2_store); static struct kobj_attribute pwm2_enable = __ATTR(pwm2_enable, 0644, pwm2_enable_show, pwm2_enable_store); static struct kobj_attribute voltage_5v = __ATTR(voltage_5v, 0644, voltage_5v_show, voltage_5v_store); static struct kobj_attribute voltage_12v = __ATTR(voltage_12v, 0644, voltage_12v_show, voltage_12v_store); static struct kobj_attribute voltage_vcore = __ATTR(voltage_vcore, 0644, voltage_vcore_show, voltage_vcore_store); static struct kobj_attribute ac_power = __ATTR(ac_power, 0644, ac_power_show, ac_power_store); static struct kobj_attribute power_flag = __ATTR(power_flag, 0644, power_flag_show, power_flag_store); /* ==================== 属性组 ==================== */ static struct attribute *fan_attrs[] = { &fan1_input.attr, &fan2_input.attr, &pwm1.attr, &pwm1_enable.attr, &pwm2.attr, &pwm2_enable.attr, &voltage_5v.attr, &voltage_12v.attr, &voltage_vcore.attr, &ac_power.attr, &power_flag.attr, NULL, }; static struct attribute_group fan_attr_group = { .attrs = fan_attrs, }; int fan_init(void) { int ret; /* 创建 /sys/kernel/vfiec/lightring */ fan_kobj = kobject_create_and_add("hwmon", vfiec_kobj); if (!fan_kobj) { ret = -ENOMEM; } else { printk(KERN_INFO "Faifan to create sysfs node\n"); } /* 创建属性文件 */ ret = sysfs_create_group(fan_kobj, &fan_attr_group); if (ret) { pr_err("Faifan to create sysfs group: %d\n", ret); goto free_fan_kobj; } else { printk(KERN_INFO "Create sysfs group success\n"); } ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); if (ret < 0) { printk(KERN_ALERT "mychar: Failed to allocate device number\n"); goto free_group; } major = MAJOR(dev_num); printk(KERN_INFO "mychar: Assigned major number %d\n", major); // 2. 分配设备结构体内存 fan_dev_device = kzalloc(sizeof(struct fan_dev), GFP_KERNEL); if (!fan_dev_device) { printk(KERN_ALERT "mychar: Failed to allocate device memory\n"); ret = -ENOMEM; goto free_chrdev; } cdev_init(&fan_dev_device->cdev, &fan_fops); fan_dev_device->cdev.owner = THIS_MODULE; ret = cdev_add(&fan_dev_device->cdev, dev_num, 1); if (ret < 0) { printk(KERN_ALERT "mychar: Failed to add cdev\n"); goto free_fan_devices; } // 4. 创建设备类(用于自动创建/dev节点) fan_dev_device->class = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(fan_dev_device->class)) { printk(KERN_ALERT "mychar: Failed to create class\n"); goto free_cdev_del; } // 5. 创建设备节点(会在/dev下生成) fan_dev_device->device = device_create(fan_dev_device->class, NULL, dev_num, NULL, DEVICE_NAME); if (IS_ERR(fan_dev_device->device)) { printk(KERN_ALERT "mychar: Failed to create device\n"); goto free_class; } return 0; free_class: class_destroy(fan_dev_device->class); free_cdev_del: cdev_del(&fan_dev_device->cdev); free_fan_devices: kfree(fan_dev_device); free_chrdev: unregister_chrdev_region(dev_num, 1); free_group: sysfs_remove_group(fan_kobj, &fan_attr_group); free_fan_kobj: kobject_put(fan_kobj); return ret; } void fan_exit(void) { device_destroy(fan_dev_device->class, dev_num); class_destroy(fan_dev_device->class); cdev_del(&fan_dev_device->cdev); kfree(fan_dev_device); unregister_chrdev_region(dev_num, 1); sysfs_remove_group(fan_kobj, &fan_attr_group); kobject_put(fan_kobj); }