lineage_kernel_xcoverpro/drivers/sensorhub/ssp_sensor_dump.c

156 lines
3.9 KiB
C
Executable File

/*
* Copyright (C) 2016, Samsung Electronics Co. Ltd. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/slab.h>
#include "ssp_sensor_dump.h"
#include "ssp_cmd_define.h"
#include "ssp_comm.h"
static bool is_support_registerdump(int sensor_type)
{
int types[] = SENSOR_DUMP_SENSOR_LIST;
int list_len = (int)(sizeof(types) / sizeof(types[0]));
int i, ret = false;
for (i = 0; i < list_len ; i++) {
if (types[i] == sensor_type) {
ret = true;
break;
}
}
return ret;
}
static int store_sensor_dump(struct ssp_data *data, int sensor_type, u16 length, u8 *buf)
{
#ifdef SENSOR_DUMP_FILE_STORE
mm_segment_t old_fs;
struct file *dump_filp = NULL;
char file_name[SENSOR_DUMP_FILE_LENGTH] = {0,};
#endif
char *contents;
int ret = SUCCESS;
int i = 0;
int dump_len = sensor_dump_length(length);
char tmp_ch;
pr_info("[SSP] %s - type %d, length %d\n", __func__, sensor_type, length);
/*make file contents*/
contents = (char *)kzalloc(dump_len, GFP_KERNEL);
for (i = 0; i < length; i++) {
tmp_ch = ((i % NUM_LINE_ITEM == NUM_LINE_ITEM - 1) || (i - 1 == length)) ? '\n' : ' ';
snprintf(contents + i * LENGTH_1BYTE_HEXA_WITH_BLANK, dump_len - i * LENGTH_1BYTE_HEXA_WITH_BLANK,
"%02x%c", buf[i], tmp_ch);
}
if (data->sensor_dump[sensor_type] != NULL) {
kfree(data->sensor_dump[sensor_type]);
data->sensor_dump[sensor_type] = NULL;
}
data->sensor_dump[sensor_type] = contents;
#ifdef SENSOR_DUMP_FILE_STORE
old_fs = get_fs();
set_fs(KERNEL_DS);
/*make file name*/
snprintf(file_name, SENSOR_DUMP_FILE_LENGTH, "%s%d.txt", SENSOR_DUMP_PATH, sensor_type);
dump_filp = filp_open(file_name,
O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, 0640);
if (IS_ERR(dump_filp)) {
pr_err("[SSP] %s - Can't open dump file %d \n", __func__, sensor_type);
set_fs(old_fs);
ret = PTR_ERR(dump_filp);
return ret;
}
ret = vfs_write(dump_filp, data->sensor_dump[sensor_type], dump_len, &dump_filp->f_pos);
if (ret < 0) {
pr_err("[SSP] %s - Can't write the dump data to file\n", __func__);
ret = -EIO;
}
filp_close(dump_filp, current->files);
set_fs(old_fs);
#endif
return ret;
}
int send_sensor_dump_command(struct ssp_data *data, u8 sensor_type)
{
int ret = SUCCESS;
char *buffer = NULL;
int buffer_length = 0;
if (sensor_type >= SENSOR_TYPE_MAX) {
ssp_errf("invalid sensor type %d\n", sensor_type);
return -EINVAL;
} else if (!(data->sensor_probe_state & (1ULL << sensor_type))) {
ssp_errf("%u is not connected(0x%llx)\n", sensor_type, data->sensor_probe_state);
return -EINVAL;
}
if (!is_support_registerdump(sensor_type)) {
ssp_errf("unsupported sensor type %u\n", sensor_type);
return -EINVAL;
}
ret = ssp_send_command(data, CMD_GETVALUE, sensor_type, SENSOR_REGISTER_DUMP, 1000, NULL, 0,
&buffer, &buffer_length);
if (ret != SUCCESS) {
ssp_errf("ssp_send_command Fail %d", ret);
if (buffer != NULL) {
kfree(buffer);
}
return ret;
}
if (buffer == NULL) {
ssp_errf("buffer is null");
return -EINVAL;
}
ssp_infof("(%u)\n", sensor_type);
ret = store_sensor_dump(data, sensor_type, buffer_length, buffer);
kfree(buffer);
return ret;
}
int send_all_sensor_dump_command(struct ssp_data *data)
{
int types[] = SENSOR_DUMP_SENSOR_LIST;
int i, ret = SUCCESS;
for (i = 0; i < sizeof(types) / sizeof(types[0]); i++) {
int temp;
if ((temp = send_sensor_dump_command(data, types[i])) != SUCCESS) {
ret = temp;
}
}
return ret;
}