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