kernel_samsung_a34x-permissive/drivers/input/touchscreen/FT3518/tpd_debug.c
2024-04-28 15:51:13 +02:00

438 lines
11 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc.
*/
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/major.h>
#include <linux/miscdevice.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include "tpd.h"
#include "met_ftrace_touch.h"
#ifdef TPD_DEBUG_CODE
int tpd_fail_count;
int tpd_trial_count;
int tpd_debug_nr;
module_param(tpd_debug_nr, int, 0644);
module_param(tpd_fail_count, int, 0644);
module_param(tpd_trial_count, int, 0644);
int tpd_debug_time;
long tpd_last_2_int_time[2] = { 0 };
long tpd_last_down_time;
int tpd_start_profiling;
int tpd_down_status;
module_param(tpd_debug_time, int, 0644);
void tpd_debug_set_time(void)
{
struct timeval t;
if (!tpd_debug_time && !tpd_em_log)
return;
do_gettimeofday(&t);
tpd_last_2_int_time[0] = tpd_last_2_int_time[1];
tpd_last_2_int_time[1] = (t.tv_sec & 0xFFF) * 1000000 + t.tv_usec;
/* */
/* Start profiling while receive touch DOWN event */
/* Stop profiling while the first frame is upadted */
/* */
if (!tpd_down_status) {
tpd_start_profiling = 1;
tpd_last_down_time = tpd_last_2_int_time[1];
}
}
#ifdef TPD_DEBUG_TRACK
int tpd_debug_track;
int tpd_debug_track_color;
int tpd_debug_touch_up;
module_param(tpd_debug_track, int, 0644);
void tpd_draw(int x, int y)
{
UINT16 *buf = (UINT16 *) dal_fb_addr;
buf = buf + (x + y * TPD_RES_X);
tpd_debug_track_color += (tpd_debug_track_color >= 31 ? 0 : 1);
*buf = (0xffe0 + tpd_debug_track_color);
}
void tpd_down_debug_track(int x, int y)
{
if (tpd_debug_touch_up == 1) {
DAL_Clean();
tpd_debug_touch_up = 0;
}
LCD_LayerEnable(5, TRUE);
tpd_draw(x - 1, y - 1);
tpd_draw(x, y - 1);
tpd_draw(x + 1, y - 1);
tpd_draw(x - 1, y);
tpd_draw(x + 1, y);
tpd_draw(x - 1, y + 1);
tpd_draw(x, y + 1);
tpd_draw(x + 1, y + 1);
}
void tpd_up_debug_track(int x, int y)
{
if (x == 0 && y == 0) {
tpd_debug_track_color = 0;
DAL_Clean();
}
tpd_debug_touch_up = 1;
}
#endif /* TPD_DEBUG_TRACK */
#define BUFFER_SIZE 128
int tpd_em_log;
module_param(tpd_em_log, int, 0664);
void tpd_enable_em_log(int enable)
{
if (enable)
tpd_em_log = 1;
else
tpd_em_log = 0;
}
EXPORT_SYMBOL(tpd_enable_em_log);
int tpd_em_log_to_fs;
module_param(tpd_em_log_to_fs, int, 0664);
int tpd_em_log_first = 1;
struct tpd_em_log_struct {
struct list_head list;
char data[BUFFER_SIZE];
};
static LIST_HEAD(tpd_em_log_list);
int tpd_log_line_buffer = 128; /* per line 128 bytes */
int tpd_log_line_cnt = 1024 * 10;
module_param(tpd_log_line_buffer, int, 0664);
module_param(tpd_log_line_cnt, int, 0664);
struct tpd_debug_log_buf {
unsigned int head;
unsigned int tail;
spinlock_t buffer_lock;
unsigned int cnt;
unsigned char *buffer;
};
struct tpd_debug_log_buf tpd_buf;
static int tpd_debug_log_open(struct inode *inode, struct file *file)
{
if (tpd_buf.buffer == NULL)
tpd_buf.buffer =
vmalloc(tpd_log_line_cnt * tpd_log_line_buffer);
if (tpd_buf.buffer == NULL) {
pr_info("tpd_log: nomem for tpd_buf->buffer\n");
return -ENOMEM;
}
spin_lock(&tpd_buf.buffer_lock);
tpd_buf.head = tpd_buf.tail = 0;
tpd_buf.cnt = 0;
spin_unlock(&tpd_buf.buffer_lock);
file->private_data = &tpd_buf;
pr_debug("[tpd_em_log]: open log file\n");
return 0;
}
static int tpd_debug_log_release(struct inode *inode, struct file *file)
{
unsigned char *tmp_buffer = NULL;
pr_debug("[tpd_em_log]: close log file\n");
spin_lock(&tpd_buf.buffer_lock);
tmp_buffer = tpd_buf.buffer;
tpd_buf.buffer = NULL;
spin_unlock(&tpd_buf.buffer_lock);
if (tmp_buffer)
vfree(tmp_buffer);
/* free(tpd_buf); */
return 0;
}
static ssize_t tpd_debug_log_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t tpd_debug_log_read(struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{
struct tpd_debug_log_buf *tpd_buf =
(struct tpd_debug_log_buf *)file->private_data;
unsigned int retval = 0, unit = tpd_log_line_buffer;
unsigned char *tmp_buf = NULL;
if (tpd_buf == NULL)
return -ENOMEM;
if (tpd_buf->head == tpd_buf->tail && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
while ((count - retval) >= unit) {
spin_lock_irq(&tpd_buf->buffer_lock);
if (tpd_buf->head != tpd_buf->tail) {
tmp_buf = &tpd_buf->buffer[tpd_buf->tail++ * unit];
tpd_buf->tail &= tpd_log_line_cnt - 1;
} else {
spin_unlock_irq(&tpd_buf->buffer_lock);
break;
}
spin_unlock_irq(&tpd_buf->buffer_lock);
/* pr_info("%s, tmp_buf:0x%x\n", tmp_buf, tmp_buf); */
if (copy_to_user(buffer + retval, tmp_buf, unit))
return -EFAULT;
retval += unit;
}
return retval;
}
static unsigned char *tpd_log_find_buffer(void)
{
unsigned char *buffer = NULL;
unsigned int unit = tpd_log_line_buffer;
if (tpd_buf.buffer == NULL) {
pr_info("[tpd_em_log] :tpd_buf.buffer is NULL\n");
return NULL;
}
spin_lock(&tpd_buf.buffer_lock);
buffer = &tpd_buf.buffer[tpd_buf.head++ * unit];
tpd_buf.head &= tpd_log_line_cnt - 1;
spin_unlock(&tpd_buf.buffer_lock);
if (tpd_buf.head == tpd_buf.tail) {
snprintf(buffer, unit, "[tpd_em_log] overlay !!!!!\n");
return NULL;
}
memset(buffer, 0, unit);
return buffer;
}
static const struct file_operations tpd_debug_log_fops = {
.owner = THIS_MODULE,
.read = tpd_debug_log_read,
.write = tpd_debug_log_write,
.open = tpd_debug_log_open,
.release = tpd_debug_log_release,
};
static struct miscdevice tpd_debug_log_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "tpd_em_log",
.fops = &tpd_debug_log_fops,
};
#ifndef CREATE_TRACE_POINTS
#define CREATE_TRACE_POINTS
#endif
noinline void MET_touch(int raw_x, int raw_y,
int cal_x, int cal_y, int p, int down)
{
struct timeval t;
do_gettimeofday(&t);
if ((tpd_down_status == 0 && down == 1) ||
(tpd_down_status == 1 && down == 0)) {
trace_MET_touch("EV_KEY",
t.tv_sec, t.tv_usec, "BTN_TOUCH", down);
tpd_down_status = !tpd_down_status;
}
if (tpd_down_status) {
trace_MET_touch("EV_ABS", t.tv_sec, t.tv_usec, "X", raw_x);
trace_MET_touch("EV_ABS", t.tv_sec, t.tv_usec, "Y", raw_y);
}
}
void tpd_em_log_output(int raw_x, int raw_y,
int cal_x, int cal_y, int p, int down)
{
if (down == TPD_TYPE_INT_DOWN) {
pr_debug("[tpd_em_log] int trigger down\n");
} else if (down == TPD_TYPE_INT_UP) {
pr_debug("[tpd_em_log] int trigger up\n");
} else if (down == TPD_TYPE_TIMER) {
pr_debug("[tpd_em_log] timer trigger\n");
} else if (down == TPD_TYPE_RAW_DATA) {
if (tpd_em_log == TPD_TYPE_RAW_DATA) {
pr_debug("[tpd_em_log] rx=%d,ry=%d,rz1=%d"
SPLIT "rz2=%d,p=%d,r\n",
raw_x, raw_y, cal_x, cal_y, p);
}
} else if (down == TPD_TYPE_REJECT1) {
pr_debug("[tpd_em_log] the first or last point is rejected\n");
} else if (down == TPD_TYPE_REJECT2) {
pr_debug
("[tpd_em_log] pressure(%d) > NICE_PRESSURE(%d)"
SPLIT "debounce debt0:%d ms, debt1:%d ms, spl_num:%d\n",
raw_x, raw_y, cal_x, cal_y, p);
} else if (down == TPD_TYPE_FIST_LATENCY) {
pr_debug("[tpd_em_log] The first touch latency is %d ms\n",
raw_x / 1000);
} else if (down && tpd_down_status == 0) {
pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
SPLIT "cy=%d,p=%d,d(+%ld ms)\n",
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
} else if (down && tpd_down_status != 0) {
pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
SPLIT "cy=%d,p=%d,m(+%ld ms)\n",
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
} else {
pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
SPLIT "cy=%d,p=%d,u(+%ld ms)\n",
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
}
}
void tpd_em_log_store(int raw_x, int raw_y,
int cal_x, int cal_y, int p, int down)
{
/* static struct proc_dir_entry *entry = NULL; */
/* struct tpd_em_log_struct *tpd_em_log_struct_new; */
struct timeval t;
unsigned char *buffer = NULL;
/* unsigned int unit = tpd_log_line_buffer; */
/* pr_info("[tpd_em_log]: start register log file"); */
buffer = tpd_log_find_buffer();
if (buffer == NULL) {
pr_info("not buffer\n");
return;
}
do_gettimeofday(&t);
if (down == TPD_TYPE_INT_DOWN) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log] int trigger down\n",
(t.tv_sec & 0xFFF), t.tv_usec);
} else if (down == TPD_TYPE_INT_UP) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log] int trigger up\n",
(t.tv_sec & 0xFFF), t.tv_usec);
} else if (down == TPD_TYPE_TIMER) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log] timer trigger\n",
(t.tv_sec & 0xFFF), t.tv_usec);
} else if (down == TPD_TYPE_RAW_DATA) {
if (tpd_em_log == TPD_TYPE_RAW_DATA) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "rx=%d,ry=%d,rz1=%d,rz2=%d,p=%d,r\n",
(t.tv_sec & 0xFFF), t.tv_usec,
raw_x, raw_y, cal_x, cal_y, p);
}
} else if (down == TPD_TYPE_REJECT1) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "the first or last point is rejected\n",
(t.tv_sec & 0xFFF), t.tv_usec);
} else if (down == TPD_TYPE_REJECT2) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "pressure(%d) > NICE_PRESSURE(%d), "
SPLIT "debounce debt0:%d, debt1:%d, spl_num:%d\n",
(t.tv_sec & 0xFFF), t.tv_usec,
raw_x, raw_y, cal_x, cal_y, p);
} else if (down == TPD_TYPE_FIST_LATENCY) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "The first touch latency is %d ms\n",
(t.tv_sec & 0xFFF), t.tv_usec, raw_x / 1000);
} else if (down && tpd_down_status == 0) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,d(+%ld ms)\n",
(t.tv_sec & 0xFFF), t.tv_usec,
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
} else if (down && tpd_down_status != 0) {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,d(+%ld ms)\n",
(t.tv_sec & 0xFFF), t.tv_usec,
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
} else {
snprintf(buffer, tpd_log_line_buffer,
"[%5lu.%06lu][tpd_em_log]"
SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,u(+%ld ms)\n",
(t.tv_sec & 0xFFF), t.tv_usec,
raw_x, raw_y, cal_x, cal_y, p,
(tpd_last_2_int_time[1] -
tpd_last_2_int_time[0]) / 1000);
}
/* list_add_tail(&tpd_em_log_struct_new->list, &tpd_em_log_list); */
}
void tpd_em_log_release(void)
{
struct tpd_em_log_struct *p, *p_tmp;
if (!tpd_em_log_first) {
remove_proc_entry("tpd_em_log", NULL);
list_for_each_entry_safe(p, p_tmp, &tpd_em_log_list, list) {
list_del(&p->list);
kfree(p);
}
tpd_em_log_first = 1;
tpd_em_log_to_fs = 0;
}
}
static int __init tpd_log_init(void)
{
if (misc_register(&tpd_debug_log_dev) < 0) {
pr_info("[tpd_em_log] :register device failed\n");
return -1;
}
pr_info("[tpd_em_log] :register device successfully\n");
spin_lock_init(&tpd_buf.buffer_lock);
return 0;
}
int tpd_debuglog;
module_param(tpd_debuglog, int, 0664);
module_init(tpd_log_init);
#endif /* TPD_DEBUG_CODE */