Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // LPT Cabinet Driver writed in C
- // Alterado by Rnery
- #include <linux/kernel.h>
- #include <linux/delay.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/init.h>
- #include <linux/parport.h>
- #include <linux/input.h>
- // UNCOMMENT FOR DEBUG :D
- // #define DEBUG_SPP
- MODULE_AUTHOR("Rodrigo Nery <rodrigonery@hotmail.com.br>");
- MODULE_DESCRIPTION("A LPT Arcade Cabinet Driver for Linux");
- MODULE_LICENSE("GPL");
- #define GC_MAX_PORTS 1
- #define GC_MAX_DEVICES 5
- struct gc_config {
- int args[GC_MAX_DEVICES + 1];
- int nargs;
- };
- static struct gc_config gc[GC_MAX_PORTS];
- module_param_array(map, int, &gc[0].args, 0);
- MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
- #if GC_MAX_PORTS > 3
- module_param_array(map2, int, &gc[1].args, 0);
- MODULE_PARM_DESC(map2, "Describes second set of devices");
- module_param_array(map3, int, &gc[2].args, 0);
- MODULE_PARM_DESC(map3, "Describes third set of devices");
- #endif
- ////////////////////////////////////
- // INITIAL PARAMETERS AND STRUCTS
- // control types
- #define GC_ARCADE 1
- #define GC_KEY1 2
- #define GC_KEY2 3
- #define GC_KEY3 4
- #define GC_MAX 4
- #define GC_REFRESH_TIME HZ / 100
- struct gc {
- struct pardevice *pd;
- struct input_dev *dev[GC_MAX_DEVICES];
- struct timer_list timer;
- unsigned char pads[GC_MAX + 1];
- int used;
- char phys[GC_MAX_DEVICES][32];
- struct mutex mutex;
- };
- static struct gc *gc_base[GC_MAX_PORTS];
- static int gc_status_bit[] = {0x40, 0x80, 0x20, 0x10, 0x08};
- static char *gc_names[] = {NULL, "Arcade Cabinet Control", "Arcade Cabinet Control Key1", "Arcade Cabinet Control Key2", "Arcade Cabinet Control Key3"};
- /*
- * Driver Arcade
- */
- #define GC_ARCADE_LENGTH 12
- #define GC_ARCADE_DELAY 15
- static void gc_arcade_read_packet(struct gc *gc, int tam, unsigned char *data)
- {
- unsigned char i;
- #ifdef DEBUG_SPP
- unsigned char tmp;
- static int test[4] = {0xf, 0xf, 0xf, 0xf};
- #endif
- udelay(GC_ARCADE_DELAY); //waiting
- for (i = 0; i < (tam - 4); i++)
- { //write 8 bits
- parport_write_data(gc->pd->port, ~(1 << i)); //11111011 (0 open)
- data[i] = parport_read_status(gc->pd->port) ^ 0x7f;
- #ifdef DEBUG_SPP
- if ((0x20 & data[i]) != 0)
- printk(KERN_INFO "arcade.c: Read in %i! DATA[%x] \n", i, (0x20 & data[i]));
- #endif
- }
- parport_write_data(gc->pd->port, 0xff); //cleaning
- for (i = 8; (i < tam); i++)
- {
- if (i != 10) //INIT LINE
- parport_write_control(gc->pd->port, (1 << (i - 8) | PARPORT_CONTROL_INIT));
- else
- parport_write_control(gc->pd->port, 0x0); //Active the INIT line (works inverted)
- data[i] = parport_read_status(gc->pd->port) ^ 0x7f; //filter
- #ifdef DEBUG_SPP
- tmp = parport_read_control(gc->pd->port);
- if (test[(i - 8)] != data[i])
- { //debug
- test[(i - 8)] = data[i];
- printk(KERN_INFO "arcade.c: HI - Change in %i! DATA[%x] - CONTROL[%x]\n", i, data[i], tmp);
- }
- #endif
- }
- parport_write_control(gc->pd->port, PARPORT_CONTROL_INIT); //clean
- }
- #define GC_MAX_LENGTH GC_ARCADE_LENGTH
- static void arcade_control_process_packet(struct gc *gc)
- {
- unsigned char data[GC_MAX_LENGTH];
- struct input_dev *dev;
- int i, s;
- memset(data, 0, sizeof(char) * GC_MAX_LENGTH); //clean
- gc_arcade_read_packet(gc, GC_ARCADE_LENGTH, data);
- for (i = 0; i < GC_MAX_DEVICES; i++)
- {
- dev = gc->dev[i];
- if (!dev)
- continue;
- s = gc_status_bit[i]; //set the bit to find
- if (s & (gc->pads[GC_ARCADE]))
- { //check connected pads
- input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); //left or right
- input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); //up or down
- input_report_key(dev, BTN_0, s & data[4]); //button 1
- input_report_key(dev, BTN_1, s & data[5]); //button 2
- input_report_key(dev, BTN_2, s & data[6]); //button 3
- input_report_key(dev, BTN_3, s & data[7]); //button 4
- //___________ USING CONTROL LINE ___________
- input_report_key(dev, BTN_4, s & data[8]); //button 5
- input_report_key(dev, BTN_5, s & data[9]); //button 6
- input_report_key(dev, BTN_6, s & data[10]); //button 7
- input_report_key(dev, BTN_7, s & data[11]); //button 8
- }
- input_sync(dev);
- }
- }
- static void arcade_keyboard1_process_packet(struct gc *gc)
- {
- unsigned char data[GC_MAX_LENGTH];
- struct input_dev *dev;
- int i, s;
- memset(data, 0, sizeof(char) * GC_MAX_LENGTH); //clean
- gc_arcade_read_packet(gc, GC_ARCADE_LENGTH, data);
- for (i = 0; i < GC_MAX_DEVICES; i++)
- {
- dev = gc->dev[i];
- if (!dev)
- continue;
- s = gc_status_bit[i]; //set the bit to find
- if (s & (gc->pads[GC_KEY1]))
- { //check connected pads
- input_report_key(dev, KEY_UP, s & data[0]); //up
- input_report_key(dev, KEY_DOWN, s & data[1]); //down
- input_report_key(dev, KEY_LEFT, s & data[2]); //left
- input_report_key(dev, KEY_RIGHT, s & data[3]); //right
- input_report_key(dev, KEY_SPACE, s & data[4]); //button 1
- input_report_key(dev, KEY_ENTER, s & data[5]); //button 2
- input_report_key(dev, KEY_LEFTCTRL, s & data[6]); //button 3
- input_report_key(dev, KEY_LEFTALT, s & data[7]); //button 4
- }
- input_sync(dev);
- }
- }
- static void arcade_keyboard2_process_packet(struct gc *gc)
- {
- unsigned char data[GC_MAX_LENGTH];
- struct input_dev *dev;
- int i, s;
- memset(data, 0, sizeof(char) * GC_MAX_LENGTH); //clean
- gc_arcade_read_packet(gc, GC_ARCADE_LENGTH, data);
- for (i = 0; i < GC_MAX_DEVICES; i++)
- {
- dev = gc->dev[i];
- if (!dev)
- continue;
- s = gc_status_bit[i]; //set the bit to find
- if (s & (gc->pads[GC_KEY2]))
- { //check connected pads
- input_report_key(dev, KEY_A, s & data[0]); //button 1
- input_report_key(dev, KEY_S, s & data[1]); //button 2
- input_report_key(dev, KEY_D, s & data[2]); //button 3
- input_report_key(dev, KEY_F, s & data[3]); //button 4
- input_report_key(dev, KEY_Q, s & data[4]); //button 5
- input_report_key(dev, KEY_W, s & data[5]); //button 6
- input_report_key(dev, KEY_E, s & data[6]); //button 7
- input_report_key(dev, KEY_R, s & data[7]); //button 8
- input_report_key(dev, KEY_LEFT, s & data[8]); //left
- input_report_key(dev, KEY_RIGHT, s & data[9]);//right
- input_report_key(dev, KEY_DOWN, s & data[10]);//down
- input_report_key(dev, KEY_UP, s & data[11]); //up
- }
- input_sync(dev);
- }
- }
- static void arcade_keyboard3_process_packet(struct gc *gc)
- {
- unsigned char data[GC_MAX_LENGTH];
- struct input_dev *dev;
- int i, s;
- memset(data, 0, sizeof(char) * GC_MAX_LENGTH); //clean
- gc_arcade_read_packet(gc, GC_ARCADE_LENGTH, data);
- for (i = 0; i < GC_MAX_DEVICES; i++)
- {
- dev = gc->dev[i];
- if (!dev)
- continue;
- s = gc_status_bit[i]; //set the bit to find
- if (s & (gc->pads[GC_KEY3]))
- { //check connected pads
- input_report_key(dev, KEY_1, s & data[0]); //button 1
- input_report_key(dev, KEY_2, s & data[1]); //button 2
- input_report_key(dev, KEY_3, s & data[2]); //button 3
- input_report_key(dev, KEY_4, s & data[3]); //button 4
- input_report_key(dev, KEY_5, s & data[4]); //button 5
- input_report_key(dev, KEY_6, s & data[5]); //button 6
- input_report_key(dev, KEY_7, s & data[6]); //button 7
- input_report_key(dev, KEY_8, s & data[7]); //button 8
- input_report_key(dev, KEY_ESC, s & data[8]); //button 9
- input_report_key(dev, KEY_TAB, s & data[9]); //button 10
- input_report_key(dev, KEY_LEFT, s & data[10]);//left
- input_report_key(dev, KEY_RIGHT, s & data[11]);//right
- }
- input_sync(dev);
- }
- }
- static void arcade_timer(struct timer_list *t)
- {
- struct gc *gc = from_timer(gc, t, timer);
- mutex_lock(&gc->mutex);
- switch (gc->used)
- {
- case GC_ARCADE:
- arcade_control_process_packet(gc);
- break;
- case GC_KEY1:
- arcade_keyboard1_process_packet(gc);
- break;
- case GC_KEY2:
- arcade_keyboard2_process_packet(gc);
- break;
- case GC_KEY3:
- arcade_keyboard3_process_packet(gc);
- break;
- }
- mutex_unlock(&gc->mutex);
- mod_timer(&gc->timer, jiffies + msecs_to_jiffies(GC_REFRESH_TIME));
- }
- static int arcade_setup_control(struct gc *gc, int idx, int pad_type)
- {
- gc->used = pad_type;
- mutex_init(&gc->mutex);
- gc->timer.function = arcade_timer;
- gc->timer.data = (unsigned long)gc;
- timer_setup(&gc->timer, arcade_timer, 0);
- // ... (restante da função)
- return 0;
- }
- static struct gc *arcade_probe(int parport, int *pads, int n_pads)
- {
- // ... (restante da função)
- for (i = 0; i < GC_MAX_DEVICES; i++)
- {
- if (pads[i] == 0)
- continue;
- gc->dev[i] = input_allocate_device();
- if (!gc->dev[i])
- goto err_free_dev;
- gc->dev[i]->evbit[0] = BIT_MASK(EV_KEY);
- input_set_capability(gc->dev[i], EV_KEY, KEY_LEFT);
- // ... (restante da função)
- }
- // ... (restante da função)
- return gc;
- err_free_dev:
- for (i = 0; i < GC_MAX_DEVICES; i++)
- if (gc->dev[i])
- input_free_device(gc->dev[i]);
- kfree(gc);
- return NULL;
- }
- static int __init arcade_init(void)
- {
- // ... (restante da função)
- for (i = 0; i < GC_MAX_PORTS; i++)
- {
- if (!gc_base[i])
- continue;
- mutex_lock(&gc_base[i]->mutex);
- setup_timer(&gc_base[i]->timer, arcade_timer, (unsigned long)gc_base[i]);
- mod_timer(&gc_base[i]->timer, jiffies + msecs_to_jiffies(GC_REFRESH_TIME));
- mutex_unlock(&gc_base[i]->mutex);
- }
- // ... (restante da função)
- return 0;
- }
- static void __exit arcade_exit(void)
- {
- // ... (restante da função)
- for (i = 0; i < GC_MAX_PORTS; i++)
- {
- if (gc_base[i])
- {
- del_timer_sync(&gc_base[i]->timer);
- mutex_destroy(&gc_base[i]->mutex);
- kfree(gc_base[i]);
- }
- }
- // ... (restante da função)
- }
- module_init(arcade_init);
- module_exit(arcade_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement