diff options
Diffstat (limited to 'drivers/input/joystick/twidjoy.c')
-rw-r--r-- | drivers/input/joystick/twidjoy.c | 120 |
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 | ||
72 | static char *twidjoy_name = "Handykey Twiddler"; | ||
73 | |||
74 | static struct twidjoy_button_spec { | 72 | static 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 | ||
97 | struct twidjoy { | 95 | struct 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 | ||
109 | static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs) | 107 | static 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 | /* |