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