commit c2f0bfbe8b9e876da60ca258bc4f0a59f7bc685c Author: encrypt Date: Wed Jun 1 12:43:43 2016 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..358b0ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*~ +*.ko +*.mod* +*.o +*.cmd +Module.symvers +modules.order +.tmp_versions/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..912d238 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +obj-m := rx2.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +DEPMOD:=$(shell which depmod) +# possible bug: maybe this will work only on debian based systems +SYSMAP:= /boot/System.map-$(shell uname -r) + +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules + +install: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install + $(DEPMOD) -ae -F $(SYSMAP) + +clean: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean diff --git a/rx2.c b/rx2.c new file mode 100644 index 0000000..7922ebe --- /dev/null +++ b/rx2.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 "); +MODULE_DESCRIPTION("Stupid driver for RX2 ic"); +MODULE_VERSION("0.1");