diff options
Diffstat (limited to 'drivers/input/joystick/warrior.c')
-rw-r--r-- | drivers/input/joystick/warrior.c | 83 |
1 files changed, 35 insertions, 48 deletions
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 6976a219504c..99a642d2a1fe 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -47,14 +47,13 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | #define WARRIOR_MAX_LENGTH 16 | 48 | #define WARRIOR_MAX_LENGTH 16 |
49 | static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 }; | 49 | static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 }; |
50 | static char *warrior_name = "Logitech WingMan Warrior"; | ||
51 | 50 | ||
52 | /* | 51 | /* |
53 | * Per-Warrior data. | 52 | * Per-Warrior data. |
54 | */ | 53 | */ |
55 | 54 | ||
56 | struct warrior { | 55 | struct warrior { |
57 | struct input_dev dev; | 56 | struct input_dev *dev; |
58 | int idx, len; | 57 | int idx, len; |
59 | unsigned char data[WARRIOR_MAX_LENGTH]; | 58 | unsigned char data[WARRIOR_MAX_LENGTH]; |
60 | char phys[32]; | 59 | char phys[32]; |
@@ -67,7 +66,7 @@ struct warrior { | |||
67 | 66 | ||
68 | static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs) | 67 | static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs) |
69 | { | 68 | { |
70 | struct input_dev *dev = &warrior->dev; | 69 | struct input_dev *dev = warrior->dev; |
71 | unsigned char *data = warrior->data; | 70 | unsigned char *data = warrior->data; |
72 | 71 | ||
73 | if (!warrior->idx) return; | 72 | if (!warrior->idx) return; |
@@ -131,9 +130,9 @@ static void warrior_disconnect(struct serio *serio) | |||
131 | { | 130 | { |
132 | struct warrior *warrior = serio_get_drvdata(serio); | 131 | struct warrior *warrior = serio_get_drvdata(serio); |
133 | 132 | ||
134 | input_unregister_device(&warrior->dev); | ||
135 | serio_close(serio); | 133 | serio_close(serio); |
136 | serio_set_drvdata(serio, NULL); | 134 | serio_set_drvdata(serio, NULL); |
135 | input_unregister_device(warrior->dev); | ||
137 | kfree(warrior); | 136 | kfree(warrior); |
138 | } | 137 | } |
139 | 138 | ||
@@ -146,60 +145,48 @@ static void warrior_disconnect(struct serio *serio) | |||
146 | static int warrior_connect(struct serio *serio, struct serio_driver *drv) | 145 | static int warrior_connect(struct serio *serio, struct serio_driver *drv) |
147 | { | 146 | { |
148 | struct warrior *warrior; | 147 | struct warrior *warrior; |
149 | int i; | 148 | struct input_dev *input_dev; |
150 | int err; | 149 | int err = -ENOMEM; |
151 | 150 | ||
152 | if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL))) | 151 | warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); |
153 | return -ENOMEM; | 152 | input_dev = input_allocate_device(); |
154 | 153 | if (!warrior || !input_dev) | |
155 | memset(warrior, 0, sizeof(struct warrior)); | 154 | goto fail; |
156 | |||
157 | warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); | ||
158 | warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); | ||
159 | warrior->dev.relbit[0] = BIT(REL_DIAL); | ||
160 | warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y); | ||
161 | 155 | ||
156 | warrior->dev = input_dev; | ||
162 | sprintf(warrior->phys, "%s/input0", serio->phys); | 157 | sprintf(warrior->phys, "%s/input0", serio->phys); |
163 | 158 | ||
164 | init_input_dev(&warrior->dev); | 159 | input_dev->name = "Logitech WingMan Warrior"; |
165 | warrior->dev.name = warrior_name; | 160 | input_dev->phys = warrior->phys; |
166 | warrior->dev.phys = warrior->phys; | 161 | input_dev->id.bustype = BUS_RS232; |
167 | warrior->dev.id.bustype = BUS_RS232; | 162 | input_dev->id.vendor = SERIO_WARRIOR; |
168 | warrior->dev.id.vendor = SERIO_WARRIOR; | 163 | input_dev->id.product = 0x0001; |
169 | warrior->dev.id.product = 0x0001; | 164 | input_dev->id.version = 0x0100; |
170 | warrior->dev.id.version = 0x0100; | 165 | input_dev->cdev.dev = &serio->dev; |
171 | warrior->dev.dev = &serio->dev; | 166 | input_dev->private = warrior; |
172 | 167 | ||
173 | for (i = 0; i < 2; i++) { | 168 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); |
174 | warrior->dev.absmax[ABS_X+i] = -64; | 169 | input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); |
175 | warrior->dev.absmin[ABS_X+i] = 64; | 170 | input_dev->relbit[0] = BIT(REL_DIAL); |
176 | warrior->dev.absflat[ABS_X+i] = 8; | 171 | input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8); |
177 | } | 172 | input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8); |
178 | 173 | input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0); | |
179 | warrior->dev.absmax[ABS_THROTTLE] = -112; | 174 | input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); |
180 | warrior->dev.absmin[ABS_THROTTLE] = 112; | 175 | input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); |
181 | |||
182 | for (i = 0; i < 2; i++) { | ||
183 | warrior->dev.absmax[ABS_HAT0X+i] = -1; | ||
184 | warrior->dev.absmin[ABS_HAT0X+i] = 1; | ||
185 | } | ||
186 | |||
187 | warrior->dev.private = warrior; | ||
188 | 176 | ||
189 | serio_set_drvdata(serio, warrior); | 177 | serio_set_drvdata(serio, warrior); |
190 | 178 | ||
191 | err = serio_open(serio, drv); | 179 | err = serio_open(serio, drv); |
192 | if (err) { | 180 | if (err) |
193 | serio_set_drvdata(serio, NULL); | 181 | goto fail; |
194 | kfree(warrior); | ||
195 | return err; | ||
196 | } | ||
197 | |||
198 | input_register_device(&warrior->dev); | ||
199 | |||
200 | printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys); | ||
201 | 182 | ||
183 | input_register_device(warrior->dev); | ||
202 | return 0; | 184 | return 0; |
185 | |||
186 | fail: serio_set_drvdata(serio, NULL); | ||
187 | input_free_device(input_dev); | ||
188 | kfree(warrior); | ||
189 | return err; | ||
203 | } | 190 | } |
204 | 191 | ||
205 | /* | 192 | /* |