diff options
-rw-r--r-- | drivers/input/joystick/Kconfig | 1 | ||||
-rw-r--r-- | drivers/input/joystick/gamecon.c | 125 |
2 files changed, 120 insertions, 6 deletions
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b11419590cfe..5b596165b571 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -221,6 +221,7 @@ config JOYSTICK_DB9 | |||
221 | config JOYSTICK_GAMECON | 221 | config JOYSTICK_GAMECON |
222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" | 222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" |
223 | depends on PARPORT | 223 | depends on PARPORT |
224 | select INPUT_FF_MEMLESS | ||
224 | ---help--- | 225 | ---help--- |
225 | Say Y here if you have a Nintendo Entertainment System gamepad, | 226 | Say Y here if you have a Nintendo Entertainment System gamepad, |
226 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, | 227 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, |
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 07a32aff5a31..bbde4e524da3 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -85,6 +85,10 @@ struct gc { | |||
85 | char phys[GC_MAX_DEVICES][32]; | 85 | char phys[GC_MAX_DEVICES][32]; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct gc_subdev { | ||
89 | unsigned int idx; | ||
90 | }; | ||
91 | |||
88 | static struct gc *gc_base[3]; | 92 | static struct gc *gc_base[3]; |
89 | 93 | ||
90 | static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; | 94 | static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; |
@@ -100,9 +104,16 @@ static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; | |||
100 | static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; | 104 | static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; |
101 | 105 | ||
102 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ | 106 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ |
103 | #define GC_N64_REQUEST_LENGTH 37 /* transmit request sequence is 9 bits long */ | 107 | #define GC_N64_STOP_LENGTH 5 /* Length of encoded stop bit */ |
108 | #define GC_N64_CMD_00 0x11111111UL | ||
109 | #define GC_N64_CMD_01 0xd1111111UL | ||
110 | #define GC_N64_CMD_03 0xdd111111UL | ||
111 | #define GC_N64_CMD_1b 0xdd1dd111UL | ||
112 | #define GC_N64_CMD_c0 0x111111ddUL | ||
113 | #define GC_N64_CMD_80 0x1111111dUL | ||
114 | #define GC_N64_STOP_BIT 0x1d /* Encoded stop bit */ | ||
115 | #define GC_N64_REQUEST_DATA GC_N64_CMD_01 /* the request data command */ | ||
104 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ | 116 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ |
105 | #define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */ | ||
106 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ | 117 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ |
107 | /* GC_N64_DWS > 24 is known to fail */ | 118 | /* GC_N64_DWS > 24 is known to fail */ |
108 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ | 119 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ |
@@ -114,6 +125,37 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, | |||
114 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ | 125 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ |
115 | 126 | ||
116 | /* | 127 | /* |
128 | * Used for rumble code. | ||
129 | */ | ||
130 | |||
131 | /* Send encoded command */ | ||
132 | static void gc_n64_send_command(struct gc *gc, unsigned long cmd, | ||
133 | unsigned char target) | ||
134 | { | ||
135 | struct parport *port = gc->pd->port; | ||
136 | int i; | ||
137 | |||
138 | for (i = 0; i < GC_N64_LENGTH; i++) { | ||
139 | unsigned char data = (cmd >> i) & 1 ? target : 0; | ||
140 | parport_write_data(port, GC_N64_POWER_W | data); | ||
141 | udelay(GC_N64_DWS); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | /* Send stop bit */ | ||
146 | static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target) | ||
147 | { | ||
148 | struct parport *port = gc->pd->port; | ||
149 | int i; | ||
150 | |||
151 | for (i = 0; i < GC_N64_STOP_LENGTH; i++) { | ||
152 | unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0; | ||
153 | parport_write_data(port, GC_N64_POWER_W | data); | ||
154 | udelay(GC_N64_DWS); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /* | ||
117 | * gc_n64_read_packet() reads an N64 packet. | 159 | * gc_n64_read_packet() reads an N64 packet. |
118 | * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. | 160 | * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. |
119 | */ | 161 | */ |
@@ -128,10 +170,8 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
128 | */ | 170 | */ |
129 | 171 | ||
130 | local_irq_save(flags); | 172 | local_irq_save(flags); |
131 | for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) { | 173 | gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT); |
132 | parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0)); | 174 | gc_n64_send_stop_bit(gc, GC_N64_OUT); |
133 | udelay(GC_N64_DWS); | ||
134 | } | ||
135 | local_irq_restore(flags); | 175 | local_irq_restore(flags); |
136 | 176 | ||
137 | /* | 177 | /* |
@@ -146,6 +186,7 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
146 | 186 | ||
147 | for (i = 0; i < GC_N64_LENGTH; i++) { | 187 | for (i = 0; i < GC_N64_LENGTH; i++) { |
148 | parport_write_data(gc->pd->port, GC_N64_POWER_R); | 188 | parport_write_data(gc->pd->port, GC_N64_POWER_R); |
189 | udelay(2); | ||
149 | data[i] = parport_read_status(gc->pd->port); | 190 | data[i] = parport_read_status(gc->pd->port); |
150 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); | 191 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); |
151 | } | 192 | } |
@@ -199,6 +240,70 @@ static void gc_n64_process_packet(struct gc *gc) | |||
199 | } | 240 | } |
200 | } | 241 | } |
201 | 242 | ||
243 | static int gc_n64_play_effect(struct input_dev *dev, void *data, | ||
244 | struct ff_effect *effect) | ||
245 | { | ||
246 | int i; | ||
247 | unsigned long flags; | ||
248 | struct gc *gc = input_get_drvdata(dev); | ||
249 | struct gc_subdev *sdev = data; | ||
250 | unsigned char target = 1 << sdev->idx; /* select desired pin */ | ||
251 | |||
252 | if (effect->type == FF_RUMBLE) { | ||
253 | struct ff_rumble_effect *rumble = &effect->u.rumble; | ||
254 | unsigned int cmd = | ||
255 | rumble->strong_magnitude || rumble->weak_magnitude ? | ||
256 | GC_N64_CMD_01 : GC_N64_CMD_00; | ||
257 | |||
258 | local_irq_save(flags); | ||
259 | |||
260 | /* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */ | ||
261 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
262 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
263 | gc_n64_send_command(gc, GC_N64_CMD_01, target); | ||
264 | for (i = 0; i < 32; i++) | ||
265 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
266 | gc_n64_send_stop_bit(gc, target); | ||
267 | |||
268 | udelay(GC_N64_DELAY); | ||
269 | |||
270 | /* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */ | ||
271 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
272 | gc_n64_send_command(gc, GC_N64_CMD_c0, target); | ||
273 | gc_n64_send_command(gc, GC_N64_CMD_1b, target); | ||
274 | for (i = 0; i < 32; i++) | ||
275 | gc_n64_send_command(gc, cmd, target); | ||
276 | gc_n64_send_stop_bit(gc, target); | ||
277 | |||
278 | local_irq_restore(flags); | ||
279 | |||
280 | } | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int __init gc_n64_init_ff(struct input_dev *dev, int i) | ||
286 | { | ||
287 | struct gc_subdev *sdev; | ||
288 | int err; | ||
289 | |||
290 | sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); | ||
291 | if (!sdev) | ||
292 | return -ENOMEM; | ||
293 | |||
294 | sdev->idx = i; | ||
295 | |||
296 | input_set_capability(dev, EV_FF, FF_RUMBLE); | ||
297 | |||
298 | err = input_ff_create_memless(dev, sdev, gc_n64_play_effect); | ||
299 | if (err) { | ||
300 | kfree(sdev); | ||
301 | return err; | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
202 | /* | 307 | /* |
203 | * NES/SNES support. | 308 | * NES/SNES support. |
204 | */ | 309 | */ |
@@ -624,6 +729,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
624 | { | 729 | { |
625 | struct input_dev *input_dev; | 730 | struct input_dev *input_dev; |
626 | int i; | 731 | int i; |
732 | int err; | ||
627 | 733 | ||
628 | if (!pad_type) | 734 | if (!pad_type) |
629 | return 0; | 735 | return 0; |
@@ -673,6 +779,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
673 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); | 779 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); |
674 | } | 780 | } |
675 | 781 | ||
782 | err = gc_n64_init_ff(input_dev, idx); | ||
783 | if (err) { | ||
784 | printk(KERN_WARNING "gamecon.c: Failed to initiate rumble for N64 device %d\n", idx); | ||
785 | input_free_device(input_dev); | ||
786 | return err; | ||
787 | } | ||
788 | |||
676 | break; | 789 | break; |
677 | 790 | ||
678 | case GC_SNESMOUSE: | 791 | case GC_SNESMOUSE: |