rx2-lkm/rx2.c
2016-06-01 12:43:43 +02:00

113 lines
2.5 KiB
C

#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");