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 
picolcd_debug_reset_show(struct seq_file * f,void * p)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 
picolcd_debug_reset_open(struct inode * inode,struct file * f)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 
picolcd_debug_reset_write(struct file * f,const char __user * user_buf,size_t count,loff_t * ppos)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  */
picolcd_debug_eeprom_read(struct file * f,char __user * u,size_t s,loff_t * off)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 
picolcd_debug_eeprom_write(struct file * f,const char __user * u,size_t s,loff_t * off)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) */
_picolcd_flash_setaddr(struct picolcd_data * data,u8 * buf,long off)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) */
_picolcd_flash_read(struct picolcd_data * data,int report_id,char __user * u,size_t s,loff_t * off)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 
picolcd_debug_flash_read(struct file * f,char __user * u,size_t s,loff_t * off)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 */
_picolcd_flash_erase64(struct picolcd_data * data,int report_id,loff_t * off)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) */
_picolcd_flash_write(struct picolcd_data * data,int report_id,const char __user * u,size_t s,loff_t * off)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 
picolcd_debug_flash_write(struct file * f,const char __user * u,size_t s,loff_t * off)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 
dump_buff_as_hex(char * dst,size_t dst_sz,const u8 * data,const size_t data_len)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 
picolcd_debug_out_report(struct picolcd_data * data,struct hid_device * hdev,struct hid_report * report)394 void picolcd_debug_out_report(struct picolcd_data *data,
395 		struct hid_device *hdev, struct hid_report *report)
396 {
397 	u8 *raw_data;
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 	raw_data = hid_alloc_report_buf(report, GFP_ATOMIC);
411 	if (!raw_data) {
412 		kfree(buff);
413 		return;
414 	}
415 
416 	snprintf(buff, BUFF_SZ, "\nout report %d (size %d) =  ",
417 			report->id, raw_size);
418 	hid_debug_event(hdev, buff);
419 	raw_data[0] = report->id;
420 	hid_output_report(report, raw_data);
421 	dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
422 	hid_debug_event(hdev, buff);
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(raw_data);
648 	kfree(buff);
649 }
650 
picolcd_debug_raw_event(struct picolcd_data * data,struct hid_device * hdev,struct hid_report * report,u8 * raw_data,int size)651 void picolcd_debug_raw_event(struct picolcd_data *data,
652 		struct hid_device *hdev, struct hid_report *report,
653 		u8 *raw_data, int size)
654 {
655 	char *buff;
656 
657 #define BUFF_SZ 256
658 	/* Avoid unnecessary overhead if debugfs is disabled */
659 	if (list_empty(&hdev->debug_list))
660 		return;
661 
662 	buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
663 	if (!buff)
664 		return;
665 
666 	switch (report->id) {
667 	case REPORT_ERROR_CODE:
668 		/* 2 data bytes with affected report and error code */
669 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
670 			"REPORT_ERROR_CODE", report->id, size-1);
671 		hid_debug_event(hdev, buff);
672 		if (raw_data[2] < ARRAY_SIZE(error_codes))
673 			snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
674 					raw_data[2], error_codes[raw_data[2]], raw_data[1]);
675 		else
676 			snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
677 					raw_data[2], raw_data[1]);
678 		hid_debug_event(hdev, buff);
679 		break;
680 	case REPORT_KEY_STATE:
681 		/* 2 data bytes with key state */
682 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
683 			"REPORT_KEY_STATE", report->id, size-1);
684 		hid_debug_event(hdev, buff);
685 		if (raw_data[1] == 0)
686 			snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
687 		else if (raw_data[2] == 0)
688 			snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
689 					raw_data[1], raw_data[1]);
690 		else
691 			snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
692 					raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
693 		hid_debug_event(hdev, buff);
694 		break;
695 	case REPORT_IR_DATA:
696 		/* Up to 20 byes of IR scancode data */
697 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
698 			"REPORT_IR_DATA", report->id, size-1);
699 		hid_debug_event(hdev, buff);
700 		if (raw_data[1] == 0) {
701 			snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
702 			hid_debug_event(hdev, buff);
703 		} else if (raw_data[1] + 1 <= size) {
704 			snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
705 					raw_data[1]);
706 			hid_debug_event(hdev, buff);
707 			dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]);
708 			hid_debug_event(hdev, buff);
709 		} else {
710 			snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
711 					raw_data[1]-1);
712 			hid_debug_event(hdev, buff);
713 		}
714 		break;
715 	case REPORT_EE_DATA:
716 		/* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
717 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
718 			"REPORT_EE_DATA", report->id, size-1);
719 		hid_debug_event(hdev, buff);
720 		snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
721 				raw_data[2], raw_data[1]);
722 		hid_debug_event(hdev, buff);
723 		snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
724 		hid_debug_event(hdev, buff);
725 		if (raw_data[3] == 0) {
726 			snprintf(buff, BUFF_SZ, "\tNo data\n");
727 			hid_debug_event(hdev, buff);
728 		} else if (raw_data[3] + 4 <= size) {
729 			snprintf(buff, BUFF_SZ, "\tData: ");
730 			hid_debug_event(hdev, buff);
731 			dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
732 			hid_debug_event(hdev, buff);
733 		} else {
734 			snprintf(buff, BUFF_SZ, "\tData overflowed\n");
735 			hid_debug_event(hdev, buff);
736 		}
737 		break;
738 	case REPORT_MEMORY:
739 		/* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRITE_MEMORY */
740 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
741 			"REPORT_MEMORY", report->id, size-1);
742 		hid_debug_event(hdev, buff);
743 		switch (data->addr_sz) {
744 		case 2:
745 			snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
746 					raw_data[2], raw_data[1]);
747 			hid_debug_event(hdev, buff);
748 			snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
749 			hid_debug_event(hdev, buff);
750 			if (raw_data[3] == 0) {
751 				snprintf(buff, BUFF_SZ, "\tNo data\n");
752 			} else if (raw_data[3] + 4 <= size) {
753 				snprintf(buff, BUFF_SZ, "\tData: ");
754 				hid_debug_event(hdev, buff);
755 				dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
756 			} else {
757 				snprintf(buff, BUFF_SZ, "\tData overflowed\n");
758 			}
759 			break;
760 		case 3:
761 			snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
762 					raw_data[3], raw_data[2], raw_data[1]);
763 			hid_debug_event(hdev, buff);
764 			snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
765 			hid_debug_event(hdev, buff);
766 			if (raw_data[4] == 0) {
767 				snprintf(buff, BUFF_SZ, "\tNo data\n");
768 			} else if (raw_data[4] + 5 <= size) {
769 				snprintf(buff, BUFF_SZ, "\tData: ");
770 				hid_debug_event(hdev, buff);
771 				dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
772 			} else {
773 				snprintf(buff, BUFF_SZ, "\tData overflowed\n");
774 			}
775 			break;
776 		default:
777 			snprintf(buff, BUFF_SZ, "\tNot supported\n");
778 		}
779 		hid_debug_event(hdev, buff);
780 		break;
781 	case REPORT_VERSION:
782 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
783 			"REPORT_VERSION", report->id, size-1);
784 		hid_debug_event(hdev, buff);
785 		snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
786 				raw_data[2], raw_data[1]);
787 		hid_debug_event(hdev, buff);
788 		break;
789 	case REPORT_BL_ERASE_MEMORY:
790 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
791 			"REPORT_BL_ERASE_MEMORY", report->id, size-1);
792 		hid_debug_event(hdev, buff);
793 		/* TODO */
794 		break;
795 	case REPORT_BL_READ_MEMORY:
796 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
797 			"REPORT_BL_READ_MEMORY", report->id, size-1);
798 		hid_debug_event(hdev, buff);
799 		/* TODO */
800 		break;
801 	case REPORT_BL_WRITE_MEMORY:
802 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
803 			"REPORT_BL_WRITE_MEMORY", report->id, size-1);
804 		hid_debug_event(hdev, buff);
805 		/* TODO */
806 		break;
807 	case REPORT_DEVID:
808 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
809 			"REPORT_DEVID", report->id, size-1);
810 		hid_debug_event(hdev, buff);
811 		snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
812 				raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
813 		hid_debug_event(hdev, buff);
814 		snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
815 				raw_data[5]);
816 		hid_debug_event(hdev, buff);
817 		break;
818 	case REPORT_SPLASH_SIZE:
819 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
820 			"REPORT_SPLASH_SIZE", report->id, size-1);
821 		hid_debug_event(hdev, buff);
822 		snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
823 				(raw_data[2] << 8) | raw_data[1]);
824 		hid_debug_event(hdev, buff);
825 		snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
826 				(raw_data[4] << 8) | raw_data[3]);
827 		hid_debug_event(hdev, buff);
828 		break;
829 	case REPORT_HOOK_VERSION:
830 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
831 			"REPORT_HOOK_VERSION", report->id, size-1);
832 		hid_debug_event(hdev, buff);
833 		snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
834 				raw_data[1], raw_data[2]);
835 		hid_debug_event(hdev, buff);
836 		break;
837 	default:
838 		snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
839 			"<unknown>", report->id, size-1);
840 		hid_debug_event(hdev, buff);
841 		break;
842 	}
843 	wake_up_interruptible(&hdev->debug_wait);
844 	kfree(buff);
845 }
846 
picolcd_init_devfs(struct picolcd_data * data,struct hid_report * eeprom_r,struct hid_report * eeprom_w,struct hid_report * flash_r,struct hid_report * flash_w,struct hid_report * reset)847 void picolcd_init_devfs(struct picolcd_data *data,
848 		struct hid_report *eeprom_r, struct hid_report *eeprom_w,
849 		struct hid_report *flash_r, struct hid_report *flash_w,
850 		struct hid_report *reset)
851 {
852 	struct hid_device *hdev = data->hdev;
853 
854 	mutex_init(&data->mutex_flash);
855 
856 	/* reset */
857 	if (reset)
858 		data->debug_reset = debugfs_create_file("reset", 0600,
859 				hdev->debug_dir, data, &picolcd_debug_reset_fops);
860 
861 	/* eeprom */
862 	if (eeprom_r || eeprom_w)
863 		data->debug_eeprom = debugfs_create_file("eeprom",
864 			(eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
865 			hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
866 
867 	/* flash */
868 	if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
869 		data->addr_sz = flash_r->field[0]->report_count - 1;
870 	else
871 		data->addr_sz = -1;
872 	if (data->addr_sz == 2 || data->addr_sz == 3) {
873 		data->debug_flash = debugfs_create_file("flash",
874 			(flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
875 			hdev->debug_dir, data, &picolcd_debug_flash_fops);
876 	} else if (flash_r || flash_w)
877 		hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
878 }
879 
picolcd_exit_devfs(struct picolcd_data * data)880 void picolcd_exit_devfs(struct picolcd_data *data)
881 {
882 	struct dentry *dent;
883 
884 	dent = data->debug_reset;
885 	data->debug_reset = NULL;
886 	debugfs_remove(dent);
887 	dent = data->debug_eeprom;
888 	data->debug_eeprom = NULL;
889 	debugfs_remove(dent);
890 	dent = data->debug_flash;
891 	data->debug_flash = NULL;
892 	debugfs_remove(dent);
893 	mutex_destroy(&data->mutex_flash);
894 }
895 
896