Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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