aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick/gamecon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joystick/gamecon.c')
-rw-r--r--drivers/input/joystick/gamecon.c125
1 files changed, 119 insertions, 6 deletions
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
88struct gc_subdev {
89 unsigned int idx;
90};
91
88static struct gc *gc_base[3]; 92static struct gc *gc_base[3];
89 93
90static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; 94static 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 };
100static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; 104static 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 */
132static 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 */
146static 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
243static 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
285static 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: