diff options
Diffstat (limited to 'drivers/input/keyboard/hil_kbd.c')
-rw-r--r-- | drivers/input/keyboard/hil_kbd.c | 607 |
1 files changed, 398 insertions, 209 deletions
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 6f356705ee3b..c83f4b2ec7d3 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -37,19 +37,19 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/semaphore.h> | 40 | #include <linux/completion.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/pci_ids.h> | 42 | #include <linux/pci_ids.h> |
43 | 43 | ||
44 | #define PREFIX "HIL KEYB: " | 44 | #define PREFIX "HIL: " |
45 | #define HIL_GENERIC_NAME "HIL keyboard" | ||
46 | 45 | ||
47 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | 46 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); |
48 | MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); | 47 | MODULE_DESCRIPTION("HIL keyboard/mouse driver"); |
49 | MODULE_LICENSE("Dual BSD/GPL"); | 48 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | MODULE_ALIAS("serio:ty03pr25id00ex*"); | 49 | MODULE_ALIAS("serio:ty03pr25id00ex*"); /* HIL keyboard */ |
50 | MODULE_ALIAS("serio:ty03pr25id0Fex*"); /* HIL mouse */ | ||
51 | 51 | ||
52 | #define HIL_KBD_MAX_LENGTH 16 | 52 | #define HIL_PACKET_MAX_LENGTH 16 |
53 | 53 | ||
54 | #define HIL_KBD_SET1_UPBIT 0x01 | 54 | #define HIL_KBD_SET1_UPBIT 0x01 |
55 | #define HIL_KBD_SET1_SHIFT 1 | 55 | #define HIL_KBD_SET1_SHIFT 1 |
@@ -67,308 +67,497 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly = | |||
67 | 67 | ||
68 | static const char hil_language[][16] = { HIL_LOCALE_MAP }; | 68 | static const char hil_language[][16] = { HIL_LOCALE_MAP }; |
69 | 69 | ||
70 | struct hil_kbd { | 70 | struct hil_dev { |
71 | struct input_dev *dev; | 71 | struct input_dev *dev; |
72 | struct serio *serio; | 72 | struct serio *serio; |
73 | 73 | ||
74 | /* Input buffer and index for packets from HIL bus. */ | 74 | /* Input buffer and index for packets from HIL bus. */ |
75 | hil_packet data[HIL_KBD_MAX_LENGTH]; | 75 | hil_packet data[HIL_PACKET_MAX_LENGTH]; |
76 | int idx4; /* four counts per packet */ | 76 | int idx4; /* four counts per packet */ |
77 | 77 | ||
78 | /* Raw device info records from HIL bus, see hil.h for fields. */ | 78 | /* Raw device info records from HIL bus, see hil.h for fields. */ |
79 | char idd[HIL_KBD_MAX_LENGTH]; /* DID byte and IDD record */ | 79 | char idd[HIL_PACKET_MAX_LENGTH]; /* DID byte and IDD record */ |
80 | char rsc[HIL_KBD_MAX_LENGTH]; /* RSC record */ | 80 | char rsc[HIL_PACKET_MAX_LENGTH]; /* RSC record */ |
81 | char exd[HIL_KBD_MAX_LENGTH]; /* EXD record */ | 81 | char exd[HIL_PACKET_MAX_LENGTH]; /* EXD record */ |
82 | char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */ | 82 | char rnm[HIL_PACKET_MAX_LENGTH + 1]; /* RNM record + NULL term. */ |
83 | 83 | ||
84 | /* Something to sleep around with. */ | 84 | struct completion cmd_done; |
85 | struct semaphore sem; | 85 | |
86 | bool is_pointer; | ||
87 | /* Extra device details needed for pointing devices. */ | ||
88 | unsigned int nbtn, naxes; | ||
89 | unsigned int btnmap[7]; | ||
86 | }; | 90 | }; |
87 | 91 | ||
88 | /* Process a complete packet after transfer from the HIL */ | 92 | static bool hil_dev_is_command_response(hil_packet p) |
89 | static void hil_kbd_process_record(struct hil_kbd *kbd) | ||
90 | { | 93 | { |
91 | struct input_dev *dev = kbd->dev; | 94 | if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
92 | hil_packet *data = kbd->data; | 95 | return false; |
93 | hil_packet p; | ||
94 | int idx, i, cnt; | ||
95 | 96 | ||
96 | idx = kbd->idx4/4; | 97 | if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) |
97 | p = data[idx - 1]; | 98 | return false; |
98 | 99 | ||
99 | if ((p & ~HIL_CMDCT_POL) == | 100 | return true; |
100 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) | 101 | } |
101 | goto report; | 102 | |
102 | if ((p & ~HIL_CMDCT_RPL) == | 103 | static void hil_dev_handle_command_response(struct hil_dev *dev) |
103 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | 104 | { |
104 | goto report; | 105 | hil_packet p; |
106 | char *buf; | ||
107 | int i, idx; | ||
108 | |||
109 | idx = dev->idx4 / 4; | ||
110 | p = dev->data[idx - 1]; | ||
105 | 111 | ||
106 | /* Not a poll response. See if we are loading config records. */ | ||
107 | switch (p & HIL_PKT_DATA_MASK) { | 112 | switch (p & HIL_PKT_DATA_MASK) { |
108 | case HIL_CMD_IDD: | 113 | case HIL_CMD_IDD: |
109 | for (i = 0; i < idx; i++) | 114 | buf = dev->idd; |
110 | kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
111 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
112 | kbd->idd[i] = 0; | ||
113 | break; | 115 | break; |
114 | 116 | ||
115 | case HIL_CMD_RSC: | 117 | case HIL_CMD_RSC: |
116 | for (i = 0; i < idx; i++) | 118 | buf = dev->rsc; |
117 | kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
118 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
119 | kbd->rsc[i] = 0; | ||
120 | break; | 119 | break; |
121 | 120 | ||
122 | case HIL_CMD_EXD: | 121 | case HIL_CMD_EXD: |
123 | for (i = 0; i < idx; i++) | 122 | buf = dev->exd; |
124 | kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
125 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
126 | kbd->exd[i] = 0; | ||
127 | break; | 123 | break; |
128 | 124 | ||
129 | case HIL_CMD_RNM: | 125 | case HIL_CMD_RNM: |
130 | for (i = 0; i < idx; i++) | 126 | dev->rnm[HIL_PACKET_MAX_LENGTH] = 0; |
131 | kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 127 | buf = dev->rnm; |
132 | for (; i < HIL_KBD_MAX_LENGTH + 1; i++) | ||
133 | kbd->rnm[i] = '\0'; | ||
134 | break; | 128 | break; |
135 | 129 | ||
136 | default: | 130 | default: |
137 | /* These occur when device isn't present */ | 131 | /* These occur when device isn't present */ |
138 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) | 132 | if (p != (HIL_ERR_INT | HIL_PKT_CMD)) { |
139 | break; | 133 | /* Anything else we'd like to know about. */ |
140 | /* Anything else we'd like to know about. */ | 134 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
141 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 135 | } |
142 | break; | 136 | goto out; |
143 | } | 137 | } |
144 | goto out; | ||
145 | 138 | ||
146 | report: | 139 | for (i = 0; i < idx; i++) |
147 | cnt = 1; | 140 | buf[i] = dev->data[i] & HIL_PKT_DATA_MASK; |
141 | for (; i < HIL_PACKET_MAX_LENGTH; i++) | ||
142 | buf[i] = 0; | ||
143 | out: | ||
144 | complete(&dev->cmd_done); | ||
145 | } | ||
146 | |||
147 | static void hil_dev_handle_kbd_events(struct hil_dev *kbd) | ||
148 | { | ||
149 | struct input_dev *dev = kbd->dev; | ||
150 | int idx = kbd->idx4 / 4; | ||
151 | int i; | ||
152 | |||
148 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { | 153 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { |
149 | case HIL_POL_CHARTYPE_NONE: | 154 | case HIL_POL_CHARTYPE_NONE: |
150 | break; | 155 | return; |
151 | 156 | ||
152 | case HIL_POL_CHARTYPE_ASCII: | 157 | case HIL_POL_CHARTYPE_ASCII: |
153 | while (cnt < idx - 1) | 158 | for (i = 1; i < idx - 1; i++) |
154 | input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); | 159 | input_report_key(dev, kbd->data[i] & 0x7f, 1); |
155 | break; | 160 | break; |
156 | 161 | ||
157 | case HIL_POL_CHARTYPE_RSVD1: | 162 | case HIL_POL_CHARTYPE_RSVD1: |
158 | case HIL_POL_CHARTYPE_RSVD2: | 163 | case HIL_POL_CHARTYPE_RSVD2: |
159 | case HIL_POL_CHARTYPE_BINARY: | 164 | case HIL_POL_CHARTYPE_BINARY: |
160 | while (cnt < idx - 1) | 165 | for (i = 1; i < idx - 1; i++) |
161 | input_report_key(dev, kbd->data[cnt++], 1); | 166 | input_report_key(dev, kbd->data[i], 1); |
162 | break; | 167 | break; |
163 | 168 | ||
164 | case HIL_POL_CHARTYPE_SET1: | 169 | case HIL_POL_CHARTYPE_SET1: |
165 | while (cnt < idx - 1) { | 170 | for (i = 1; i < idx - 1; i++) { |
166 | unsigned int key; | 171 | unsigned int key = kbd->data[i]; |
167 | int up; | 172 | int up = key & HIL_KBD_SET1_UPBIT; |
168 | key = kbd->data[cnt++]; | 173 | |
169 | up = key & HIL_KBD_SET1_UPBIT; | ||
170 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 174 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
171 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; | 175 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; |
172 | if (key != KEY_RESERVED) | 176 | input_report_key(dev, key, !up); |
173 | input_report_key(dev, key, !up); | ||
174 | } | 177 | } |
175 | break; | 178 | break; |
176 | 179 | ||
177 | case HIL_POL_CHARTYPE_SET2: | 180 | case HIL_POL_CHARTYPE_SET2: |
178 | while (cnt < idx - 1) { | 181 | for (i = 1; i < idx - 1; i++) { |
179 | unsigned int key; | 182 | unsigned int key = kbd->data[i]; |
180 | int up; | 183 | int up = key & HIL_KBD_SET2_UPBIT; |
181 | key = kbd->data[cnt++]; | 184 | |
182 | up = key & HIL_KBD_SET2_UPBIT; | ||
183 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 185 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
184 | key = key >> HIL_KBD_SET2_SHIFT; | 186 | key = key >> HIL_KBD_SET2_SHIFT; |
185 | if (key != KEY_RESERVED) | 187 | input_report_key(dev, key, !up); |
186 | input_report_key(dev, key, !up); | ||
187 | } | 188 | } |
188 | break; | 189 | break; |
189 | 190 | ||
190 | case HIL_POL_CHARTYPE_SET3: | 191 | case HIL_POL_CHARTYPE_SET3: |
191 | while (cnt < idx - 1) { | 192 | for (i = 1; i < idx - 1; i++) { |
192 | unsigned int key; | 193 | unsigned int key = kbd->data[i]; |
193 | int up; | 194 | int up = key & HIL_KBD_SET3_UPBIT; |
194 | key = kbd->data[cnt++]; | 195 | |
195 | up = key & HIL_KBD_SET3_UPBIT; | ||
196 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 196 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
197 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; | 197 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; |
198 | if (key != KEY_RESERVED) | 198 | input_report_key(dev, key, !up); |
199 | input_report_key(dev, key, !up); | ||
200 | } | 199 | } |
201 | break; | 200 | break; |
202 | } | 201 | } |
203 | out: | 202 | |
204 | kbd->idx4 = 0; | 203 | input_sync(dev); |
205 | up(&kbd->sem); | ||
206 | } | 204 | } |
207 | 205 | ||
208 | static void hil_kbd_process_err(struct hil_kbd *kbd) | 206 | static void hil_dev_handle_ptr_events(struct hil_dev *ptr) |
207 | { | ||
208 | struct input_dev *dev = ptr->dev; | ||
209 | int idx = ptr->idx4 / 4; | ||
210 | hil_packet p = ptr->data[idx - 1]; | ||
211 | int i, cnt, laxis; | ||
212 | bool absdev, ax16; | ||
213 | |||
214 | if ((p & HIL_CMDCT_POL) != idx - 1) { | ||
215 | printk(KERN_WARNING PREFIX | ||
216 | "Malformed poll packet %x (idx = %i)\n", p, idx); | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | i = (p & HIL_POL_AXIS_ALT) ? 3 : 0; | ||
221 | laxis = (p & HIL_POL_NUM_AXES_MASK) + i; | ||
222 | |||
223 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ | ||
224 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; | ||
225 | |||
226 | for (cnt = 1; i < laxis; i++) { | ||
227 | unsigned int lo, hi, val; | ||
228 | |||
229 | lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK; | ||
230 | hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0; | ||
231 | |||
232 | if (absdev) { | ||
233 | val = lo + (hi << 8); | ||
234 | #ifdef TABLET_AUTOADJUST | ||
235 | if (val < dev->absmin[ABS_X + i]) | ||
236 | dev->absmin[ABS_X + i] = val; | ||
237 | if (val > dev->absmax[ABS_X + i]) | ||
238 | dev->absmax[ABS_X + i] = val; | ||
239 | #endif | ||
240 | if (i%3) val = dev->absmax[ABS_X + i] - val; | ||
241 | input_report_abs(dev, ABS_X + i, val); | ||
242 | } else { | ||
243 | val = (int) (((int8_t)lo) | ((int8_t)hi << 8)); | ||
244 | if (i % 3) | ||
245 | val *= -1; | ||
246 | input_report_rel(dev, REL_X + i, val); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | while (cnt < idx - 1) { | ||
251 | unsigned int btn = ptr->data[cnt++]; | ||
252 | int up = btn & 1; | ||
253 | |||
254 | btn &= 0xfe; | ||
255 | if (btn == 0x8e) | ||
256 | continue; /* TODO: proximity == touch? */ | ||
257 | if (btn > 0x8c || btn < 0x80) | ||
258 | continue; | ||
259 | btn = (btn - 0x80) >> 1; | ||
260 | btn = ptr->btnmap[btn]; | ||
261 | input_report_key(dev, btn, !up); | ||
262 | } | ||
263 | |||
264 | input_sync(dev); | ||
265 | } | ||
266 | |||
267 | static void hil_dev_process_err(struct hil_dev *dev) | ||
209 | { | 268 | { |
210 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 269 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
211 | kbd->idx4 = 0; | 270 | dev->idx4 = 0; |
212 | up(&kbd->sem); | 271 | complete(&dev->cmd_done); /* just in case somebody is waiting */ |
213 | } | 272 | } |
214 | 273 | ||
215 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, | 274 | static irqreturn_t hil_dev_interrupt(struct serio *serio, |
216 | unsigned char data, unsigned int flags) | 275 | unsigned char data, unsigned int flags) |
217 | { | 276 | { |
218 | struct hil_kbd *kbd; | 277 | struct hil_dev *dev; |
219 | hil_packet packet; | 278 | hil_packet packet; |
220 | int idx; | 279 | int idx; |
221 | 280 | ||
222 | kbd = serio_get_drvdata(serio); | 281 | dev = serio_get_drvdata(serio); |
223 | BUG_ON(kbd == NULL); | 282 | BUG_ON(dev == NULL); |
224 | 283 | ||
225 | if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { | 284 | if (dev->idx4 >= HIL_PACKET_MAX_LENGTH * sizeof(hil_packet)) { |
226 | hil_kbd_process_err(kbd); | 285 | hil_dev_process_err(dev); |
227 | return IRQ_HANDLED; | 286 | goto out; |
228 | } | 287 | } |
229 | idx = kbd->idx4/4; | 288 | |
230 | if (!(kbd->idx4 % 4)) | 289 | idx = dev->idx4 / 4; |
231 | kbd->data[idx] = 0; | 290 | if (!(dev->idx4 % 4)) |
232 | packet = kbd->data[idx]; | 291 | dev->data[idx] = 0; |
233 | packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); | 292 | packet = dev->data[idx]; |
234 | kbd->data[idx] = packet; | 293 | packet |= ((hil_packet)data) << ((3 - (dev->idx4 % 4)) * 8); |
294 | dev->data[idx] = packet; | ||
235 | 295 | ||
236 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 296 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
237 | if ((++(kbd->idx4)) % 4) | 297 | if ((++dev->idx4 % 4) == 0) { |
238 | return IRQ_HANDLED; | 298 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
239 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 299 | hil_dev_process_err(dev); |
240 | hil_kbd_process_err(kbd); | 300 | } else if (packet & HIL_PKT_CMD) { |
241 | return IRQ_HANDLED; | 301 | if (hil_dev_is_command_response(packet)) |
302 | hil_dev_handle_command_response(dev); | ||
303 | else if (dev->is_pointer) | ||
304 | hil_dev_handle_ptr_events(dev); | ||
305 | else | ||
306 | hil_dev_handle_kbd_events(dev); | ||
307 | dev->idx4 = 0; | ||
308 | } | ||
242 | } | 309 | } |
243 | if (packet & HIL_PKT_CMD) | 310 | out: |
244 | hil_kbd_process_record(kbd); | ||
245 | return IRQ_HANDLED; | 311 | return IRQ_HANDLED; |
246 | } | 312 | } |
247 | 313 | ||
248 | static void hil_kbd_disconnect(struct serio *serio) | 314 | static void hil_dev_disconnect(struct serio *serio) |
249 | { | 315 | { |
250 | struct hil_kbd *kbd; | 316 | struct hil_dev *dev = serio_get_drvdata(serio); |
251 | 317 | ||
252 | kbd = serio_get_drvdata(serio); | 318 | BUG_ON(dev == NULL); |
253 | BUG_ON(kbd == NULL); | ||
254 | 319 | ||
255 | serio_close(serio); | 320 | serio_close(serio); |
256 | input_unregister_device(kbd->dev); | 321 | input_unregister_device(dev->dev); |
257 | kfree(kbd); | 322 | serio_set_drvdata(serio, NULL); |
323 | kfree(dev); | ||
324 | } | ||
325 | |||
326 | static void hil_dev_keyboard_setup(struct hil_dev *kbd) | ||
327 | { | ||
328 | struct input_dev *input_dev = kbd->dev; | ||
329 | uint8_t did = kbd->idd[0]; | ||
330 | int i; | ||
331 | |||
332 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
333 | input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | ||
334 | BIT_MASK(LED_SCROLLL); | ||
335 | |||
336 | for (i = 0; i < 128; i++) { | ||
337 | __set_bit(hil_kbd_set1[i], input_dev->keybit); | ||
338 | __set_bit(hil_kbd_set3[i], input_dev->keybit); | ||
339 | } | ||
340 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
341 | |||
342 | input_dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | ||
343 | input_dev->keycodesize = sizeof(hil_kbd_set1[0]); | ||
344 | input_dev->keycode = hil_kbd_set1; | ||
345 | |||
346 | input_dev->name = strlen(kbd->rnm) ? kbd->rnm : "HIL keyboard"; | ||
347 | input_dev->phys = "hpkbd/input0"; | ||
348 | |||
349 | printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n", | ||
350 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); | ||
258 | } | 351 | } |
259 | 352 | ||
260 | static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | 353 | static void hil_dev_pointer_setup(struct hil_dev *ptr) |
261 | { | 354 | { |
262 | struct hil_kbd *kbd; | 355 | struct input_dev *input_dev = ptr->dev; |
263 | uint8_t did, *idd; | 356 | uint8_t did = ptr->idd[0]; |
264 | int i; | 357 | uint8_t *idd = ptr->idd + 1; |
358 | unsigned int naxsets = HIL_IDD_NUM_AXSETS(*idd); | ||
359 | unsigned int i, btntype; | ||
360 | const char *txt; | ||
361 | |||
362 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); | ||
363 | |||
364 | switch (did & HIL_IDD_DID_TYPE_MASK) { | ||
365 | case HIL_IDD_DID_TYPE_REL: | ||
366 | input_dev->evbit[0] = BIT_MASK(EV_REL); | ||
265 | 367 | ||
266 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); | 368 | for (i = 0; i < ptr->naxes; i++) |
267 | if (!kbd) | 369 | __set_bit(REL_X + i, input_dev->relbit); |
268 | return -ENOMEM; | ||
269 | 370 | ||
270 | kbd->dev = input_allocate_device(); | 371 | for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++) |
271 | if (!kbd->dev) | 372 | __set_bit(REL_X + i, input_dev->relbit); |
373 | |||
374 | txt = "relative"; | ||
375 | break; | ||
376 | |||
377 | case HIL_IDD_DID_TYPE_ABS: | ||
378 | input_dev->evbit[0] = BIT_MASK(EV_ABS); | ||
379 | |||
380 | for (i = 0; i < ptr->naxes; i++) | ||
381 | input_set_abs_params(input_dev, ABS_X + i, | ||
382 | 0, HIL_IDD_AXIS_MAX(idd, i), 0, 0); | ||
383 | |||
384 | for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++) | ||
385 | input_set_abs_params(input_dev, ABS_X + i, | ||
386 | 0, HIL_IDD_AXIS_MAX(idd, i - 3), 0, 0); | ||
387 | |||
388 | #ifdef TABLET_AUTOADJUST | ||
389 | for (i = 0; i < ABS_MAX; i++) { | ||
390 | int diff = input_dev->absmax[ABS_X + i] / 10; | ||
391 | input_dev->absmin[ABS_X + i] += diff; | ||
392 | input_dev->absmax[ABS_X + i] -= diff; | ||
393 | } | ||
394 | #endif | ||
395 | |||
396 | txt = "absolute"; | ||
397 | break; | ||
398 | |||
399 | default: | ||
400 | BUG(); | ||
401 | } | ||
402 | |||
403 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | ||
404 | if (ptr->nbtn) | ||
405 | input_dev->evbit[0] |= BIT_MASK(EV_KEY); | ||
406 | |||
407 | btntype = BTN_MISC; | ||
408 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) | ||
409 | #ifdef TABLET_SIMULATES_MOUSE | ||
410 | btntype = BTN_TOUCH; | ||
411 | #else | ||
412 | btntype = BTN_DIGI; | ||
413 | #endif | ||
414 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) | ||
415 | btntype = BTN_TOUCH; | ||
416 | |||
417 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) | ||
418 | btntype = BTN_MOUSE; | ||
419 | |||
420 | for (i = 0; i < ptr->nbtn; i++) { | ||
421 | __set_bit(btntype | i, input_dev->keybit); | ||
422 | ptr->btnmap[i] = btntype | i; | ||
423 | } | ||
424 | |||
425 | if (btntype == BTN_MOUSE) { | ||
426 | /* Swap buttons 2 and 3 */ | ||
427 | ptr->btnmap[1] = BTN_MIDDLE; | ||
428 | ptr->btnmap[2] = BTN_RIGHT; | ||
429 | } | ||
430 | |||
431 | input_dev->name = strlen(ptr->rnm) ? ptr->rnm : "HIL pointer device"; | ||
432 | |||
433 | printk(KERN_INFO PREFIX | ||
434 | "HIL pointer device found (did: 0x%02x, axis: %s)\n", | ||
435 | did, txt); | ||
436 | printk(KERN_INFO PREFIX | ||
437 | "HIL pointer has %i buttons and %i sets of %i axes\n", | ||
438 | ptr->nbtn, naxsets, ptr->naxes); | ||
439 | } | ||
440 | |||
441 | static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) | ||
442 | { | ||
443 | struct hil_dev *dev; | ||
444 | struct input_dev *input_dev; | ||
445 | uint8_t did, *idd; | ||
446 | int error; | ||
447 | |||
448 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
449 | input_dev = input_allocate_device(); | ||
450 | if (!dev || !input_dev) { | ||
451 | error = -ENOMEM; | ||
272 | goto bail0; | 452 | goto bail0; |
453 | } | ||
273 | 454 | ||
274 | if (serio_open(serio, drv)) | 455 | dev->serio = serio; |
275 | goto bail1; | 456 | dev->dev = input_dev; |
276 | 457 | ||
277 | serio_set_drvdata(serio, kbd); | 458 | error = serio_open(serio, drv); |
278 | kbd->serio = serio; | 459 | if (error) |
460 | goto bail0; | ||
279 | 461 | ||
280 | init_MUTEX_LOCKED(&kbd->sem); | 462 | serio_set_drvdata(serio, dev); |
281 | 463 | ||
282 | /* Get device info. MLC driver supplies devid/status/etc. */ | 464 | /* Get device info. MLC driver supplies devid/status/etc. */ |
283 | serio->write(serio, 0); | 465 | init_completion(&dev->cmd_done); |
284 | serio->write(serio, 0); | 466 | serio_write(serio, 0); |
285 | serio->write(serio, HIL_PKT_CMD >> 8); | 467 | serio_write(serio, 0); |
286 | serio->write(serio, HIL_CMD_IDD); | 468 | serio_write(serio, HIL_PKT_CMD >> 8); |
287 | down(&kbd->sem); | 469 | serio_write(serio, HIL_CMD_IDD); |
288 | 470 | error = wait_for_completion_killable(&dev->cmd_done); | |
289 | serio->write(serio, 0); | 471 | if (error) |
290 | serio->write(serio, 0); | 472 | goto bail1; |
291 | serio->write(serio, HIL_PKT_CMD >> 8); | 473 | |
292 | serio->write(serio, HIL_CMD_RSC); | 474 | init_completion(&dev->cmd_done); |
293 | down(&kbd->sem); | 475 | serio_write(serio, 0); |
294 | 476 | serio_write(serio, 0); | |
295 | serio->write(serio, 0); | 477 | serio_write(serio, HIL_PKT_CMD >> 8); |
296 | serio->write(serio, 0); | 478 | serio_write(serio, HIL_CMD_RSC); |
297 | serio->write(serio, HIL_PKT_CMD >> 8); | 479 | error = wait_for_completion_killable(&dev->cmd_done); |
298 | serio->write(serio, HIL_CMD_RNM); | 480 | if (error) |
299 | down(&kbd->sem); | 481 | goto bail1; |
300 | 482 | ||
301 | serio->write(serio, 0); | 483 | init_completion(&dev->cmd_done); |
302 | serio->write(serio, 0); | 484 | serio_write(serio, 0); |
303 | serio->write(serio, HIL_PKT_CMD >> 8); | 485 | serio_write(serio, 0); |
304 | serio->write(serio, HIL_CMD_EXD); | 486 | serio_write(serio, HIL_PKT_CMD >> 8); |
305 | down(&kbd->sem); | 487 | serio_write(serio, HIL_CMD_RNM); |
306 | 488 | error = wait_for_completion_killable(&dev->cmd_done); | |
307 | up(&kbd->sem); | 489 | if (error) |
308 | 490 | goto bail1; | |
309 | did = kbd->idd[0]; | 491 | |
310 | idd = kbd->idd + 1; | 492 | init_completion(&dev->cmd_done); |
493 | serio_write(serio, 0); | ||
494 | serio_write(serio, 0); | ||
495 | serio_write(serio, HIL_PKT_CMD >> 8); | ||
496 | serio_write(serio, HIL_CMD_EXD); | ||
497 | error = wait_for_completion_killable(&dev->cmd_done); | ||
498 | if (error) | ||
499 | goto bail1; | ||
500 | |||
501 | did = dev->idd[0]; | ||
502 | idd = dev->idd + 1; | ||
503 | |||
311 | switch (did & HIL_IDD_DID_TYPE_MASK) { | 504 | switch (did & HIL_IDD_DID_TYPE_MASK) { |
312 | case HIL_IDD_DID_TYPE_KB_INTEGRAL: | 505 | case HIL_IDD_DID_TYPE_KB_INTEGRAL: |
313 | case HIL_IDD_DID_TYPE_KB_ITF: | 506 | case HIL_IDD_DID_TYPE_KB_ITF: |
314 | case HIL_IDD_DID_TYPE_KB_RSVD: | 507 | case HIL_IDD_DID_TYPE_KB_RSVD: |
315 | case HIL_IDD_DID_TYPE_CHAR: | 508 | case HIL_IDD_DID_TYPE_CHAR: |
316 | printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n", | 509 | if (HIL_IDD_NUM_BUTTONS(idd) || |
317 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); | 510 | HIL_IDD_NUM_AXES_PER_SET(*idd)) { |
318 | break; | 511 | printk(KERN_INFO PREFIX |
319 | default: | 512 | "combo devices are not supported.\n"); |
320 | goto bail2; | 513 | goto bail1; |
321 | } | 514 | } |
322 | 515 | ||
323 | if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { | 516 | dev->is_pointer = false; |
324 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); | 517 | hil_dev_keyboard_setup(dev); |
325 | goto bail2; | 518 | break; |
326 | } | ||
327 | 519 | ||
328 | kbd->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 520 | case HIL_IDD_DID_TYPE_REL: |
329 | kbd->dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | 521 | case HIL_IDD_DID_TYPE_ABS: |
330 | BIT_MASK(LED_SCROLLL); | 522 | dev->is_pointer = true; |
331 | kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 523 | hil_dev_pointer_setup(dev); |
332 | kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); | 524 | break; |
333 | kbd->dev->keycode = hil_kbd_set1; | ||
334 | kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; | ||
335 | kbd->dev->phys = "hpkbd/input0"; /* XXX */ | ||
336 | |||
337 | kbd->dev->id.bustype = BUS_HIL; | ||
338 | kbd->dev->id.vendor = PCI_VENDOR_ID_HP; | ||
339 | kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ | ||
340 | kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | ||
341 | kbd->dev->dev.parent = &serio->dev; | ||
342 | 525 | ||
343 | for (i = 0; i < 128; i++) { | 526 | default: |
344 | set_bit(hil_kbd_set1[i], kbd->dev->keybit); | 527 | goto bail1; |
345 | set_bit(hil_kbd_set3[i], kbd->dev->keybit); | ||
346 | } | 528 | } |
347 | clear_bit(0, kbd->dev->keybit); | ||
348 | 529 | ||
349 | input_register_device(kbd->dev); | 530 | input_dev->id.bustype = BUS_HIL; |
350 | printk(KERN_INFO "input: %s, ID: %d\n", | 531 | input_dev->id.vendor = PCI_VENDOR_ID_HP; |
351 | kbd->dev->name, did); | 532 | input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ |
533 | input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | ||
534 | input_dev->dev.parent = &serio->dev; | ||
535 | |||
536 | if (!dev->is_pointer) { | ||
537 | serio_write(serio, 0); | ||
538 | serio_write(serio, 0); | ||
539 | serio_write(serio, HIL_PKT_CMD >> 8); | ||
540 | /* Enable Keyswitch Autorepeat 1 */ | ||
541 | serio_write(serio, HIL_CMD_EK1); | ||
542 | /* No need to wait for completion */ | ||
543 | } | ||
352 | 544 | ||
353 | serio->write(serio, 0); | 545 | error = input_register_device(input_dev); |
354 | serio->write(serio, 0); | 546 | if (error) |
355 | serio->write(serio, HIL_PKT_CMD >> 8); | 547 | goto bail1; |
356 | serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ | ||
357 | down(&kbd->sem); | ||
358 | up(&kbd->sem); | ||
359 | 548 | ||
360 | return 0; | 549 | return 0; |
361 | bail2: | 550 | |
551 | bail1: | ||
362 | serio_close(serio); | 552 | serio_close(serio); |
363 | serio_set_drvdata(serio, NULL); | 553 | serio_set_drvdata(serio, NULL); |
364 | bail1: | ||
365 | input_free_device(kbd->dev); | ||
366 | bail0: | 554 | bail0: |
367 | kfree(kbd); | 555 | input_free_device(input_dev); |
368 | return -EIO; | 556 | kfree(dev); |
557 | return error; | ||
369 | } | 558 | } |
370 | 559 | ||
371 | static struct serio_device_id hil_kbd_ids[] = { | 560 | static struct serio_device_id hil_dev_ids[] = { |
372 | { | 561 | { |
373 | .type = SERIO_HIL_MLC, | 562 | .type = SERIO_HIL_MLC, |
374 | .proto = SERIO_HIL, | 563 | .proto = SERIO_HIL, |
@@ -378,26 +567,26 @@ static struct serio_device_id hil_kbd_ids[] = { | |||
378 | { 0 } | 567 | { 0 } |
379 | }; | 568 | }; |
380 | 569 | ||
381 | static struct serio_driver hil_kbd_serio_drv = { | 570 | static struct serio_driver hil_serio_drv = { |
382 | .driver = { | 571 | .driver = { |
383 | .name = "hil_kbd", | 572 | .name = "hil_dev", |
384 | }, | 573 | }, |
385 | .description = "HP HIL keyboard driver", | 574 | .description = "HP HIL keyboard/mouse/tablet driver", |
386 | .id_table = hil_kbd_ids, | 575 | .id_table = hil_dev_ids, |
387 | .connect = hil_kbd_connect, | 576 | .connect = hil_dev_connect, |
388 | .disconnect = hil_kbd_disconnect, | 577 | .disconnect = hil_dev_disconnect, |
389 | .interrupt = hil_kbd_interrupt | 578 | .interrupt = hil_dev_interrupt |
390 | }; | 579 | }; |
391 | 580 | ||
392 | static int __init hil_kbd_init(void) | 581 | static int __init hil_dev_init(void) |
393 | { | 582 | { |
394 | return serio_register_driver(&hil_kbd_serio_drv); | 583 | return serio_register_driver(&hil_serio_drv); |
395 | } | 584 | } |
396 | 585 | ||
397 | static void __exit hil_kbd_exit(void) | 586 | static void __exit hil_dev_exit(void) |
398 | { | 587 | { |
399 | serio_unregister_driver(&hil_kbd_serio_drv); | 588 | serio_unregister_driver(&hil_serio_drv); |
400 | } | 589 | } |
401 | 590 | ||
402 | module_init(hil_kbd_init); | 591 | module_init(hil_dev_init); |
403 | module_exit(hil_kbd_exit); | 592 | module_exit(hil_dev_exit); |