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