Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/***************************************************************************
3 * Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org> *
4 * *
5 * Based on Logitech G13 driver (v0.4) *
6 * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
7 * *
8 ***************************************************************************/
9
10#include <linux/hid.h>
11#include <linux/hid-debug.h>
12
13#include <linux/fb.h>
14#include <linux/hex.h>
15#include <linux/seq_file.h>
16#include <linux/debugfs.h>
17
18#include <linux/module.h>
19#include <linux/uaccess.h>
20
21#include "hid-picolcd.h"
22
23
24static int picolcd_debug_reset_show(struct seq_file *f, void *p)
25{
26 if (picolcd_fbinfo((struct picolcd_data *)f->private))
27 seq_printf(f, "all fb\n");
28 else
29 seq_printf(f, "all\n");
30 return 0;
31}
32
33static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
34{
35 return single_open(f, picolcd_debug_reset_show, inode->i_private);
36}
37
38static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
39 size_t count, loff_t *ppos)
40{
41 struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
42 char buf[32];
43 size_t cnt = min(count, sizeof(buf)-1);
44 if (copy_from_user(buf, user_buf, cnt))
45 return -EFAULT;
46
47 while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
48 cnt--;
49 buf[cnt] = '\0';
50 if (strcmp(buf, "all") == 0) {
51 picolcd_reset(data->hdev);
52 picolcd_fb_reset(data, 1);
53 } else if (strcmp(buf, "fb") == 0) {
54 picolcd_fb_reset(data, 1);
55 } else {
56 return -EINVAL;
57 }
58 return count;
59}
60
61static const struct file_operations picolcd_debug_reset_fops = {
62 .owner = THIS_MODULE,
63 .open = picolcd_debug_reset_open,
64 .read = seq_read,
65 .llseek = seq_lseek,
66 .write = picolcd_debug_reset_write,
67 .release = single_release,
68};
69
70/*
71 * The "eeprom" file
72 */
73static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
74 size_t s, loff_t *off)
75{
76 struct picolcd_data *data = f->private_data;
77 struct picolcd_pending *resp;
78 u8 raw_data[3];
79 ssize_t ret = -EIO;
80
81 if (s == 0)
82 return -EINVAL;
83 if (*off > 0x0ff)
84 return 0;
85
86 /* prepare buffer with info about what we want to read (addr & len) */
87 raw_data[0] = *off & 0xff;
88 raw_data[1] = (*off >> 8) & 0xff;
89 raw_data[2] = s < 20 ? s : 20;
90 if (*off + raw_data[2] > 0xff)
91 raw_data[2] = 0x100 - *off;
92 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
93 sizeof(raw_data));
94 if (!resp)
95 return -EIO;
96
97 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
98 /* successful read :) */
99 ret = resp->raw_data[2];
100 if (ret > s)
101 ret = s;
102 if (copy_to_user(u, resp->raw_data+3, ret))
103 ret = -EFAULT;
104 else
105 *off += ret;
106 } /* anything else is some kind of IO error */
107
108 kfree(resp);
109 return ret;
110}
111
112static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
113 size_t s, loff_t *off)
114{
115 struct picolcd_data *data = f->private_data;
116 struct picolcd_pending *resp;
117 ssize_t ret = -EIO;
118 u8 raw_data[23];
119
120 if (s == 0)
121 return -EINVAL;
122 if (*off > 0x0ff)
123 return -ENOSPC;
124
125 memset(raw_data, 0, sizeof(raw_data));
126 raw_data[0] = *off & 0xff;
127 raw_data[1] = (*off >> 8) & 0xff;
128 raw_data[2] = min_t(size_t, 20, s);
129 if (*off + raw_data[2] > 0xff)
130 raw_data[2] = 0x100 - *off;
131
132 if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
133 return -EFAULT;
134 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
135 sizeof(raw_data));
136
137 if (!resp)
138 return -EIO;
139
140 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
141 /* check if written data matches */
142 if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
143 *off += raw_data[2];
144 ret = raw_data[2];
145 }
146 }
147 kfree(resp);
148 return ret;
149}
150
151/*
152 * Notes:
153 * - read/write happens in chunks of at most 20 bytes, it's up to userspace
154 * to loop in order to get more data.
155 * - on write errors on otherwise correct write request the bytes
156 * that should have been written are in undefined state.
157 */
158static const struct file_operations picolcd_debug_eeprom_fops = {
159 .owner = THIS_MODULE,
160 .open = simple_open,
161 .read = picolcd_debug_eeprom_read,
162 .write = picolcd_debug_eeprom_write,
163 .llseek = generic_file_llseek,
164};
165
166/*
167 * The "flash" file
168 */
169/* record a flash address to buf (bounds check to be done by caller) */
170static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
171{
172 buf[0] = off & 0xff;
173 buf[1] = (off >> 8) & 0xff;
174 if (data->addr_sz == 3)
175 buf[2] = (off >> 16) & 0xff;
176 return data->addr_sz == 2 ? 2 : 3;
177}
178
179/* read a given size of data (bounds check to be done by caller) */
180static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
181 char __user *u, size_t s, loff_t *off)
182{
183 struct picolcd_pending *resp;
184 u8 raw_data[4];
185 ssize_t ret = 0;
186 int len_off, err = -EIO;
187
188 while (s > 0) {
189 err = -EIO;
190 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
191 raw_data[len_off] = s > 32 ? 32 : s;
192 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
193 if (!resp || !resp->in_report)
194 goto skip;
195 if (resp->in_report->id == REPORT_MEMORY ||
196 resp->in_report->id == REPORT_BL_READ_MEMORY) {
197 if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
198 goto skip;
199 if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
200 err = -EFAULT;
201 goto skip;
202 }
203 *off += raw_data[len_off];
204 s -= raw_data[len_off];
205 ret += raw_data[len_off];
206 err = 0;
207 }
208skip:
209 kfree(resp);
210 if (err)
211 return ret > 0 ? ret : err;
212 }
213 return ret;
214}
215
216static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
217 size_t s, loff_t *off)
218{
219 struct picolcd_data *data = f->private_data;
220
221 if (s == 0)
222 return -EINVAL;
223 if (*off > 0x05fff)
224 return 0;
225 if (*off + s > 0x05fff)
226 s = 0x06000 - *off;
227
228 if (data->status & PICOLCD_BOOTLOADER)
229 return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
230 else
231 return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
232}
233
234/* erase block aligned to 64bytes boundary */
235static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
236 loff_t *off)
237{
238 struct picolcd_pending *resp;
239 u8 raw_data[3];
240 int len_off;
241 ssize_t ret = -EIO;
242
243 if (*off & 0x3f)
244 return -EINVAL;
245
246 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
247 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
248 if (!resp || !resp->in_report)
249 goto skip;
250 if (resp->in_report->id == REPORT_MEMORY ||
251 resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
252 if (memcmp(raw_data, resp->raw_data, len_off) != 0)
253 goto skip;
254 ret = 0;
255 }
256skip:
257 kfree(resp);
258 return ret;
259}
260
261/* write a given size of data (bounds check to be done by caller) */
262static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
263 const char __user *u, size_t s, loff_t *off)
264{
265 struct picolcd_pending *resp;
266 u8 raw_data[36];
267 ssize_t ret = 0;
268 int len_off, err = -EIO;
269
270 while (s > 0) {
271 err = -EIO;
272 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
273 raw_data[len_off] = s > 32 ? 32 : s;
274 if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
275 err = -EFAULT;
276 break;
277 }
278 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
279 len_off+1+raw_data[len_off]);
280 if (!resp || !resp->in_report)
281 goto skip;
282 if (resp->in_report->id == REPORT_MEMORY ||
283 resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
284 if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
285 goto skip;
286 *off += raw_data[len_off];
287 s -= raw_data[len_off];
288 ret += raw_data[len_off];
289 err = 0;
290 }
291skip:
292 kfree(resp);
293 if (err)
294 break;
295 }
296 return ret > 0 ? ret : err;
297}
298
299static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
300 size_t s, loff_t *off)
301{
302 struct picolcd_data *data = f->private_data;
303 ssize_t err, ret = 0;
304 int report_erase, report_write;
305
306 if (s == 0)
307 return -EINVAL;
308 if (*off > 0x5fff)
309 return -ENOSPC;
310 if (s & 0x3f)
311 return -EINVAL;
312 if (*off & 0x3f)
313 return -EINVAL;
314
315 if (data->status & PICOLCD_BOOTLOADER) {
316 report_erase = REPORT_BL_ERASE_MEMORY;
317 report_write = REPORT_BL_WRITE_MEMORY;
318 } else {
319 report_erase = REPORT_ERASE_MEMORY;
320 report_write = REPORT_WRITE_MEMORY;
321 }
322 mutex_lock(&data->mutex_flash);
323 while (s > 0) {
324 err = _picolcd_flash_erase64(data, report_erase, off);
325 if (err)
326 break;
327 err = _picolcd_flash_write(data, report_write, u, 64, off);
328 if (err < 0)
329 break;
330 ret += err;
331 *off += err;
332 s -= err;
333 if (err != 64)
334 break;
335 }
336 mutex_unlock(&data->mutex_flash);
337 return ret > 0 ? ret : err;
338}
339
340/*
341 * Notes:
342 * - concurrent writing is prevented by mutex and all writes must be
343 * n*64 bytes and 64-byte aligned, each write being preceded by an
344 * ERASE which erases a 64byte block.
345 * If less than requested was written or an error is returned for an
346 * otherwise correct write request the next 64-byte block which should
347 * have been written is in undefined state (mostly: original, erased,
348 * (half-)written with write error)
349 * - reading can happen without special restriction
350 */
351static const struct file_operations picolcd_debug_flash_fops = {
352 .owner = THIS_MODULE,
353 .open = simple_open,
354 .read = picolcd_debug_flash_read,
355 .write = picolcd_debug_flash_write,
356 .llseek = generic_file_llseek,
357};
358
359
360/*
361 * Helper code for HID report level dumping/debugging
362 */
363static const char * const error_codes[] = {
364 "success", "parameter missing", "data_missing", "block readonly",
365 "block not erasable", "block too big", "section overflow",
366 "invalid command length", "invalid data length",
367};
368
369static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
370 const size_t data_len)
371{
372 int i, j;
373 for (i = j = 0; i < data_len && j + 4 < dst_sz; i++) {
374 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
375 dst[j++] = hex_asc[data[i] & 0x0f];
376 dst[j++] = ' ';
377 }
378 dst[j] = '\0';
379 if (j > 0)
380 dst[j-1] = '\n';
381 if (i < data_len && j > 2)
382 dst[j-2] = dst[j-3] = '.';
383}
384
385void picolcd_debug_out_report(struct picolcd_data *data,
386 struct hid_device *hdev, struct hid_report *report)
387{
388 u8 *raw_data;
389 int raw_size = (report->size >> 3) + 1;
390 char *buff;
391#define BUFF_SZ 256
392
393 /* Avoid unnecessary overhead if debugfs is disabled */
394 if (list_empty(&hdev->debug_list))
395 return;
396
397 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
398 if (!buff)
399 return;
400
401 raw_data = hid_alloc_report_buf(report, GFP_ATOMIC);
402 if (!raw_data) {
403 kfree(buff);
404 return;
405 }
406
407 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
408 report->id, raw_size);
409 hid_debug_event(hdev, buff);
410 raw_data[0] = report->id;
411 hid_output_report(report, raw_data);
412 dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
413 hid_debug_event(hdev, buff);
414
415 switch (report->id) {
416 case REPORT_LED_STATE:
417 /* 1 data byte with GPO state */
418 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
419 "REPORT_LED_STATE", report->id, raw_size-1);
420 hid_debug_event(hdev, buff);
421 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
422 hid_debug_event(hdev, buff);
423 break;
424 case REPORT_BRIGHTNESS:
425 /* 1 data byte with brightness */
426 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
427 "REPORT_BRIGHTNESS", report->id, raw_size-1);
428 hid_debug_event(hdev, buff);
429 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
430 hid_debug_event(hdev, buff);
431 break;
432 case REPORT_CONTRAST:
433 /* 1 data byte with contrast */
434 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
435 "REPORT_CONTRAST", report->id, raw_size-1);
436 hid_debug_event(hdev, buff);
437 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
438 hid_debug_event(hdev, buff);
439 break;
440 case REPORT_RESET:
441 /* 2 data bytes with reset duration in ms */
442 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
443 "REPORT_RESET", report->id, raw_size-1);
444 hid_debug_event(hdev, buff);
445 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
446 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
447 hid_debug_event(hdev, buff);
448 break;
449 case REPORT_LCD_CMD:
450 /* 63 data bytes with LCD commands */
451 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
452 "REPORT_LCD_CMD", report->id, raw_size-1);
453 hid_debug_event(hdev, buff);
454 /* TODO: format decoding */
455 break;
456 case REPORT_LCD_DATA:
457 /* 63 data bytes with LCD data */
458 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
459 "REPORT_LCD_CMD", report->id, raw_size-1);
460 /* TODO: format decoding */
461 hid_debug_event(hdev, buff);
462 break;
463 case REPORT_LCD_CMD_DATA:
464 /* 63 data bytes with LCD commands and data */
465 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
466 "REPORT_LCD_CMD", report->id, raw_size-1);
467 /* TODO: format decoding */
468 hid_debug_event(hdev, buff);
469 break;
470 case REPORT_EE_READ:
471 /* 3 data bytes with read area description */
472 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
473 "REPORT_EE_READ", report->id, raw_size-1);
474 hid_debug_event(hdev, buff);
475 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
476 raw_data[2], raw_data[1]);
477 hid_debug_event(hdev, buff);
478 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
479 hid_debug_event(hdev, buff);
480 break;
481 case REPORT_EE_WRITE:
482 /* 3+1..20 data bytes with write area description */
483 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
484 "REPORT_EE_WRITE", report->id, raw_size-1);
485 hid_debug_event(hdev, buff);
486 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
487 raw_data[2], raw_data[1]);
488 hid_debug_event(hdev, buff);
489 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
490 hid_debug_event(hdev, buff);
491 if (raw_data[3] == 0) {
492 snprintf(buff, BUFF_SZ, "\tNo data\n");
493 } else if (raw_data[3] + 4 <= raw_size) {
494 snprintf(buff, BUFF_SZ, "\tData: ");
495 hid_debug_event(hdev, buff);
496 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
497 } else {
498 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
499 }
500 hid_debug_event(hdev, buff);
501 break;
502 case REPORT_ERASE_MEMORY:
503 case REPORT_BL_ERASE_MEMORY:
504 /* 3 data bytes with pointer inside erase block */
505 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
506 "REPORT_ERASE_MEMORY", report->id, raw_size-1);
507 hid_debug_event(hdev, buff);
508 switch (data->addr_sz) {
509 case 2:
510 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
511 raw_data[2], raw_data[1]);
512 break;
513 case 3:
514 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
515 raw_data[3], raw_data[2], raw_data[1]);
516 break;
517 default:
518 snprintf(buff, BUFF_SZ, "\tNot supported\n");
519 }
520 hid_debug_event(hdev, buff);
521 break;
522 case REPORT_READ_MEMORY:
523 case REPORT_BL_READ_MEMORY:
524 /* 4 data bytes with read area description */
525 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
526 "REPORT_READ_MEMORY", report->id, raw_size-1);
527 hid_debug_event(hdev, buff);
528 switch (data->addr_sz) {
529 case 2:
530 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
531 raw_data[2], raw_data[1]);
532 hid_debug_event(hdev, buff);
533 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
534 break;
535 case 3:
536 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
537 raw_data[3], raw_data[2], raw_data[1]);
538 hid_debug_event(hdev, buff);
539 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
540 break;
541 default:
542 snprintf(buff, BUFF_SZ, "\tNot supported\n");
543 }
544 hid_debug_event(hdev, buff);
545 break;
546 case REPORT_WRITE_MEMORY:
547 case REPORT_BL_WRITE_MEMORY:
548 /* 4+1..32 data bytes with write adrea description */
549 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
550 "REPORT_WRITE_MEMORY", report->id, raw_size-1);
551 hid_debug_event(hdev, buff);
552 switch (data->addr_sz) {
553 case 2:
554 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
555 raw_data[2], raw_data[1]);
556 hid_debug_event(hdev, buff);
557 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
558 hid_debug_event(hdev, buff);
559 if (raw_data[3] == 0) {
560 snprintf(buff, BUFF_SZ, "\tNo data\n");
561 } else if (raw_data[3] + 4 <= raw_size) {
562 snprintf(buff, BUFF_SZ, "\tData: ");
563 hid_debug_event(hdev, buff);
564 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
565 } else {
566 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
567 }
568 break;
569 case 3:
570 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
571 raw_data[3], raw_data[2], raw_data[1]);
572 hid_debug_event(hdev, buff);
573 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
574 hid_debug_event(hdev, buff);
575 if (raw_data[4] == 0) {
576 snprintf(buff, BUFF_SZ, "\tNo data\n");
577 } else if (raw_data[4] + 5 <= raw_size) {
578 snprintf(buff, BUFF_SZ, "\tData: ");
579 hid_debug_event(hdev, buff);
580 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
581 } else {
582 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
583 }
584 break;
585 default:
586 snprintf(buff, BUFF_SZ, "\tNot supported\n");
587 }
588 hid_debug_event(hdev, buff);
589 break;
590 case REPORT_SPLASH_RESTART:
591 /* TODO */
592 break;
593 case REPORT_EXIT_KEYBOARD:
594 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
595 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
596 hid_debug_event(hdev, buff);
597 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
598 raw_data[1] | (raw_data[2] << 8),
599 raw_data[2], raw_data[1]);
600 hid_debug_event(hdev, buff);
601 break;
602 case REPORT_VERSION:
603 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
604 "REPORT_VERSION", report->id, raw_size-1);
605 hid_debug_event(hdev, buff);
606 break;
607 case REPORT_DEVID:
608 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
609 "REPORT_DEVID", report->id, raw_size-1);
610 hid_debug_event(hdev, buff);
611 break;
612 case REPORT_SPLASH_SIZE:
613 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
614 "REPORT_SPLASH_SIZE", report->id, raw_size-1);
615 hid_debug_event(hdev, buff);
616 break;
617 case REPORT_HOOK_VERSION:
618 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
619 "REPORT_HOOK_VERSION", report->id, raw_size-1);
620 hid_debug_event(hdev, buff);
621 break;
622 case REPORT_EXIT_FLASHER:
623 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
624 "REPORT_VERSION", report->id, raw_size-1);
625 hid_debug_event(hdev, buff);
626 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
627 raw_data[1] | (raw_data[2] << 8),
628 raw_data[2], raw_data[1]);
629 hid_debug_event(hdev, buff);
630 break;
631 default:
632 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
633 "<unknown>", report->id, raw_size-1);
634 hid_debug_event(hdev, buff);
635 break;
636 }
637 wake_up_interruptible(&hdev->debug_wait);
638 kfree(raw_data);
639 kfree(buff);
640}
641
642void picolcd_debug_raw_event(struct picolcd_data *data,
643 struct hid_device *hdev, struct hid_report *report,
644 u8 *raw_data, int size)
645{
646 char *buff;
647
648#define BUFF_SZ 256
649 /* Avoid unnecessary overhead if debugfs is disabled */
650 if (list_empty(&hdev->debug_list))
651 return;
652
653 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
654 if (!buff)
655 return;
656
657 switch (report->id) {
658 case REPORT_ERROR_CODE:
659 /* 2 data bytes with affected report and error code */
660 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
661 "REPORT_ERROR_CODE", report->id, size-1);
662 hid_debug_event(hdev, buff);
663 if (raw_data[2] < ARRAY_SIZE(error_codes))
664 snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
665 raw_data[2], error_codes[raw_data[2]], raw_data[1]);
666 else
667 snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
668 raw_data[2], raw_data[1]);
669 hid_debug_event(hdev, buff);
670 break;
671 case REPORT_KEY_STATE:
672 /* 2 data bytes with key state */
673 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
674 "REPORT_KEY_STATE", report->id, size-1);
675 hid_debug_event(hdev, buff);
676 if (raw_data[1] == 0)
677 snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
678 else if (raw_data[2] == 0)
679 snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
680 raw_data[1], raw_data[1]);
681 else
682 snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
683 raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
684 hid_debug_event(hdev, buff);
685 break;
686 case REPORT_IR_DATA:
687 /* Up to 20 byes of IR scancode data */
688 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
689 "REPORT_IR_DATA", report->id, size-1);
690 hid_debug_event(hdev, buff);
691 if (raw_data[1] == 0) {
692 snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
693 hid_debug_event(hdev, buff);
694 } else if (raw_data[1] + 1 <= size) {
695 snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
696 raw_data[1]);
697 hid_debug_event(hdev, buff);
698 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]);
699 hid_debug_event(hdev, buff);
700 } else {
701 snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
702 raw_data[1]-1);
703 hid_debug_event(hdev, buff);
704 }
705 break;
706 case REPORT_EE_DATA:
707 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
708 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
709 "REPORT_EE_DATA", report->id, size-1);
710 hid_debug_event(hdev, buff);
711 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
712 raw_data[2], raw_data[1]);
713 hid_debug_event(hdev, buff);
714 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
715 hid_debug_event(hdev, buff);
716 if (raw_data[3] == 0) {
717 snprintf(buff, BUFF_SZ, "\tNo data\n");
718 hid_debug_event(hdev, buff);
719 } else if (raw_data[3] + 4 <= size) {
720 snprintf(buff, BUFF_SZ, "\tData: ");
721 hid_debug_event(hdev, buff);
722 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
723 hid_debug_event(hdev, buff);
724 } else {
725 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
726 hid_debug_event(hdev, buff);
727 }
728 break;
729 case REPORT_MEMORY:
730 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRITE_MEMORY */
731 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
732 "REPORT_MEMORY", report->id, size-1);
733 hid_debug_event(hdev, buff);
734 switch (data->addr_sz) {
735 case 2:
736 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
737 raw_data[2], raw_data[1]);
738 hid_debug_event(hdev, buff);
739 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
740 hid_debug_event(hdev, buff);
741 if (raw_data[3] == 0) {
742 snprintf(buff, BUFF_SZ, "\tNo data\n");
743 } else if (raw_data[3] + 4 <= size) {
744 snprintf(buff, BUFF_SZ, "\tData: ");
745 hid_debug_event(hdev, buff);
746 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
747 } else {
748 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
749 }
750 break;
751 case 3:
752 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
753 raw_data[3], raw_data[2], raw_data[1]);
754 hid_debug_event(hdev, buff);
755 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
756 hid_debug_event(hdev, buff);
757 if (raw_data[4] == 0) {
758 snprintf(buff, BUFF_SZ, "\tNo data\n");
759 } else if (raw_data[4] + 5 <= size) {
760 snprintf(buff, BUFF_SZ, "\tData: ");
761 hid_debug_event(hdev, buff);
762 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
763 } else {
764 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
765 }
766 break;
767 default:
768 snprintf(buff, BUFF_SZ, "\tNot supported\n");
769 }
770 hid_debug_event(hdev, buff);
771 break;
772 case REPORT_VERSION:
773 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
774 "REPORT_VERSION", report->id, size-1);
775 hid_debug_event(hdev, buff);
776 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
777 raw_data[2], raw_data[1]);
778 hid_debug_event(hdev, buff);
779 break;
780 case REPORT_BL_ERASE_MEMORY:
781 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
782 "REPORT_BL_ERASE_MEMORY", report->id, size-1);
783 hid_debug_event(hdev, buff);
784 /* TODO */
785 break;
786 case REPORT_BL_READ_MEMORY:
787 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
788 "REPORT_BL_READ_MEMORY", report->id, size-1);
789 hid_debug_event(hdev, buff);
790 /* TODO */
791 break;
792 case REPORT_BL_WRITE_MEMORY:
793 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
794 "REPORT_BL_WRITE_MEMORY", report->id, size-1);
795 hid_debug_event(hdev, buff);
796 /* TODO */
797 break;
798 case REPORT_DEVID:
799 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
800 "REPORT_DEVID", report->id, size-1);
801 hid_debug_event(hdev, buff);
802 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
803 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
804 hid_debug_event(hdev, buff);
805 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
806 raw_data[5]);
807 hid_debug_event(hdev, buff);
808 break;
809 case REPORT_SPLASH_SIZE:
810 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
811 "REPORT_SPLASH_SIZE", report->id, size-1);
812 hid_debug_event(hdev, buff);
813 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
814 (raw_data[2] << 8) | raw_data[1]);
815 hid_debug_event(hdev, buff);
816 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
817 (raw_data[4] << 8) | raw_data[3]);
818 hid_debug_event(hdev, buff);
819 break;
820 case REPORT_HOOK_VERSION:
821 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
822 "REPORT_HOOK_VERSION", report->id, size-1);
823 hid_debug_event(hdev, buff);
824 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
825 raw_data[1], raw_data[2]);
826 hid_debug_event(hdev, buff);
827 break;
828 default:
829 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
830 "<unknown>", report->id, size-1);
831 hid_debug_event(hdev, buff);
832 break;
833 }
834 wake_up_interruptible(&hdev->debug_wait);
835 kfree(buff);
836}
837
838void picolcd_init_devfs(struct picolcd_data *data,
839 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
840 struct hid_report *flash_r, struct hid_report *flash_w,
841 struct hid_report *reset)
842{
843 struct hid_device *hdev = data->hdev;
844
845 mutex_init(&data->mutex_flash);
846
847 /* reset */
848 if (reset)
849 data->debug_reset = debugfs_create_file("reset", 0600,
850 hdev->debug_dir, data, &picolcd_debug_reset_fops);
851
852 /* eeprom */
853 if (eeprom_r || eeprom_w)
854 data->debug_eeprom = debugfs_create_file("eeprom",
855 (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
856 hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
857
858 /* flash */
859 if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
860 data->addr_sz = flash_r->field[0]->report_count - 1;
861 else
862 data->addr_sz = -1;
863 if (data->addr_sz == 2 || data->addr_sz == 3) {
864 data->debug_flash = debugfs_create_file("flash",
865 (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
866 hdev->debug_dir, data, &picolcd_debug_flash_fops);
867 } else if (flash_r || flash_w)
868 hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
869}
870
871void picolcd_exit_devfs(struct picolcd_data *data)
872{
873 struct dentry *dent;
874
875 dent = data->debug_reset;
876 data->debug_reset = NULL;
877 debugfs_remove(dent);
878 dent = data->debug_eeprom;
879 data->debug_eeprom = NULL;
880 debugfs_remove(dent);
881 dent = data->debug_flash;
882 data->debug_flash = NULL;
883 debugfs_remove(dent);
884 mutex_destroy(&data->mutex_flash);
885}
886