summaryrefslogtreecommitdiff
path: root/relay_control.c
blob: 7b0e59c9c0c0a95ee1e9894aee0483db4731cfa9 (plain)
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);