1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/string.h>
MODULE_LICENSE("GPL");
#define RELAY_K1 18
#define RELAY_K2 23
#define RELAY_K3 24
#define RELAY_K4 25
#define NO_OFF 0
#define NO_ON 1
static struct kobject *relay_kobject;
static ssize_t set_relay(struct kobject *kobj, struct kobj_attribute *attr, const char *buff, size_t count) {
int relay = 0;
u8 v = 0;
sscanf(buff, "%hhd", &v);
if (strcmp(attr->attr.name, "relay1") == 0) {
relay = RELAY_K1;
} else if (strcmp(attr->attr.name, "relay2") == 0) {
relay = RELAY_K2;
} else if (strcmp(attr->attr.name, "relay3") == 0) {
relay = RELAY_K3;
} else if (strcmp(attr->attr.name, "relay4") == 0) {
relay = RELAY_K4;
}
gpio_set_value(relay, (v == 0) ? NO_OFF : NO_ON);
return count;
}
static ssize_t get_relay(struct kobject *kobj, struct kobj_attribute *attr, char *buff) {
int relay = 0;
if (strcmp(attr->attr.name, "relay1") == 0) {
relay = RELAY_K1;
} else if (strcmp(attr->attr.name, "relay2") == 0) {
relay = RELAY_K2;
} else if (strcmp(attr->attr.name, "relay3") == 0) {
relay = RELAY_K3;
} else if (strcmp(attr->attr.name, "relay4") == 0) {
relay = RELAY_K4;
}
return sprintf(buff, "%d", gpio_get_value(relay));
}
static struct kobj_attribute relay1_attribute = __ATTR(relay1, (S_IWUSR | S_IRUGO), get_relay, set_relay);
static struct kobj_attribute relay2_attribute = __ATTR(relay2, (S_IWUSR | S_IRUGO), get_relay, set_relay);
static struct kobj_attribute relay3_attribute = __ATTR(relay3, (S_IWUSR | S_IRUGO), get_relay, set_relay);
static struct kobj_attribute relay4_attribute = __ATTR(relay4, (S_IWUSR | S_IRUGO), get_relay, set_relay);
static int __init relay_init(void) {
gpio_request(RELAY_K1, "RELAY_K1");
gpio_request(RELAY_K2, "RELAY_K2");
gpio_request(RELAY_K3, "RELAY_K3");
gpio_request(RELAY_K4, "RELAY_K4");
gpio_direction_output(RELAY_K1, NO_ON);
gpio_direction_output(RELAY_K2, NO_ON);
gpio_direction_output(RELAY_K3, NO_ON);
gpio_direction_output(RELAY_K4, NO_ON);
relay_kobject = kobject_create_and_add("relay", NULL);
if (sysfs_create_file(relay_kobject, &relay1_attribute.attr)) {
pr_debug("failed to create relay1 sysfs!\n");
}
if (sysfs_create_file(relay_kobject, &relay2_attribute.attr)) {
pr_debug("failed to create relay2 sysfs!\n");
}
if (sysfs_create_file(relay_kobject, &relay3_attribute.attr)) {
pr_debug("failed to create relay3 sysfs!\n");
}
if (sysfs_create_file(relay_kobject, &relay4_attribute.attr)) {
pr_debug("failed to create relay4 sysfs!\n");
}
return 0;
}
static void __exit relay_exit(void) {
kobject_put(relay_kobject);
gpio_free(RELAY_K1);
gpio_free(RELAY_K2);
gpio_free(RELAY_K3);
gpio_free(RELAY_K4);
}
module_init(relay_init);
module_exit(relay_exit);
|