^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)