aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruno Prémont <bonbons@linux-vserver.org>2010-03-30 16:33:50 -0400
committerJiri Kosina <jkosina@suse.cz>2010-03-31 05:20:59 -0400
commit236db47c2b3b69464d50c695ab2ddd516cf64520 (patch)
tree599125d28f2f0a23be2da9dc59d783fc404b65b0 /drivers
parent39710479303fd3affb3e204e9a7a75cc676977b5 (diff)
HID: new driver for PicoLCD device
Add basic driver for PicoLCD graphics device. Initially support keypad with input device and provide support for debugging communication via events file from debugfs. Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig18
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hid-picolcd.c1183
5 files changed, 1206 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 71d4c0703629..138ba6a277ee 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -262,6 +262,24 @@ config HID_PETALYNX
262 ---help--- 262 ---help---
263 Support for Petalynx Maxter remote control. 263 Support for Petalynx Maxter remote control.
264 264
265config HID_PICOLCD
266 tristate "PicoLCD (graphic version)"
267 depends on USB_HID
268 ---help---
269 This provides support for Minibox PicoLCD devices, currently
270 only the graphical ones are supported.
271
272 This includes support for the following device features:
273 - Keypad
274 - Switching between Firmware and Flash mode
275 Features that are not (yet) supported:
276 - Framebuffer for monochrome 256x64 display
277 - Backlight control
278 - Contrast control
279 - IR
280 - General purpose outputs
281 - EEProm / Flash access
282
265config HID_QUANTA 283config HID_QUANTA
266 tristate "Quanta Optical Touch" 284 tristate "Quanta Optical Touch"
267 depends on USB_HID 285 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 0b2618f092ca..7fd1614e7e2c 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
44obj-$(CONFIG_HID_QUANTA) += hid-quanta.o 44obj-$(CONFIG_HID_QUANTA) += hid-quanta.o
45obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 45obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
46obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 46obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
47obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
47obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 48obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
48obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 49obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
49obj-$(CONFIG_HID_SONY) += hid-sony.o 50obj-$(CONFIG_HID_SONY) += hid-sony.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 2e2aa759d230..bb11fb460d55 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1335,6 +1335,8 @@ static const struct hid_device_id hid_blacklist[] = {
1335 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1335 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1336 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, 1336 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1337 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, 1337 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
1338 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
1339 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
1338 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, 1340 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
1339 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, 1341 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
1340 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, 1342 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 797e06470356..783b41d8592e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -341,6 +341,8 @@
341#define USB_VENDOR_ID_MICROCHIP 0x04d8 341#define USB_VENDOR_ID_MICROCHIP 0x04d8
342#define USB_DEVICE_ID_PICKIT1 0x0032 342#define USB_DEVICE_ID_PICKIT1 0x0032
343#define USB_DEVICE_ID_PICKIT2 0x0033 343#define USB_DEVICE_ID_PICKIT2 0x0033
344#define USB_DEVICE_ID_PICOLCD 0xc002
345#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002
344 346
345#define USB_VENDOR_ID_MICROSOFT 0x045e 347#define USB_VENDOR_ID_MICROSOFT 0x045e
346#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b 348#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
new file mode 100644
index 000000000000..c7855f388898
--- /dev/null
+++ b/drivers/hid/hid-picolcd.c
@@ -0,0 +1,1183 @@
1/***************************************************************************
2 * Copyright (C) 2010 by Bruno Prémont <bonbons@linux-vserver.org> *
3 * *
4 * Based on Logitech G13 driver (v0.4) *
5 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, version 2 of the License. *
10 * *
11 * This driver is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this software. If not see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
19
20#include <linux/hid.h>
21#include <linux/hid-debug.h>
22#include <linux/input.h>
23#include "hid-ids.h"
24#include "usbhid/usbhid.h"
25#include <linux/usb.h>
26
27#include <linux/seq_file.h>
28#include <linux/debugfs.h>
29
30#include <linux/completion.h>
31
32#define PICOLCD_NAME "PicoLCD (graphic)"
33
34/* Report numbers */
35#define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */
36#define ERR_SUCCESS 0x00
37#define ERR_PARAMETER_MISSING 0x01
38#define ERR_DATA_MISSING 0x02
39#define ERR_BLOCK_READ_ONLY 0x03
40#define ERR_BLOCK_NOT_ERASABLE 0x04
41#define ERR_BLOCK_TOO_BIG 0x05
42#define ERR_SECTION_OVERFLOW 0x06
43#define ERR_INVALID_CMD_LEN 0x07
44#define ERR_INVALID_DATA_LEN 0x08
45#define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */
46#define REPORT_IR_DATA 0x21 /* LCD: IN[63] */
47#define REPORT_EE_DATA 0x32 /* LCD: IN[63] */
48#define REPORT_MEMORY 0x41 /* LCD: IN[63] */
49#define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */
50#define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */
51#define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */
52#define REPORT_RESET 0x93 /* LCD: OUT[2] */
53#define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */
54#define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */
55#define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */
56#define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */
57#define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */
58#define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */
59#define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */
60#define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */
61#define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */
62#define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */
63#define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */
64#define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */
65#define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */
66#define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */
67#define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */
68#define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */
69#define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */
70#define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */
71
72/* Input device
73 *
74 * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
75 * and header for 4x4 key matrix. The built-in keys are part of the matrix.
76 */
77static const unsigned short def_keymap[] = {
78 KEY_RESERVED, /* none */
79 KEY_BACK, /* col 4 + row 1 */
80 KEY_HOMEPAGE, /* col 3 + row 1 */
81 KEY_RESERVED, /* col 2 + row 1 */
82 KEY_RESERVED, /* col 1 + row 1 */
83 KEY_SCROLLUP, /* col 4 + row 2 */
84 KEY_OK, /* col 3 + row 2 */
85 KEY_SCROLLDOWN, /* col 2 + row 2 */
86 KEY_RESERVED, /* col 1 + row 2 */
87 KEY_RESERVED, /* col 4 + row 3 */
88 KEY_RESERVED, /* col 3 + row 3 */
89 KEY_RESERVED, /* col 2 + row 3 */
90 KEY_RESERVED, /* col 1 + row 3 */
91 KEY_RESERVED, /* col 4 + row 4 */
92 KEY_RESERVED, /* col 3 + row 4 */
93 KEY_RESERVED, /* col 2 + row 4 */
94 KEY_RESERVED, /* col 1 + row 4 */
95};
96#define PICOLCD_KEYS ARRAY_SIZE(def_keymap)
97
98/* Description of in-progress IO operation, used for operations
99 * that trigger response from device */
100struct picolcd_pending {
101 struct hid_report *out_report;
102 struct hid_report *in_report;
103 struct completion ready;
104 int raw_size;
105 u8 raw_data[64];
106};
107
108/* Per device data structure */
109struct picolcd_data {
110 struct hid_device *hdev;
111#ifdef CONFIG_DEBUG_FS
112 int addr_sz;
113#endif
114 u8 version[2];
115 /* input stuff */
116 u8 pressed_keys[2];
117 struct input_dev *input_keys;
118 struct input_dev *input_cir;
119 unsigned short keycode[PICOLCD_KEYS];
120
121 /* Housekeeping stuff */
122 spinlock_t lock;
123 struct mutex mutex;
124 struct picolcd_pending *pending;
125 int status;
126#define PICOLCD_BOOTLOADER 1
127#define PICOLCD_FAILED 2
128};
129
130
131/* Find a given report */
132#define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
133#define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
134
135static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir)
136{
137 struct list_head *feature_report_list = &hdev->report_enum[dir].report_list;
138 struct hid_report *report = NULL;
139
140 list_for_each_entry(report, feature_report_list, list) {
141 if (report->id == id)
142 return report;
143 }
144 dev_warn(&hdev->dev, "No report with id 0x%x found\n", id);
145 return NULL;
146}
147
148#ifdef CONFIG_DEBUG_FS
149static void picolcd_debug_out_report(struct picolcd_data *data,
150 struct hid_device *hdev, struct hid_report *report);
151#define usbhid_submit_report(a, b, c) \
152 do { \
153 picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
154 usbhid_submit_report(a, b, c); \
155 } while (0)
156#endif
157
158/* Submit a report and wait for a reply from device - if device fades away
159 * or does not respond in time, return NULL */
160static struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
161 int report_id, const u8 *raw_data, int size)
162{
163 struct picolcd_data *data = hid_get_drvdata(hdev);
164 struct picolcd_pending *work;
165 struct hid_report *report = picolcd_out_report(report_id, hdev);
166 unsigned long flags;
167 int i, j, k;
168
169 if (!report || !data)
170 return NULL;
171 if (data->status & PICOLCD_FAILED)
172 return NULL;
173 work = kzalloc(sizeof(*work), GFP_KERNEL);
174 if (!work)
175 return NULL;
176
177 init_completion(&work->ready);
178 work->out_report = report;
179 work->in_report = NULL;
180 work->raw_size = 0;
181
182 mutex_lock(&data->mutex);
183 spin_lock_irqsave(&data->lock, flags);
184 for (i = k = 0; i < report->maxfield; i++)
185 for (j = 0; j < report->field[i]->report_count; j++) {
186 hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0);
187 k++;
188 }
189 data->pending = work;
190 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
191 spin_unlock_irqrestore(&data->lock, flags);
192 wait_for_completion_interruptible_timeout(&work->ready, HZ*2);
193 spin_lock_irqsave(&data->lock, flags);
194 data->pending = NULL;
195 spin_unlock_irqrestore(&data->lock, flags);
196 mutex_unlock(&data->mutex);
197 return work;
198}
199
200/*
201 * input class device
202 */
203static int picolcd_raw_keypad(struct picolcd_data *data,
204 struct hid_report *report, u8 *raw_data, int size)
205{
206 /*
207 * Keypad event
208 * First and second data bytes list currently pressed keys,
209 * 0x00 means no key and at most 2 keys may be pressed at same time
210 */
211 int i, j;
212
213 /* determine newly pressed keys */
214 for (i = 0; i < size; i++) {
215 unsigned int key_code;
216 if (raw_data[i] == 0)
217 continue;
218 for (j = 0; j < sizeof(data->pressed_keys); j++)
219 if (data->pressed_keys[j] == raw_data[i])
220 goto key_already_down;
221 for (j = 0; j < sizeof(data->pressed_keys); j++)
222 if (data->pressed_keys[j] == 0) {
223 data->pressed_keys[j] = raw_data[i];
224 break;
225 }
226 input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]);
227 if (raw_data[i] < PICOLCD_KEYS)
228 key_code = data->keycode[raw_data[i]];
229 else
230 key_code = KEY_UNKNOWN;
231 if (key_code != KEY_UNKNOWN) {
232 dbg_hid(PICOLCD_NAME " got key press for %u:%d",
233 raw_data[i], key_code);
234 input_report_key(data->input_keys, key_code, 1);
235 }
236 input_sync(data->input_keys);
237key_already_down:
238 continue;
239 }
240
241 /* determine newly released keys */
242 for (j = 0; j < sizeof(data->pressed_keys); j++) {
243 unsigned int key_code;
244 if (data->pressed_keys[j] == 0)
245 continue;
246 for (i = 0; i < size; i++)
247 if (data->pressed_keys[j] == raw_data[i])
248 goto key_still_down;
249 input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]);
250 if (data->pressed_keys[j] < PICOLCD_KEYS)
251 key_code = data->keycode[data->pressed_keys[j]];
252 else
253 key_code = KEY_UNKNOWN;
254 if (key_code != KEY_UNKNOWN) {
255 dbg_hid(PICOLCD_NAME " got key release for %u:%d",
256 data->pressed_keys[j], key_code);
257 input_report_key(data->input_keys, key_code, 0);
258 }
259 input_sync(data->input_keys);
260 data->pressed_keys[j] = 0;
261key_still_down:
262 continue;
263 }
264 return 1;
265}
266
267static int picolcd_raw_cir(struct picolcd_data *data,
268 struct hid_report *report, u8 *raw_data, int size)
269{
270 /* Need understanding of CIR data format to implement ... */
271 return 1;
272}
273
274static int picolcd_check_version(struct hid_device *hdev)
275{
276 struct picolcd_data *data = hid_get_drvdata(hdev);
277 struct picolcd_pending *verinfo;
278 int ret = 0;
279
280 if (!data)
281 return -ENODEV;
282
283 verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
284 if (!verinfo) {
285 dev_err(&hdev->dev, "no version response from PicoLCD");
286 return -ENODEV;
287 }
288
289 if (verinfo->raw_size == 2) {
290 if (data->status & PICOLCD_BOOTLOADER) {
291 dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n",
292 verinfo->raw_data[0], verinfo->raw_data[1]);
293 data->version[0] = verinfo->raw_data[0];
294 data->version[1] = verinfo->raw_data[1];
295 } else {
296 dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n",
297 verinfo->raw_data[1], verinfo->raw_data[0]);
298 data->version[0] = verinfo->raw_data[1];
299 data->version[1] = verinfo->raw_data[0];
300 }
301 } else {
302 dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n");
303 ret = -EINVAL;
304 }
305 kfree(verinfo);
306 return ret;
307}
308
309/*
310 * Reset our device and wait for answer to VERSION request
311 */
312static int picolcd_reset(struct hid_device *hdev)
313{
314 struct picolcd_data *data = hid_get_drvdata(hdev);
315 struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev);
316 unsigned long flags;
317
318 if (!data || !report || report->maxfield != 1)
319 return -ENODEV;
320
321 spin_lock_irqsave(&data->lock, flags);
322 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
323 data->status |= PICOLCD_BOOTLOADER;
324
325 /* perform the reset */
326 hid_set_field(report->field[0], 0, 1);
327 usbhid_submit_report(hdev, report, USB_DIR_OUT);
328 spin_unlock_irqrestore(&data->lock, flags);
329
330 return picolcd_check_version(hdev);
331}
332
333/*
334 * The "operation_mode" sysfs attribute
335 */
336static ssize_t picolcd_operation_mode_show(struct device *dev,
337 struct device_attribute *attr, char *buf)
338{
339 struct picolcd_data *data = dev_get_drvdata(dev);
340
341 if (data->status & PICOLCD_BOOTLOADER)
342 return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n");
343 else
344 return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n");
345}
346
347static ssize_t picolcd_operation_mode_store(struct device *dev,
348 struct device_attribute *attr, const char *buf, size_t count)
349{
350 struct picolcd_data *data = dev_get_drvdata(dev);
351 struct hid_report *report = NULL;
352 size_t cnt = count;
353 int timeout = 5000;
354 unsigned u;
355 unsigned long flags;
356
357 if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) {
358 if (data->status & PICOLCD_BOOTLOADER)
359 report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev);
360 buf += 3;
361 cnt -= 3;
362 } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) {
363 if (!(data->status & PICOLCD_BOOTLOADER))
364 report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev);
365 buf += 10;
366 cnt -= 10;
367 }
368 if (!report)
369 return -EINVAL;
370
371 while (cnt > 0 && (*buf == ' ' || *buf == '\t')) {
372 buf++;
373 cnt--;
374 }
375 while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
376 cnt--;
377 if (cnt > 0) {
378 if (sscanf(buf, "%u", &u) != 1)
379 return -EINVAL;
380 if (u > 30000)
381 return -EINVAL;
382 else
383 timeout = u;
384 }
385
386 spin_lock_irqsave(&data->lock, flags);
387 hid_set_field(report->field[0], 0, timeout & 0xff);
388 hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff);
389 usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
390 spin_unlock_irqrestore(&data->lock, flags);
391 return count;
392}
393
394static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show,
395 picolcd_operation_mode_store);
396
397
398#ifdef CONFIG_DEBUG_FS
399/*
400 * Helper code for HID report level dumping/debugging
401 */
402static const char *error_codes[] = {
403 "success", "parameter missing", "data_missing", "block readonly",
404 "block not erasable", "block too big", "section overflow",
405 "invalid command length", "invalid data length",
406};
407
408static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
409 const size_t data_len)
410{
411 int i, j;
412 for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) {
413 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
414 dst[j++] = hex_asc[data[i] & 0x0f];
415 dst[j++] = ' ';
416 }
417 if (j < dst_sz) {
418 dst[j--] = '\0';
419 dst[j] = '\n';
420 } else
421 dst[j] = '\0';
422}
423
424static void picolcd_debug_out_report(struct picolcd_data *data,
425 struct hid_device *hdev, struct hid_report *report)
426{
427 u8 raw_data[70];
428 int raw_size = (report->size >> 3) + 1;
429 char *buff;
430#define BUFF_SZ 256
431
432 /* Avoid unnecessary overhead if debugfs is disabled */
433 if (!hdev->debug_events)
434 return;
435
436 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
437 if (!buff)
438 return;
439
440 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
441 report->id, raw_size);
442 hid_debug_event(hdev, buff);
443 if (raw_size + 5 > sizeof(raw_data)) {
444 hid_debug_event(hdev, " TOO BIG\n");
445 return;
446 } else {
447 raw_data[0] = report->id;
448 hid_output_report(report, raw_data);
449 dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
450 hid_debug_event(hdev, buff);
451 }
452
453 switch (report->id) {
454 case REPORT_LED_STATE:
455 /* 1 data byte with GPO state */
456 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
457 "REPORT_LED_STATE", report->id, raw_size-1);
458 hid_debug_event(hdev, buff);
459 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
460 hid_debug_event(hdev, buff);
461 break;
462 case REPORT_BRIGHTNESS:
463 /* 1 data byte with brightness */
464 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
465 "REPORT_BRIGHTNESS", report->id, raw_size-1);
466 hid_debug_event(hdev, buff);
467 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
468 hid_debug_event(hdev, buff);
469 break;
470 case REPORT_CONTRAST:
471 /* 1 data byte with contrast */
472 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
473 "REPORT_CONTRAST", report->id, raw_size-1);
474 hid_debug_event(hdev, buff);
475 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
476 hid_debug_event(hdev, buff);
477 break;
478 case REPORT_RESET:
479 /* 2 data bytes with reset duration in ms */
480 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
481 "REPORT_RESET", report->id, raw_size-1);
482 hid_debug_event(hdev, buff);
483 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
484 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
485 hid_debug_event(hdev, buff);
486 break;
487 case REPORT_LCD_CMD:
488 /* 63 data bytes with LCD commands */
489 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
490 "REPORT_LCD_CMD", report->id, raw_size-1);
491 hid_debug_event(hdev, buff);
492 /* TODO: format decoding */
493 break;
494 case REPORT_LCD_DATA:
495 /* 63 data bytes with LCD data */
496 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
497 "REPORT_LCD_CMD", report->id, raw_size-1);
498 /* TODO: format decoding */
499 hid_debug_event(hdev, buff);
500 break;
501 case REPORT_LCD_CMD_DATA:
502 /* 63 data bytes with LCD commands and data */
503 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
504 "REPORT_LCD_CMD", report->id, raw_size-1);
505 /* TODO: format decoding */
506 hid_debug_event(hdev, buff);
507 break;
508 case REPORT_EE_READ:
509 /* 3 data bytes with read area description */
510 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
511 "REPORT_EE_READ", report->id, raw_size-1);
512 hid_debug_event(hdev, buff);
513 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
514 raw_data[2], raw_data[1]);
515 hid_debug_event(hdev, buff);
516 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
517 hid_debug_event(hdev, buff);
518 break;
519 case REPORT_EE_WRITE:
520 /* 3+1..20 data bytes with write area description */
521 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
522 "REPORT_EE_WRITE", report->id, raw_size-1);
523 hid_debug_event(hdev, buff);
524 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
525 raw_data[2], raw_data[1]);
526 hid_debug_event(hdev, buff);
527 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
528 hid_debug_event(hdev, buff);
529 if (raw_data[3] == 0) {
530 snprintf(buff, BUFF_SZ, "\tNo data\n");
531 } else if (raw_data[3] + 4 <= raw_size) {
532 snprintf(buff, BUFF_SZ, "\tData: ");
533 hid_debug_event(hdev, buff);
534 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
535 } else {
536 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
537 }
538 hid_debug_event(hdev, buff);
539 break;
540 case REPORT_ERASE_MEMORY:
541 case REPORT_BL_ERASE_MEMORY:
542 /* 3 data bytes with pointer inside erase block */
543 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
544 "REPORT_ERASE_MEMORY", report->id, raw_size-1);
545 hid_debug_event(hdev, buff);
546 switch (data->addr_sz) {
547 case 2:
548 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
549 raw_data[2], raw_data[1]);
550 break;
551 case 3:
552 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
553 raw_data[3], raw_data[2], raw_data[1]);
554 break;
555 default:
556 snprintf(buff, BUFF_SZ, "\tNot supported\n");
557 }
558 hid_debug_event(hdev, buff);
559 break;
560 case REPORT_READ_MEMORY:
561 case REPORT_BL_READ_MEMORY:
562 /* 4 data bytes with read area description */
563 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
564 "REPORT_READ_MEMORY", report->id, raw_size-1);
565 hid_debug_event(hdev, buff);
566 switch (data->addr_sz) {
567 case 2:
568 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
569 raw_data[2], raw_data[1]);
570 hid_debug_event(hdev, buff);
571 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
572 break;
573 case 3:
574 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
575 raw_data[3], raw_data[2], raw_data[1]);
576 hid_debug_event(hdev, buff);
577 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
578 break;
579 default:
580 snprintf(buff, BUFF_SZ, "\tNot supported\n");
581 }
582 hid_debug_event(hdev, buff);
583 break;
584 case REPORT_WRITE_MEMORY:
585 case REPORT_BL_WRITE_MEMORY:
586 /* 4+1..32 data bytes with write adrea description */
587 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
588 "REPORT_WRITE_MEMORY", report->id, raw_size-1);
589 hid_debug_event(hdev, buff);
590 switch (data->addr_sz) {
591 case 2:
592 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
593 raw_data[2], raw_data[1]);
594 hid_debug_event(hdev, buff);
595 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
596 hid_debug_event(hdev, buff);
597 if (raw_data[3] == 0) {
598 snprintf(buff, BUFF_SZ, "\tNo data\n");
599 } else if (raw_data[3] + 4 <= raw_size) {
600 snprintf(buff, BUFF_SZ, "\tData: ");
601 hid_debug_event(hdev, buff);
602 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
603 } else {
604 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
605 }
606 break;
607 case 3:
608 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
609 raw_data[3], raw_data[2], raw_data[1]);
610 hid_debug_event(hdev, buff);
611 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
612 hid_debug_event(hdev, buff);
613 if (raw_data[4] == 0) {
614 snprintf(buff, BUFF_SZ, "\tNo data\n");
615 } else if (raw_data[4] + 5 <= raw_size) {
616 snprintf(buff, BUFF_SZ, "\tData: ");
617 hid_debug_event(hdev, buff);
618 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
619 } else {
620 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
621 }
622 break;
623 default:
624 snprintf(buff, BUFF_SZ, "\tNot supported\n");
625 }
626 hid_debug_event(hdev, buff);
627 break;
628 case REPORT_SPLASH_RESTART:
629 /* TODO */
630 break;
631 case REPORT_EXIT_KEYBOARD:
632 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
633 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
634 hid_debug_event(hdev, buff);
635 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
636 raw_data[1] | (raw_data[2] << 8),
637 raw_data[2], raw_data[1]);
638 hid_debug_event(hdev, buff);
639 break;
640 case REPORT_VERSION:
641 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
642 "REPORT_VERSION", report->id, raw_size-1);
643 hid_debug_event(hdev, buff);
644 break;
645 case REPORT_DEVID:
646 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
647 "REPORT_DEVID", report->id, raw_size-1);
648 hid_debug_event(hdev, buff);
649 break;
650 case REPORT_SPLASH_SIZE:
651 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
652 "REPORT_SPLASH_SIZE", report->id, raw_size-1);
653 hid_debug_event(hdev, buff);
654 break;
655 case REPORT_HOOK_VERSION:
656 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
657 "REPORT_HOOK_VERSION", report->id, raw_size-1);
658 hid_debug_event(hdev, buff);
659 break;
660 case REPORT_EXIT_FLASHER:
661 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
662 "REPORT_VERSION", report->id, raw_size-1);
663 hid_debug_event(hdev, buff);
664 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
665 raw_data[1] | (raw_data[2] << 8),
666 raw_data[2], raw_data[1]);
667 hid_debug_event(hdev, buff);
668 break;
669 default:
670 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
671 "<unknown>", report->id, raw_size-1);
672 hid_debug_event(hdev, buff);
673 break;
674 }
675 wake_up_interruptible(&hdev->debug_wait);
676 kfree(buff);
677}
678
679static void picolcd_debug_raw_event(struct picolcd_data *data,
680 struct hid_device *hdev, struct hid_report *report,
681 u8 *raw_data, int size)
682{
683 char *buff;
684
685#define BUFF_SZ 256
686 /* Avoid unnecessary overhead if debugfs is disabled */
687 if (!hdev->debug_events)
688 return;
689
690 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
691 if (!buff)
692 return;
693
694 switch (report->id) {
695 case REPORT_ERROR_CODE:
696 /* 2 data bytes with affected report and error code */
697 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
698 "REPORT_ERROR_CODE", report->id, size-1);
699 hid_debug_event(hdev, buff);
700 if (raw_data[2] < ARRAY_SIZE(error_codes))
701 snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
702 raw_data[2], error_codes[raw_data[2]], raw_data[1]);
703 else
704 snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
705 raw_data[2], raw_data[1]);
706 hid_debug_event(hdev, buff);
707 break;
708 case REPORT_KEY_STATE:
709 /* 2 data bytes with key state */
710 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
711 "REPORT_KEY_STATE", report->id, size-1);
712 hid_debug_event(hdev, buff);
713 if (raw_data[1] == 0)
714 snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
715 else if (raw_data[2] == 0)
716 snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
717 raw_data[1], raw_data[1]);
718 else
719 snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
720 raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
721 hid_debug_event(hdev, buff);
722 break;
723 case REPORT_IR_DATA:
724 /* Up to 20 byes of IR scancode data */
725 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
726 "REPORT_IR_DATA", report->id, size-1);
727 hid_debug_event(hdev, buff);
728 if (raw_data[1] == 0) {
729 snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
730 hid_debug_event(hdev, buff);
731 } else if (raw_data[1] + 1 <= size) {
732 snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
733 raw_data[1]-1);
734 hid_debug_event(hdev, buff);
735 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-1);
736 hid_debug_event(hdev, buff);
737 } else {
738 snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
739 raw_data[1]-1);
740 hid_debug_event(hdev, buff);
741 }
742 break;
743 case REPORT_EE_DATA:
744 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
745 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
746 "REPORT_EE_DATA", report->id, size-1);
747 hid_debug_event(hdev, buff);
748 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
749 raw_data[2], raw_data[1]);
750 hid_debug_event(hdev, buff);
751 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
752 hid_debug_event(hdev, buff);
753 if (raw_data[3] == 0) {
754 snprintf(buff, BUFF_SZ, "\tNo data\n");
755 hid_debug_event(hdev, buff);
756 } else if (raw_data[3] + 4 <= size) {
757 snprintf(buff, BUFF_SZ, "\tData: ");
758 hid_debug_event(hdev, buff);
759 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
760 hid_debug_event(hdev, buff);
761 } else {
762 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
763 hid_debug_event(hdev, buff);
764 }
765 break;
766 case REPORT_MEMORY:
767 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
768 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
769 "REPORT_MEMORY", report->id, size-1);
770 hid_debug_event(hdev, buff);
771 switch (data->addr_sz) {
772 case 2:
773 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
774 raw_data[2], raw_data[1]);
775 hid_debug_event(hdev, buff);
776 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
777 hid_debug_event(hdev, buff);
778 if (raw_data[3] == 0) {
779 snprintf(buff, BUFF_SZ, "\tNo data\n");
780 } else if (raw_data[3] + 4 <= size) {
781 snprintf(buff, BUFF_SZ, "\tData: ");
782 hid_debug_event(hdev, buff);
783 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
784 } else {
785 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
786 }
787 break;
788 case 3:
789 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
790 raw_data[3], raw_data[2], raw_data[1]);
791 hid_debug_event(hdev, buff);
792 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
793 hid_debug_event(hdev, buff);
794 if (raw_data[4] == 0) {
795 snprintf(buff, BUFF_SZ, "\tNo data\n");
796 } else if (raw_data[4] + 5 <= size) {
797 snprintf(buff, BUFF_SZ, "\tData: ");
798 hid_debug_event(hdev, buff);
799 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
800 } else {
801 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
802 }
803 break;
804 default:
805 snprintf(buff, BUFF_SZ, "\tNot supported\n");
806 }
807 hid_debug_event(hdev, buff);
808 break;
809 case REPORT_VERSION:
810 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
811 "REPORT_VERSION", report->id, size-1);
812 hid_debug_event(hdev, buff);
813 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
814 raw_data[2], raw_data[1]);
815 hid_debug_event(hdev, buff);
816 break;
817 case REPORT_BL_ERASE_MEMORY:
818 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
819 "REPORT_BL_ERASE_MEMORY", report->id, size-1);
820 hid_debug_event(hdev, buff);
821 /* TODO */
822 break;
823 case REPORT_BL_READ_MEMORY:
824 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
825 "REPORT_BL_READ_MEMORY", report->id, size-1);
826 hid_debug_event(hdev, buff);
827 /* TODO */
828 break;
829 case REPORT_BL_WRITE_MEMORY:
830 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
831 "REPORT_BL_WRITE_MEMORY", report->id, size-1);
832 hid_debug_event(hdev, buff);
833 /* TODO */
834 break;
835 case REPORT_DEVID:
836 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
837 "REPORT_DEVID", report->id, size-1);
838 hid_debug_event(hdev, buff);
839 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
840 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
841 hid_debug_event(hdev, buff);
842 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
843 raw_data[5]);
844 hid_debug_event(hdev, buff);
845 break;
846 case REPORT_SPLASH_SIZE:
847 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
848 "REPORT_SPLASH_SIZE", report->id, size-1);
849 hid_debug_event(hdev, buff);
850 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
851 (raw_data[2] << 8) | raw_data[1]);
852 hid_debug_event(hdev, buff);
853 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
854 (raw_data[4] << 8) | raw_data[3]);
855 hid_debug_event(hdev, buff);
856 break;
857 case REPORT_HOOK_VERSION:
858 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
859 "REPORT_HOOK_VERSION", report->id, size-1);
860 hid_debug_event(hdev, buff);
861 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
862 raw_data[1], raw_data[2]);
863 hid_debug_event(hdev, buff);
864 break;
865 default:
866 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
867 "<unknown>", report->id, size-1);
868 hid_debug_event(hdev, buff);
869 break;
870 }
871 wake_up_interruptible(&hdev->debug_wait);
872 kfree(buff);
873}
874#else
875#define picolcd_debug_raw_event(data, hdev, report, raw_data, size)
876#endif
877
878/*
879 * Handle raw report as sent by device
880 */
881static int picolcd_raw_event(struct hid_device *hdev,
882 struct hid_report *report, u8 *raw_data, int size)
883{
884 struct picolcd_data *data = hid_get_drvdata(hdev);
885 unsigned long flags;
886 int ret = 0;
887
888 if (!data)
889 return 1;
890
891 if (report->id == REPORT_KEY_STATE) {
892 if (data->input_keys)
893 ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
894 } else if (report->id == REPORT_IR_DATA) {
895 if (data->input_cir)
896 ret = picolcd_raw_cir(data, report, raw_data+1, size-1);
897 } else {
898 spin_lock_irqsave(&data->lock, flags);
899 /*
900 * We let the caller of picolcd_send_and_wait() check if the
901 * report we got is one of the expected ones or not.
902 */
903 if (data->pending) {
904 memcpy(data->pending->raw_data, raw_data+1, size-1);
905 data->pending->raw_size = size-1;
906 data->pending->in_report = report;
907 complete(&data->pending->ready);
908 }
909 spin_unlock_irqrestore(&data->lock, flags);
910 }
911
912 picolcd_debug_raw_event(data, hdev, report, raw_data, size);
913 return 1;
914}
915
916/* initialize keypad input device */
917static int picolcd_init_keys(struct picolcd_data *data,
918 struct hid_report *report)
919{
920 struct hid_device *hdev = data->hdev;
921 struct input_dev *idev;
922 int error, i;
923
924 if (!report)
925 return -ENODEV;
926 if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
927 report->field[0]->report_size != 8) {
928 dev_err(&hdev->dev, "unsupported KEY_STATE report");
929 return -EINVAL;
930 }
931
932 idev = input_allocate_device();
933 if (idev == NULL) {
934 dev_err(&hdev->dev, "failed to allocate input device");
935 return -ENOMEM;
936 }
937 input_set_drvdata(idev, hdev);
938 memcpy(data->keycode, def_keymap, sizeof(def_keymap));
939 idev->name = hdev->name;
940 idev->phys = hdev->phys;
941 idev->uniq = hdev->uniq;
942 idev->id.bustype = hdev->bus;
943 idev->id.vendor = hdev->vendor;
944 idev->id.product = hdev->product;
945 idev->id.version = hdev->version;
946 idev->dev.parent = hdev->dev.parent;
947 idev->keycode = &data->keycode;
948 idev->keycodemax = PICOLCD_KEYS;
949 idev->keycodesize = sizeof(data->keycode[0]);
950 input_set_capability(idev, EV_MSC, MSC_SCAN);
951 set_bit(EV_REP, idev->evbit);
952 for (i = 0; i < PICOLCD_KEYS; i++)
953 input_set_capability(idev, EV_KEY, data->keycode[i]);
954 error = input_register_device(idev);
955 if (error) {
956 dev_err(&hdev->dev, "error registering the input device");
957 input_free_device(idev);
958 return error;
959 }
960 data->input_keys = idev;
961 return 0;
962}
963
964static void picolcd_exit_keys(struct picolcd_data *data)
965{
966 struct input_dev *idev = data->input_keys;
967
968 data->input_keys = NULL;
969 if (idev)
970 input_unregister_device(idev);
971}
972
973/* initialize CIR input device */
974static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
975{
976 /* support not implemented yet */
977 return 0;
978}
979
980static inline void picolcd_exit_cir(struct picolcd_data *data)
981{
982}
983
984static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
985{
986 struct hid_report *report;
987 int error;
988
989 error = picolcd_check_version(hdev);
990 if (error)
991 return error;
992
993 if (data->version[0] != 0 && data->version[1] != 3)
994 dev_info(&hdev->dev, "Device with untested firmware revision, "
995 "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
996 dev_name(&hdev->dev));
997
998 /* Setup keypad input device */
999 error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
1000 if (error)
1001 goto err;
1002
1003 /* Setup CIR input device */
1004 error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev));
1005 if (error)
1006 goto err;
1007
1008#ifdef CONFIG_DEBUG_FS
1009 report = picolcd_out_report(REPORT_READ_MEMORY, hdev);
1010 if (report && report->maxfield == 1 && report->field[0]->report_size == 8)
1011 data->addr_sz = report->field[0]->report_count - 1;
1012 else
1013 data->addr_sz = -1;
1014#endif
1015 return 0;
1016err:
1017 picolcd_exit_cir(data);
1018 picolcd_exit_keys(data);
1019 return error;
1020}
1021
1022static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data)
1023{
1024 struct hid_report *report;
1025 int error;
1026
1027 error = picolcd_check_version(hdev);
1028 if (error)
1029 return error;
1030
1031 if (data->version[0] != 1 && data->version[1] != 0)
1032 dev_info(&hdev->dev, "Device with untested bootloader revision, "
1033 "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
1034 dev_name(&hdev->dev));
1035
1036#ifdef CONFIG_DEBUG_FS
1037 report = picolcd_out_report(REPORT_BL_READ_MEMORY, hdev);
1038 if (report && report->maxfield == 1 && report->field[0]->report_size == 8)
1039 data->addr_sz = report->field[0]->report_count - 1;
1040 else
1041 data->addr_sz = -1;
1042#endif
1043 return 0;
1044}
1045
1046static int picolcd_probe(struct hid_device *hdev,
1047 const struct hid_device_id *id)
1048{
1049 struct picolcd_data *data;
1050 int error = -ENOMEM;
1051
1052 dbg_hid(PICOLCD_NAME " hardware probe...\n");
1053
1054 /*
1055 * Let's allocate the picolcd data structure, set some reasonable
1056 * defaults, and associate it with the device
1057 */
1058 data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
1059 if (data == NULL) {
1060 dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n");
1061 error = -ENOMEM;
1062 goto err_no_cleanup;
1063 }
1064
1065 spin_lock_init(&data->lock);
1066 mutex_init(&data->mutex);
1067 data->hdev = hdev;
1068 if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
1069 data->status |= PICOLCD_BOOTLOADER;
1070 hid_set_drvdata(hdev, data);
1071
1072 /* Parse the device reports and start it up */
1073 error = hid_parse(hdev);
1074 if (error) {
1075 dev_err(&hdev->dev, "device report parse failed\n");
1076 goto err_cleanup_data;
1077 }
1078
1079 /* We don't use hidinput but hid_hw_start() fails if nothing is
1080 * claimed. So spoof claimed input. */
1081 hdev->claimed = HID_CLAIMED_INPUT;
1082 error = hid_hw_start(hdev, 0);
1083 hdev->claimed = 0;
1084 if (error) {
1085 dev_err(&hdev->dev, "hardware start failed\n");
1086 goto err_cleanup_data;
1087 }
1088
1089 error = hdev->ll_driver->open(hdev);
1090 if (error) {
1091 dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n");
1092 goto err_cleanup_hid_hw;
1093 }
1094
1095 error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
1096 if (error) {
1097 dev_err(&hdev->dev, "failed to create sysfs attributes\n");
1098 goto err_cleanup_hid_ll;
1099 }
1100
1101 if (data->status & PICOLCD_BOOTLOADER)
1102 error = picolcd_probe_bootloader(hdev, data);
1103 else
1104 error = picolcd_probe_lcd(hdev, data);
1105 if (error)
1106 goto err_cleanup_sysfs;
1107
1108 dbg_hid(PICOLCD_NAME " activated and initialized\n");
1109 return 0;
1110
1111err_cleanup_sysfs:
1112 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
1113err_cleanup_hid_ll:
1114 hdev->ll_driver->close(hdev);
1115err_cleanup_hid_hw:
1116 hid_hw_stop(hdev);
1117err_cleanup_data:
1118 kfree(data);
1119err_no_cleanup:
1120 hid_set_drvdata(hdev, NULL);
1121
1122 return error;
1123}
1124
1125static void picolcd_remove(struct hid_device *hdev)
1126{
1127 struct picolcd_data *data = hid_get_drvdata(hdev);
1128 unsigned long flags;
1129
1130 dbg_hid(PICOLCD_NAME " hardware remove...\n");
1131 spin_lock_irqsave(&data->lock, flags);
1132 data->status |= PICOLCD_FAILED;
1133 spin_unlock_irqrestore(&data->lock, flags);
1134
1135 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
1136 hdev->ll_driver->close(hdev);
1137 hid_hw_stop(hdev);
1138 hid_set_drvdata(hdev, NULL);
1139
1140 /* Shortcut potential pending reply that will never arrive */
1141 spin_lock_irqsave(&data->lock, flags);
1142 if (data->pending)
1143 complete(&data->pending->ready);
1144 spin_unlock_irqrestore(&data->lock, flags);
1145
1146 /* Cleanup input */
1147 picolcd_exit_cir(data);
1148 picolcd_exit_keys(data);
1149
1150 mutex_destroy(&data->mutex);
1151 /* Finally, clean up the picolcd data itself */
1152 kfree(data);
1153}
1154
1155static const struct hid_device_id picolcd_devices[] = {
1156 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
1157 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
1158 { }
1159};
1160MODULE_DEVICE_TABLE(hid, picolcd_devices);
1161
1162static struct hid_driver picolcd_driver = {
1163 .name = "hid-picolcd",
1164 .id_table = picolcd_devices,
1165 .probe = picolcd_probe,
1166 .remove = picolcd_remove,
1167 .raw_event = picolcd_raw_event,
1168};
1169
1170static int __init picolcd_init(void)
1171{
1172 return hid_register_driver(&picolcd_driver);
1173}
1174
1175static void __exit picolcd_exit(void)
1176{
1177 hid_unregister_driver(&picolcd_driver);
1178}
1179
1180module_init(picolcd_init);
1181module_exit(picolcd_exit);
1182MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
1183MODULE_LICENSE("GPL v2");