aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick/twidjoy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joystick/twidjoy.c')
-rw-r--r--drivers/input/joystick/twidjoy.c120
1 files changed, 52 insertions, 68 deletions
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index 0379bc166525..cd3a1e742a30 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -69,8 +69,6 @@ MODULE_LICENSE("GPL");
69 69
70#define TWIDJOY_MAX_LENGTH 5 70#define TWIDJOY_MAX_LENGTH 5
71 71
72static char *twidjoy_name = "Handykey Twiddler";
73
74static struct twidjoy_button_spec { 72static struct twidjoy_button_spec {
75 int bitshift; 73 int bitshift;
76 int bitmask; 74 int bitmask;
@@ -95,7 +93,7 @@ twidjoy_buttons[] = {
95 */ 93 */
96 94
97struct twidjoy { 95struct twidjoy {
98 struct input_dev dev; 96 struct input_dev *dev;
99 int idx; 97 int idx;
100 unsigned char data[TWIDJOY_MAX_LENGTH]; 98 unsigned char data[TWIDJOY_MAX_LENGTH];
101 char phys[32]; 99 char phys[32];
@@ -108,37 +106,33 @@ struct twidjoy {
108 106
109static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs) 107static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
110{ 108{
111 if (twidjoy->idx == TWIDJOY_MAX_LENGTH) { 109 struct input_dev *dev = twidjoy->dev;
112 struct input_dev *dev = &twidjoy->dev; 110 unsigned char *data = twidjoy->data;
113 unsigned char *data = twidjoy->data; 111 struct twidjoy_button_spec *bp;
114 struct twidjoy_button_spec *bp; 112 int button_bits, abs_x, abs_y;
115 int button_bits, abs_x, abs_y;
116
117 button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
118 113
119 input_regs(dev, regs); 114 button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
120 115
121 for (bp = twidjoy_buttons; bp->bitmask; bp++) { 116 input_regs(dev, regs);
122 int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
123 int i;
124 117
125 for (i = 0; i < bp->bitmask; i++) 118 for (bp = twidjoy_buttons; bp->bitmask; bp++) {
126 input_report_key(dev, bp->buttons[i], i+1 == value); 119 int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
127 } 120 int i;
128 121
129 abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2); 122 for (i = 0; i < bp->bitmask; i++)
130 if (data[4] & 0x08) abs_x -= 256; 123 input_report_key(dev, bp->buttons[i], i+1 == value);
124 }
131 125
132 abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0); 126 abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
133 if (data[3] & 0x02) abs_y -= 256; 127 if (data[4] & 0x08) abs_x -= 256;
134 128
135 input_report_abs(dev, ABS_X, -abs_x); 129 abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
136 input_report_abs(dev, ABS_Y, +abs_y); 130 if (data[3] & 0x02) abs_y -= 256;
137 131
138 input_sync(dev); 132 input_report_abs(dev, ABS_X, -abs_x);
139 } 133 input_report_abs(dev, ABS_Y, +abs_y);
140 134
141 return; 135 input_sync(dev);
142} 136}
143 137
144/* 138/*
@@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct serio *serio)
179{ 173{
180 struct twidjoy *twidjoy = serio_get_drvdata(serio); 174 struct twidjoy *twidjoy = serio_get_drvdata(serio);
181 175
182 input_unregister_device(&twidjoy->dev);
183 serio_close(serio); 176 serio_close(serio);
184 serio_set_drvdata(serio, NULL); 177 serio_set_drvdata(serio, NULL);
178 input_unregister_device(twidjoy->dev);
185 kfree(twidjoy); 179 kfree(twidjoy);
186} 180}
187 181
@@ -195,59 +189,49 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
195{ 189{
196 struct twidjoy_button_spec *bp; 190 struct twidjoy_button_spec *bp;
197 struct twidjoy *twidjoy; 191 struct twidjoy *twidjoy;
192 struct input_dev *input_dev;
193 int err = -ENOMEM;
198 int i; 194 int i;
199 int err;
200
201 if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
202 return -ENOMEM;
203 195
204 memset(twidjoy, 0, sizeof(struct twidjoy)); 196 twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
197 input_dev = input_allocate_device();
198 if (!twidjoy || !input_dev)
199 goto fail;
205 200
201 twidjoy->dev = input_dev;
206 sprintf(twidjoy->phys, "%s/input0", serio->phys); 202 sprintf(twidjoy->phys, "%s/input0", serio->phys);
207 203
208 init_input_dev(&twidjoy->dev); 204 input_dev->name = "Handykey Twiddler";
209 twidjoy->dev.name = twidjoy_name; 205 input_dev->phys = twidjoy->phys;
210 twidjoy->dev.phys = twidjoy->phys; 206 input_dev->id.bustype = BUS_RS232;
211 twidjoy->dev.id.bustype = BUS_RS232; 207 input_dev->id.vendor = SERIO_TWIDJOY;
212 twidjoy->dev.id.vendor = SERIO_TWIDJOY; 208 input_dev->id.product = 0x0001;
213 twidjoy->dev.id.product = 0x0001; 209 input_dev->id.version = 0x0100;
214 twidjoy->dev.id.version = 0x0100; 210 input_dev->cdev.dev = &serio->dev;
215 twidjoy->dev.dev = &serio->dev; 211 input_dev->private = twidjoy;
216 212
217 twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); 213 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
218 214 input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
219 for (bp = twidjoy_buttons; bp->bitmask; bp++) { 215 input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
216 input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
217
218 for (bp = twidjoy_buttons; bp->bitmask; bp++)
220 for (i = 0; i < bp->bitmask; i++) 219 for (i = 0; i < bp->bitmask; i++)
221 set_bit(bp->buttons[i], twidjoy->dev.keybit); 220 set_bit(bp->buttons[i], input_dev->keybit);
222 }
223
224 twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
225
226 for (i = 0; i < 2; i++) {
227 twidjoy->dev.absmax[ABS_X+i] = 50;
228 twidjoy->dev.absmin[ABS_X+i] = -50;
229
230 /* TODO: arndt 20010708: Are these values appropriate? */
231 twidjoy->dev.absfuzz[ABS_X+i] = 4;
232 twidjoy->dev.absflat[ABS_X+i] = 4;
233 }
234
235 twidjoy->dev.private = twidjoy;
236 221
237 serio_set_drvdata(serio, twidjoy); 222 serio_set_drvdata(serio, twidjoy);
238 223
239 err = serio_open(serio, drv); 224 err = serio_open(serio, drv);
240 if (err) { 225 if (err)
241 serio_set_drvdata(serio, NULL); 226 goto fail;
242 kfree(twidjoy);
243 return err;
244 }
245
246 input_register_device(&twidjoy->dev);
247
248 printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
249 227
228 input_register_device(twidjoy->dev);
250 return 0; 229 return 0;
230
231 fail: serio_set_drvdata(serio, NULL);
232 input_free_device(input_dev);
233 kfree(twidjoy);
234 return err;
251} 235}
252 236
253/* 237/*