167 lines
3.9 KiB
C
167 lines
3.9 KiB
C
|
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/rtc.h>
|
||
|
#include "ssp.h"
|
||
|
#include "ssp_dev.h"
|
||
|
#include "ssp_comm.h"
|
||
|
#include "ssp_dump.h"
|
||
|
#include "ssp_firmware.h"
|
||
|
#include "../staging/nanohub/chub.h"
|
||
|
#include "../staging/nanohub/chub_dbg.h"
|
||
|
|
||
|
int sensorhub_comms_read(void *ssp_data, u8 *buf, int length, int timeout)
|
||
|
{
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
return contexthub_ipc_read(ipc, buf, length, timeout);
|
||
|
}
|
||
|
|
||
|
int sensorhub_comms_write(void *ssp_data, u8 *buf, int length, int timeout)
|
||
|
{
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
int ret = contexthub_ipc_write(ipc, buf, length, timeout);
|
||
|
if (!ret) {
|
||
|
ret = ERROR;
|
||
|
pr_err("%s : write fail\n", __func__);
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int sensorhub_reset(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
int dump = (data->reset_type < RESET_TYPE_MAX) ? CHUB_ERR_MAX + data->reset_type : 0;
|
||
|
ssp_infof("err type %d, dump %d", data->reset_type, dump);
|
||
|
return contexthub_reset(ipc, 1, (1 << dump));
|
||
|
}
|
||
|
|
||
|
int sensorhub_firmware_download(void *ssp_data)
|
||
|
{
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
return contexthub_reset(ipc, 1, 0);
|
||
|
}
|
||
|
|
||
|
int sensorhub_shutdown(void *ssp_data)
|
||
|
{
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
int ret;
|
||
|
ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_SHUTDOWN);
|
||
|
if (ret)
|
||
|
ssp_errf("shutdonw fails, ret:%d\n", ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void *ssp_device_probe(struct device *dev)
|
||
|
{
|
||
|
return ssp_probe(dev);
|
||
|
}
|
||
|
|
||
|
void ssp_device_remove(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
ssp_remove(data);
|
||
|
}
|
||
|
|
||
|
void ssp_device_suspend(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
ssp_suspend(data);
|
||
|
}
|
||
|
|
||
|
void ssp_device_resume(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
ssp_resume(data);
|
||
|
}
|
||
|
|
||
|
void ssp_platform_init(void *ssp_data, void *platform_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
|
||
|
data->platform_data = platform_data;
|
||
|
}
|
||
|
|
||
|
void ssp_handle_recv_packet(void *ssp_data, char *packet, int packet_len)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
handle_packet(data, packet, packet_len);
|
||
|
}
|
||
|
|
||
|
void ssp_platform_start_refrsh_task(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
queue_refresh_task(data, 0);
|
||
|
}
|
||
|
|
||
|
void save_ram_dump(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
|
||
|
if (contexthub_get_token(ipc)) {
|
||
|
ssp_infof("get token, skip save dump");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ssp_infof("");
|
||
|
write_ssp_dump_file(data, (char *)ipc_get_base(IPC_REG_DUMP), ipc_get_chub_mem_size(), 0, 1);
|
||
|
contexthub_put_token(ipc);
|
||
|
}
|
||
|
|
||
|
int get_sensorhub_dump_size()
|
||
|
{
|
||
|
return ipc_get_chub_mem_size();
|
||
|
}
|
||
|
|
||
|
void *get_sensorhub_dump_address(void)
|
||
|
{
|
||
|
return ipc_get_base(IPC_REG_DUMP);
|
||
|
}
|
||
|
|
||
|
void ssp_dump_write_file(void *ssp_data, void *dump_data, int dump_size, int err_type)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
int i = 0;
|
||
|
int dump_type;
|
||
|
|
||
|
if (err_type == 0) {
|
||
|
if (data->reset_type < RESET_TYPE_MAX)
|
||
|
dump_type = DUMP_TYPE_BASE + data->reset_type;
|
||
|
else
|
||
|
dump_type = 0;
|
||
|
} else {
|
||
|
for (i = 0 ; i < CHUB_ERR_MAX ; i++) {
|
||
|
if (err_type & 1 << i) {
|
||
|
dump_type = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (i != CHUB_ERR_MAX)
|
||
|
write_ssp_dump_file(data, (char *)dump_data, dump_size, dump_type, 1);
|
||
|
}
|
||
|
|
||
|
bool is_sensorhub_working(void *ssp_data)
|
||
|
{
|
||
|
struct ssp_data *data = (struct ssp_data *)ssp_data;
|
||
|
struct contexthub_ipc_info *ipc = ((struct ssp_data *)ssp_data)->platform_data;
|
||
|
if (!work_busy(&data->work_reset) && atomic_read(&ipc->chub_status) == CHUB_ST_RUN && atomic_read(&ipc->in_reset) == 0)
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int ssp_download_firmware(void *ssp_data, struct device *dev, void *addr)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
return download_sensorhub_firmware(data, dev, addr);
|
||
|
}
|
||
|
|
||
|
void ssp_set_firmware_name(void *ssp_data, const char *fw_name)
|
||
|
{
|
||
|
struct ssp_data *data = ssp_data;
|
||
|
strcpy(data->fw_name, fw_name);
|
||
|
}
|