|
@@ -0,0 +1,113 @@
|
|
|
+#include <linux/fs.h>
|
|
|
+#include <linux/init.h>
|
|
|
+#include <linux/device.h>
|
|
|
+#include <linux/miscdevice.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/gpio.h>
|
|
|
+#include <linux/of.h>
|
|
|
+#include <linux/of_gpio.h>
|
|
|
+#include <asm/uaccess.h>
|
|
|
+#include <asm/delay.h>
|
|
|
+
|
|
|
+typedef struct { char *key; u8 value; } t_command;
|
|
|
+
|
|
|
+static t_command commands_table[] = {
|
|
|
+ { "ENDCODE", 4},
|
|
|
+ { "FORWARD", 10},
|
|
|
+ { "FORWARD_TURBO", 16},
|
|
|
+ { "TURBO", 22},
|
|
|
+ { "FORWARD_LEFT", 28},
|
|
|
+ { "FORWARD_RIGHT", 34},
|
|
|
+ { "BACKWARD", 40},
|
|
|
+ { "BACKWARD_RIGHT", 46},
|
|
|
+ { "BACKWARD_LEFT", 52},
|
|
|
+ { "LEFT", 58},
|
|
|
+ { "RIGHT", 64}
|
|
|
+};
|
|
|
+
|
|
|
+static ssize_t rx2_dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset);
|
|
|
+
|
|
|
+static const struct file_operations rx2_fops = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .write = rx2_dev_write
|
|
|
+};
|
|
|
+
|
|
|
+static struct miscdevice rx2_dev = {
|
|
|
+ MISC_DYNAMIC_MINOR,
|
|
|
+ "rx2",
|
|
|
+ &rx2_fops
|
|
|
+};
|
|
|
+
|
|
|
+static int gpio = -1;
|
|
|
+
|
|
|
+static void rx2_send_command(u8 command) {
|
|
|
+ int w = 0;
|
|
|
+
|
|
|
+ for(w = 0; w < 4; w++) {
|
|
|
+ gpio_set_value(gpio, 1);
|
|
|
+ udelay(1200);
|
|
|
+ gpio_set_value(gpio, 0);
|
|
|
+ udelay(400);
|
|
|
+ }
|
|
|
+
|
|
|
+ for(w = 0; w < command; w++) {
|
|
|
+ gpio_set_value(gpio, 1);
|
|
|
+ udelay(400);
|
|
|
+ gpio_set_value(gpio, 0);
|
|
|
+ udelay(400);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t rx2_dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset) {
|
|
|
+ u8 n;
|
|
|
+ for(n = 0; n < sizeof(commands_table) / sizeof(t_command); n++) {
|
|
|
+ if(strcmp(commands_table[n].key, buffer) == 0) {
|
|
|
+ printk(KERN_INFO "%s %i\n", commands_table[n].key, commands_table[n].value);
|
|
|
+ rx2_send_command(commands_table[n].value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+static int __init rx2_init(void) {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if(!gpio_is_valid(gpio)) {
|
|
|
+ printk(KERN_ERR "rx2: invalid gpio\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ ret = gpio_request(gpio, "ant");
|
|
|
+ if(ret) {
|
|
|
+ if (ret == -EINVAL)
|
|
|
+ ret = -EPROBE_DEFER;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ printk(KERN_INFO "rx2: ant on gpio: %i\n",gpio);
|
|
|
+ gpio_direction_output(gpio, 0);
|
|
|
+
|
|
|
+ ret = misc_register(&rx2_dev);
|
|
|
+
|
|
|
+ if(ret) {
|
|
|
+ printk(KERN_ERR "Unable to register rx2 device\n");
|
|
|
+ gpio_free(gpio);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void __exit rx2_exit(void) {
|
|
|
+ gpio_free(gpio);
|
|
|
+ misc_deregister(&rx2_dev);
|
|
|
+}
|
|
|
+
|
|
|
+module_init(rx2_init);
|
|
|
+module_exit(rx2_exit);
|
|
|
+
|
|
|
+module_param(gpio, int, 0444);
|
|
|
+MODULE_PARM_DESC(gpio, "Guess what");
|
|
|
+
|
|
|
+MODULE_LICENSE("GPL");
|
|
|
+MODULE_AUTHOR("encrypt <encrypt@labr.xyz>");
|
|
|
+MODULE_DESCRIPTION("Stupid driver for RX2 ic");
|
|
|
+MODULE_VERSION("0.1");
|