kernel-brax3-ubuntu-touch/drivers/input/touchscreen/omnivision_tcm/omnivision_tcm_csv_parser.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

289 lines
6.3 KiB
C
Executable file

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include "omnivision_tcm_testing.h"
#include "omnivision_tcm_core.h"
#define STRTOL_LEN 10
static void copy_this_line(char *dest, char *src)
{
char *copy_from;
char *copy_to;
copy_from = src;
copy_to = dest;
do {
*copy_to = *copy_from;
copy_from++;
copy_to++;
} while((*copy_from != '\n') && (*copy_from != '\r') && (*copy_from != '\0'));
*copy_to = '\0';
}
static void goto_next_line(char **ptr)
{
do {
*ptr = *ptr + 1;
} while (**ptr != '\n' && **ptr != '\0');
if (**ptr == '\0') {
return;
}
*ptr = *ptr + 1;
}
static void parse_valid_data(char *buf_start, loff_t buf_size,
char *ptr, int32_t* data, int rows)
{
int i = 0;
int j = 0;
char *token = NULL;
char *tok_ptr = NULL;
char row_data[512] = {0};
if(!ptr) {
printk("ovt tcm csv parser: %s, ptr is NULL\n", __func__);
return;
}
if (!data) {
printk("ovt tcm csv parser: %s, data is NULL\n", __func__);
return;
}
for (i = 0; i < rows; i++) {
// copy this line to row_data buffer
memset(row_data, 0, sizeof(row_data));
copy_this_line(row_data, ptr);
tok_ptr = row_data;
while ((token = strsep(&tok_ptr,", \t\n\r\0"))) {
if (strlen(token) == 0)
continue;
data[j] = (int32_t)simple_strtol(token, NULL, STRTOL_LEN);
j ++;
}
goto_next_line(&ptr); //next row
if(!ptr || (0 == strlen(ptr)) || (ptr >= (buf_start + buf_size))) {
printk("ovt tcm csv parser: invalid ptr, return\n");
break;
}
}
return;
}
static void print_data(char* target_name, int32_t* data, int rows, int columns)
{
int i,j;
printk("ovt tcm csv parser: print data %s\n", target_name);
if(NULL == data) {
printk("ovt tcm csv parser: rawdata is NULL\n");
return;
}
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
printk("\t%d", data[i*columns + j]);
}
printk("\n");
}
return;
}
int ovt_tcm_parse_csvfile(char *file_path, char *target_name, int32_t *data, int rows, int columns)
{
struct file *fp = NULL;
int ret = 0;
int32_t read_ret = 0;
char *buf = NULL;
char *ptr = NULL;
int32_t fsize = 0;
loff_t pos = 0;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 14, 0)
struct kstat stat;
mm_segment_t org_fs;
org_fs = get_fs();
set_fs(KERNEL_DS);
#endif
if(NULL == file_path) {
printk("ovt tcm csv parser: file path pointer is NULL\n");
ret = -EPERM;
goto exit_free;
}
if(NULL == target_name) {
printk("ovt tcm csv parser: target path pointer is NULL\n");
ret = -EPERM;
goto exit_free;
}
printk("ovt tcm csv parser: %s, file name is %s, target is %s.\n", __func__,file_path,target_name);
fp = filp_open(file_path, O_RDONLY, 0);
if (IS_ERR_OR_NULL(fp)) {
printk("ovt tcm csv parser: %s, filp_open error, file name is %s.\n", __func__,file_path);
ret = -EPERM;
goto exit_free;
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 14, 0)
ret = vfs_stat(file_path, &stat);
if(ret) {
printk("ovt tcm csv parser: %s, failed to get file stat.\n", __func__);
ret = -ENOENT;
goto exit_free;
}
fsize = stat.size;
#else
if (fp != NULL) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
fsize = fp->f_inode->i_size;
#endif
}
#endif
buf = (char *)kzalloc(fsize + 1, GFP_KERNEL);
if(NULL == buf) {
printk("ovt tcm csv parser: %s: kzalloc %d bytes failed.\n", __func__, fsize);
ret = -ESRCH;
goto exit_free;
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 14, 0)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
read_ret = kernel_read(fp, pos, buf, fsize);
#else
read_ret = vfs_read(fp, buf, fsize, &pos);
set_fs(org_fs);
#endif
#else
read_ret = kernel_read(fp, buf, fsize, &pos);
#endif
if (read_ret >= 0) {
buf[fsize] = '\0';
ptr = buf;
ptr = strstr(ptr, target_name);
if (ptr == NULL) {
printk("ovt tcm csv parser: %s: load %s failed 1!\n", __func__,target_name);
ret = -EINTR;
goto exit_free;
}
// walk thru this line
goto_next_line(&ptr);
if ((NULL == ptr) || (0 == strlen(ptr))) {
printk("ovt tcm csv parser: %s: load %s failed 2!\n", __func__,target_name);
ret = -EIO;
goto exit_free;
}
//analyze the data
if (data) {
parse_valid_data(buf, fsize, ptr, data, rows);
print_data(target_name, data, rows, columns);
}else{
printk("ovt tcm csv parser: %s: load %s failed 3!\n", __func__,target_name);
ret = -EINTR;
goto exit_free;
}
}
else {
printk("ovt tcm csv parser: %s: ret=%d,read_ret=%d, buf=%p, fsize=%d\n", __func__, ret, read_ret, buf, fsize);
ret = -ENXIO;
goto exit_free;
}
ret = 0;
exit_free:
printk("ovt tcm csv parser: %s exit free\n", __func__);
if(buf) {
printk("ovt tcm csv parser: kfree buf\n");
kfree(buf);
buf = NULL;
}
if (!IS_ERR_OR_NULL(fp)) { //fp open fail not means fp is NULL, so free fp may cause Uncertainty
printk("ovt tcm csv parser: filp close\n");
filp_close(fp, NULL);
fp = NULL;
}
return ret;
}
void ovt_tcm_store_to_buf(char *buffer, char* format, ...)
{
va_list args;
char buf[TMP_STRING_LEN_FOR_CSV] = {0};
static int count = 0;
if (buffer == NULL) {
count = 0;
return;
}
va_start(args, format);
vsnprintf(buf, TMP_STRING_LEN_FOR_CSV, format, args);
va_end(args);
if (count + strlen(buf) + 2 > MAX_BUFFER_SIZE_FOR_CSV) {
pr_err("exceed the max buffer size\n");
count = 0;
return;
}
memcpy(buffer + count, buf, strlen(buf));
count += strlen(buf);
*(buffer + count) = '\n';
count++;
}
void ovt_tcm_store_to_file(struct file *fp, char* format, ...)
{
va_list args;
char buf[TMP_STRING_LEN_FOR_CSV] = {0};
// mm_segment_t fs;
loff_t pos;
// struct file *fp;
va_start(args, format);
vsnprintf(buf, TMP_STRING_LEN_FOR_CSV, format, args);
va_end(args);
// fp = filp_open(file_path, O_RDWR | O_CREAT, 0666);
// if (IS_ERR(fp)) {
// printk("ovt tcm create file error\n");
// return;
// }
// fs = get_fs();
// set_fs(KERNEL_DS);
buf[TMP_STRING_LEN_FOR_CSV - 1] = 0;
pos = fp->f_pos;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 14, 0)
vfs_write(fp, buf, strlen(buf), &pos);
#else
kernel_write(fp, g_testing_output_buf, strlen(g_testing_output_buf), &pos);
#endif
fp->f_pos = pos;
// set_fs(fs);
// filp_close(fp, NULL);
return;
}