File: joystick.c

package info (click to toggle)
kernel-source-2.0.32 2.0.32-5
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 29,648 kB
  • ctags: 86,850
  • sloc: ansic: 542,141; asm: 26,201; makefile: 3,423; sh: 1,195; perl: 727; tcl: 408; cpp: 277; lisp: 211; awk: 134
file content (141 lines) | stat: -rw-r--r-- 3,485 bytes parent folder | download | duplicates (7)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Atari Joystick Driver for Linux
 * by Robert de Vries (robert@and.nl) 19Jul93
 *
 * 16 Nov 1994 Andreas Schwab
 * Support for three button mouse (shamelessly stolen from MiNT)
 * third button wired to one of the joystick directions on joystick 1
 */

#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/major.h>

#include <asm/atarikb.h>
#include <asm/atari_joystick.h>
#include <asm/atari_mouse.h>
#include <asm/segment.h>

#define MAJOR_NR    JOYSTICK_MAJOR

#define	ANALOG_JOY(n)	(!(n & 0x80))
#define	DIGITAL_JOY(n)	(n & 0x80)
#define	DEVICE_NR(n)	(MINOR(n) & 0x7f)


static struct joystick_status joystick[2];
int atari_mouse_buttons; /* for three-button mouse */

void atari_joystick_interrupt(char *buf)
{
    int j;
/*    ikbd_joystick_disable(); */

    j = buf[0] & 0x1;
    joystick[j].dir   = buf[1] & 0xF;
    joystick[j].fire  = (buf[1] & 0x80) >> 7;
    joystick[j].ready = 1;
    wake_up_interruptible(&joystick[j].wait);

    /* For three-button mouse emulation fake a mouse packet */
    if (atari_mouse_interrupt_hook &&
	j == 1 && (buf[1] & 1) != ((atari_mouse_buttons & 2) >> 1))
      {
	char faked_packet[3];

	atari_mouse_buttons = (atari_mouse_buttons & 5) | ((buf[1] & 1) << 1);
	faked_packet[0] = (atari_mouse_buttons & 1) | 
			  (atari_mouse_buttons & 4 ? 2 : 0);
	faked_packet[1] = 0;
	faked_packet[2] = 0;
	atari_mouse_interrupt_hook (faked_packet);
      }

/*    ikbd_joystick_event_on(); */
}

static void release_joystick(struct inode *inode, struct file *file)
{
    int minor = DEVICE_NR(inode->i_rdev);

    joystick[minor].active = 0;
    joystick[minor].ready = 0;

    if ((joystick[0].active == 0) && (joystick[1].active == 0))
	ikbd_joystick_disable();
}

static int open_joystick(struct inode *inode, struct file *file)
{
    int minor = DEVICE_NR(inode->i_rdev);

    if (!DIGITAL_JOY(inode->i_rdev) || minor > 1)
	return -ENODEV;
    if (joystick[minor].active)
	return -EBUSY;
    joystick[minor].active = 1;
    joystick[minor].ready = 0;
    ikbd_joystick_event_on();
    return 0;
}

static int write_joystick(struct inode *inode, struct file *file,
			  const char *buffer, int count)
{
    return -EINVAL;
}

static int read_joystick(struct inode *inode, struct file *file,
			 char *buffer, int count)
{
    int minor = DEVICE_NR(inode->i_rdev);
    int i;

    if (count < 2)
	return -EINVAL;
    if (!joystick[minor].ready)
	return -EAGAIN;
    put_user(joystick[minor].fire, buffer++);
    put_user(joystick[minor].dir, buffer++);
    for (i = 0; i < count; i++)
	put_user(0, buffer++);
    joystick[minor].ready = 0;

    return i;
}

static int joystick_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
{
    int minor = DEVICE_NR(inode->i_rdev);

    if (sel_type != SEL_IN)
	return 0;
    if (joystick[minor].ready)
	return 1;
    select_wait(&joystick[minor].wait, wait);
    return 0;
}

struct file_operations atari_joystick_fops = {
	NULL,		/* joystick_seek */
	read_joystick,
	write_joystick,
	NULL,		/* joystick_readdir */
	joystick_select,
	NULL,		/* joystick_ioctl */
	NULL,		/* joystick_mmap */
	open_joystick,
	release_joystick
};

int atari_joystick_init(void)
{
    joystick[0].active = joystick[1].active = 0;
    joystick[0].ready = joystick[1].ready = 0;
    joystick[0].wait = joystick[1].wait = NULL;

    if (register_chrdev(MAJOR_NR, "joystick", &atari_joystick_fops))
	printk("unable to get major %d for joystick devices\n", MAJOR_NR);

    return 0;
}