You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
770 lines
24 KiB
770 lines
24 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
|
|
* Description: drv adec
|
|
* Author: Audio
|
|
* Create: 2012-05-30
|
|
*/
|
|
|
|
#include "drv_adec_debug.h"
|
|
|
|
#include "osal_ext.h"
|
|
#include "drv_base_ext.h"
|
|
#include "drv_dev_ext.h"
|
|
#include "drv_adsp_ext.h"
|
|
#include "drv_adec_ext.h"
|
|
#include "drv_ioctl_adec.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
#define ADEC_NAME "SOC_ADEC"
|
|
#define ADEC_PROC_NAME_LEN 16
|
|
#define ADEC_PERCENTAGE 100
|
|
#define ADEC_PROC_TITLE_LINE_LENGTH 72
|
|
|
|
typedef struct {
|
|
td_u32 id;
|
|
adec_proc_item *proc_addr;
|
|
ext_audio_buffer proc_buf;
|
|
struct osal_list_head list;
|
|
} adec_instance;
|
|
|
|
static OSAL_LIST_HEAD(g_adec_list);
|
|
static osal_semaphore g_adec_mutex = {TD_NULL};
|
|
|
|
static td_void adec_unreg_proc(const adec_instance *adec);
|
|
static td_void adec_reg_proc(const adec_instance *adec);
|
|
|
|
static adec_instance *adec_find_by_id(td_u32 id)
|
|
{
|
|
adec_instance *adec = TD_NULL;
|
|
|
|
osal_list_for_each_entry(adec, &g_adec_list, list) {
|
|
if (adec->id == id) {
|
|
return adec;
|
|
}
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
static inline td_u32 adec_find_free_id(td_void)
|
|
{
|
|
td_u32 id;
|
|
|
|
for (id = 0; id < ADEC_INSTANCE_MAXNUM; id++) {
|
|
if (adec_find_by_id(id) == TD_NULL) {
|
|
return id;
|
|
}
|
|
}
|
|
|
|
return ADEC_INSTANCE_MAXNUM;
|
|
}
|
|
|
|
static td_void adec_destroy_instance(adec_instance *adec)
|
|
{
|
|
osal_list_del(&adec->list);
|
|
osal_kfree(adec);
|
|
}
|
|
|
|
static adec_instance *adec_create_instance(td_void)
|
|
{
|
|
td_u32 id;
|
|
td_s32 ret;
|
|
adec_instance *adec = TD_NULL;
|
|
|
|
id = adec_find_free_id();
|
|
if (id >= ADEC_INSTANCE_MAXNUM) {
|
|
soc_log_err("adec_find_free_id failed\n");
|
|
return TD_NULL;
|
|
}
|
|
|
|
adec = (adec_instance *)osal_kmalloc(sizeof(*adec), OSAL_GFP_KERNEL);
|
|
if (adec == TD_NULL) {
|
|
soc_log_err("osal_kmalloc adec_instance failed\n");
|
|
return TD_NULL;
|
|
}
|
|
|
|
ret = memset_s(adec, sizeof(*adec), 0, sizeof(*adec));
|
|
if (ret != EOK) {
|
|
soc_log_err("call memset_s failed(0x%x)\n", ret);
|
|
osal_kfree(adec);
|
|
return TD_NULL;
|
|
}
|
|
|
|
adec->id = id;
|
|
osal_list_add(&adec->list, &g_adec_list);
|
|
|
|
return adec;
|
|
}
|
|
|
|
static adsp_export_func *adec_get_audio_mem_func(td_void)
|
|
{
|
|
td_s32 ret;
|
|
adsp_export_func *mem_func = TD_NULL;
|
|
|
|
ret = osal_exportfunc_get(SOC_ID_ADSP, (td_void **)&mem_func);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_fatal("get audio mem function failed(0x%x)\n", ret);
|
|
return TD_NULL;
|
|
}
|
|
|
|
if ((mem_func == TD_NULL) ||
|
|
(mem_func->smmu_alloc == TD_NULL) ||
|
|
(mem_func->smmu_release == TD_NULL)) {
|
|
soc_log_fatal("audio mem function is invalid\n");
|
|
return TD_NULL;
|
|
}
|
|
|
|
return mem_func;
|
|
}
|
|
|
|
static td_void adec_free_proc_buf(ext_audio_buffer *buf)
|
|
{
|
|
td_s32 ret;
|
|
adsp_export_func *mem_func = adec_get_audio_mem_func();
|
|
if (mem_func == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
if (buf->fd >= 0) {
|
|
ret = osal_mem_close_fd(buf->fd);
|
|
if (ret != 0) {
|
|
soc_err_print_s32(buf->fd);
|
|
soc_err_print_call_fun_err(osal_mem_close_fd, ret);
|
|
}
|
|
|
|
buf->fd = -1;
|
|
}
|
|
|
|
if (buf->virt_addr != TD_NULL) {
|
|
mem_func->smmu_release(buf);
|
|
buf->virt_addr = TD_NULL;
|
|
}
|
|
}
|
|
|
|
static td_s32 adec_alloc_proc_buf(td_char *name, td_u32 name_len, ext_audio_buffer *buf)
|
|
{
|
|
td_s32 ret;
|
|
adsp_export_func *mem_func = adec_get_audio_mem_func();
|
|
if (mem_func == TD_NULL) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
TD_UNUSED(name_len);
|
|
|
|
ret = mem_func->smmu_alloc(name, sizeof(adec_proc_item), TD_FALSE, buf);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call smmu_alloc failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
if (buf->dma_buf == TD_NULL) {
|
|
goto out;
|
|
}
|
|
|
|
buf->fd = osal_mem_create_fd(buf->dma_buf, OSAL_O_CLOEXEC);
|
|
if (buf->fd < 0) {
|
|
soc_log_err("call osal_mem_create_fd failed\n");
|
|
goto out;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
out:
|
|
mem_func->smmu_release(buf);
|
|
return SOC_ERR_ADEC_ALLOC_MEM_FAILED;
|
|
}
|
|
|
|
static td_s32 adec_proc_buf_init(adec_instance *adec)
|
|
{
|
|
td_s32 ret;
|
|
td_char name[ADEC_PROC_NAME_LEN];
|
|
|
|
ret = snprintf_s(name, sizeof(name), sizeof(name) - 1, "adec_proc%02d", adec->id);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return ret;
|
|
}
|
|
|
|
adec->proc_addr = TD_NULL;
|
|
ret = adec_alloc_proc_buf(name, sizeof(name), &adec->proc_buf);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(adec_alloc_proc_buf, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (adec->proc_buf.virt_addr == TD_NULL) {
|
|
adec_free_proc_buf(&adec->proc_buf);
|
|
return SOC_ERR_ADEC_ALLOC_MEM_FAILED;
|
|
}
|
|
|
|
ret = memset_s(adec->proc_buf.virt_addr, adec->proc_buf.size,
|
|
0, sizeof(adec_proc_item));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memset_s, ret);
|
|
adec_free_proc_buf(&adec->proc_buf);
|
|
return ret;
|
|
}
|
|
|
|
adec->proc_addr = (adec_proc_item *)adec->proc_buf.virt_addr;
|
|
adec->proc_addr->pcm_ctrl_state = ADEC_CMD_CTRL_STOP;
|
|
adec->proc_addr->es_ctrl_state = ADEC_CMD_CTRL_STOP;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void adec_proc_buf_deinit(adec_instance *adec)
|
|
{
|
|
if (adec->proc_addr == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
adec_free_proc_buf(&adec->proc_buf);
|
|
adec->proc_addr = TD_NULL;
|
|
}
|
|
|
|
static td_s32 adec_ioctl_proc_init(td_void *private_data, td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
adec_instance *adec = TD_NULL;
|
|
adec_proc_param* proc_param = (adec_proc_param *)arg;
|
|
|
|
if ((private_data == TD_NULL) || (arg == TD_NULL)) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
adec = adec_create_instance();
|
|
if (adec == TD_NULL) {
|
|
soc_log_err("call adec_create_instance failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = adec_proc_buf_init(adec);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call adec_proc_buf_init failed(0x%x)\n", ret);
|
|
adec_destroy_instance(adec);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
adec_reg_proc(adec);
|
|
|
|
*((adec_instance **)private_data) = adec;
|
|
proc_param->id = adec->id;
|
|
proc_param->map_fd = adec->proc_buf.fd;
|
|
proc_param->proc_phys_addr = adec->proc_buf.phys_addr;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 adec_ioctl_proc_deinit(td_void *private_data)
|
|
{
|
|
adec_instance *adec = TD_NULL;
|
|
|
|
if (private_data == TD_NULL) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
adec = *((adec_instance **)private_data);
|
|
if (adec == TD_NULL) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
adec_unreg_proc(adec);
|
|
adec_proc_buf_deinit(adec);
|
|
adec_destroy_instance(adec);
|
|
|
|
*((adec_instance **)private_data) = TD_NULL;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 adec_drv_open(td_void *private_data)
|
|
{
|
|
if (private_data == TD_NULL) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
*((adec_instance **)private_data) = TD_NULL;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 adec_drv_release(td_void *private_data)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_sem_down_interruptible(&g_adec_mutex);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("lock g_adec_mutex failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = adec_ioctl_proc_deinit(private_data);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("adec_ioctl_proc_deinit failed!\n");
|
|
}
|
|
|
|
osal_sem_up(&g_adec_mutex);
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 adec_process_cmd(td_void *private_data, td_u32 cmd, td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
|
|
switch (cmd) {
|
|
case DRV_ADEC_PROC_INIT: {
|
|
ret = adec_ioctl_proc_init(private_data, arg);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("adec_ioctl_proc_init failed!\n");
|
|
}
|
|
break;
|
|
}
|
|
|
|
case DRV_ADEC_PROC_EXIT: {
|
|
ret = adec_ioctl_proc_deinit(private_data);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("adec_ioctl_proc_deinit failed!\n");
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
ret = SOC_ERR_ADEC_INVALID_PARA;
|
|
soc_log_err("invalid cmd!\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 adec_drv_ioctl(td_u32 cmd, td_void *arg, td_void *private_data)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_sem_down_interruptible(&g_adec_mutex);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("lock g_adec_mutex failed(0x%x)\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = adec_process_cmd(private_data, cmd, arg);
|
|
|
|
osal_sem_up(&g_adec_mutex);
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 adec_proc_how_help(td_u32 argc, td_char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
|
|
{
|
|
adec_instance *adec = (adec_instance *)private;
|
|
if (adec == TD_NULL) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
osal_proc_echo("=======================================adec=======================================\n");
|
|
osal_proc_echo("%-82s\n", "echo command para path explanation ");
|
|
osal_proc_echo("%-82s\n", "echo save_es start > /proc/msp/adec00 start save es data before audio decode");
|
|
osal_proc_echo("%-82s\n", "echo save_es stop > /proc/msp/adec00 stop save es data before audio decode");
|
|
osal_proc_echo("%-82s\n", "echo save_pcm start > /proc/msp/adec00 start save pcm data after audio decode");
|
|
osal_proc_echo("%-82s\n", "echo save_pcm stop > /proc/msp/adec00 stop save pcm data after audio decode");
|
|
osal_proc_echo("==================================================================================\n");
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static const struct {
|
|
td_u32 adec_format;
|
|
const td_char *format;
|
|
} g_adec_format_map[] = {
|
|
{EXT_ACODEC_ID_PCM, "pcm"},
|
|
{EXT_ACODEC_ID_MP2, "mp2"},
|
|
{EXT_ACODEC_ID_MP3, "mp3"},
|
|
{EXT_ACODEC_ID_AAC, "aac"},
|
|
{EXT_ACODEC_ID_COOK, "cook"},
|
|
{EXT_ACODEC_ID_DRA, "dra"},
|
|
{EXT_ACODEC_ID_DOLBY_PLUS, "ddp"},
|
|
{EXT_ACODEC_ID_DOLBY_TRUEHD, "truehd"},
|
|
{EXT_ACODEC_ID_DTSHD, "dtshd"},
|
|
{EXT_ACODEC_ID_DTSM6, "dtsm6"},
|
|
};
|
|
|
|
static const td_char *adec_stream_format_name(td_u32 format)
|
|
{
|
|
td_u32 i;
|
|
td_u32 num = sizeof(g_adec_format_map) / sizeof(g_adec_format_map[0]);
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (format == g_adec_format_map[i].adec_format) {
|
|
return g_adec_format_map[i].format;
|
|
}
|
|
}
|
|
|
|
return "unknow";
|
|
}
|
|
|
|
static td_void adec_read_proc_decoder_info(td_void *file, const adec_proc_item *adec_proc)
|
|
{
|
|
osal_seq_printf(file, "%-33s:%-37s|\n",
|
|
"state", (adec_proc->adec_work_enable == TD_TRUE) ? "start" : "stop");
|
|
osal_seq_printf(file, "%-33s:0x%-35x|\n", "codec_id", adec_proc->codec_id);
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "decoder_name", adec_proc->codec_type);
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "description", adec_proc->codec_description);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "decode_thread_id", adec_proc->thread_id);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "volume", adec_proc->volume);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "sample_rate", adec_proc->sample_rate);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "bit_depth", adec_proc->bit_width);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "channels", adec_proc->out_channels);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "pcm_samples", adec_proc->pcm_samples_per_frame);
|
|
osal_seq_printf(file, "%-33s:0x%-35x|\n", "bits_byte", adec_proc->bits_out_bytes_per_frame);
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "stream_format", adec_stream_format_name(adec_proc->codec_id));
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "packet_decoder", (adec_proc->fmt == TD_TRUE) ? "yes" : "no");
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "enter_decode_entry_times", adec_proc->dbg_decode_entry_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "try_decode_times", adec_proc->dbg_try_decode_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "frame_num_total_cnt", adec_proc->framn_nm);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "frame_num_error_cnt", adec_proc->err_frame_num);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "frame_unsupport_num", adec_proc->codec_unsupport_num);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "stream_corrupt_num", adec_proc->stream_corrupt_num);
|
|
}
|
|
|
|
static td_void adec_read_proc_input_buf(td_void *file, const adec_proc_item *adec_proc)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 data_size = 0;
|
|
td_u32 buf_percent = 0;
|
|
td_char tmp[ADEC_PROC_TITLE_LINE_LENGTH];
|
|
|
|
if (adec_proc->buf_size != 0) {
|
|
if (adec_proc->buf_write >= adec_proc->buf_read) {
|
|
data_size = adec_proc->buf_write - adec_proc->buf_read;
|
|
} else {
|
|
data_size = adec_proc->buf_size - adec_proc->buf_read + adec_proc->buf_write;
|
|
}
|
|
buf_percent = data_size * ADEC_PERCENTAGE / adec_proc->buf_size;
|
|
}
|
|
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "stream_buf_total_bytes", adec_proc->buf_size);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "stream_buf_use_bytes", data_size);
|
|
ret = snprintf_s(tmp, sizeof(tmp), sizeof(tmp) - 1, "%u%%", buf_percent);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return;
|
|
}
|
|
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "stream_buf_percent", tmp);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "stream_buf_read_pos", adec_proc->buf_read);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "stream_buf_write_pos", adec_proc->buf_write);
|
|
}
|
|
|
|
static td_void adec_read_proc_output_buf(td_void *file, const adec_proc_item *adec_proc)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 frame_percent = 0;
|
|
td_u32 frame_num = 0;
|
|
td_char tmp[ADEC_PROC_TITLE_LINE_LENGTH];
|
|
|
|
if (adec_proc->frame_size != 0) {
|
|
if (adec_proc->frame_write >= adec_proc->frame_read) {
|
|
frame_num = adec_proc->frame_write - adec_proc->frame_read;
|
|
} else {
|
|
frame_num = adec_proc->frame_size - adec_proc->frame_read + adec_proc->frame_write;
|
|
}
|
|
|
|
frame_percent = frame_num * ADEC_PERCENTAGE / adec_proc->frame_size;
|
|
}
|
|
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "out_frame_buf_total_num", adec_proc->frame_size);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "out_frame_buf_use_num", frame_num);
|
|
ret = snprintf_s(tmp, sizeof(tmp), sizeof(tmp) - 1, "%u%%", frame_percent);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return;
|
|
}
|
|
|
|
osal_seq_printf(file, "%-33s:%-37s|\n", "out_frame_buf_percent", tmp);
|
|
}
|
|
|
|
static td_void adec_read_proc_dbg_count(td_void *file, const adec_proc_item *adec_proc)
|
|
{
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "get_buffer_try_cnt", adec_proc->dbg_get_buf_count_try);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "get_buffer_ok_cnt", adec_proc->dbg_get_buf_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "put_buffer_try_cnt", adec_proc->dbg_put_buf_count_try);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "put_buffer_ok_cnt", adec_proc->dbg_put_buf_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "send_stream_try_cnt", adec_proc->dbg_send_straem_count_try);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "send_stream_ok_cnt", adec_proc->dbg_send_straem_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "receive_frame_try_cnt", adec_proc->dbg_receive_frame_count_try);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "receive_frame_ok_cnt", adec_proc->dbg_receive_frame_count);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "pts_lost_num", adec_proc->pts_lost);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n",
|
|
"decode_thread_exec_time_out_cnt", adec_proc->thread_exe_time_out_cnt);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n",
|
|
"decode_thread_sched_time_out_cnt", adec_proc->thread_sched_time_out_cnt);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n",
|
|
"decode_thread_sleep_time_ms", adec_proc->adec_system_sleep_time);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n",
|
|
"codec_exec_time_out_cnt", adec_proc->codec_exe_time_out_cnt);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n",
|
|
"codec_sched_time_out_cnt", adec_proc->codec_sched_time_out_cnt);
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "adec_delay_ms", adec_proc->adec_delay_ms);
|
|
osal_seq_printf(file, "%-33s:%-37s|\n",
|
|
"set_eos_flag_set", ((adec_proc->set_eos) == TD_TRUE) ? "true" : "false");
|
|
osal_seq_printf(file, "%-33s:%-37s|\n",
|
|
"set_eos_flag_report", ((adec_proc->report_eos) == TD_TRUE) ? "true" : "false");
|
|
osal_seq_printf(file, "%-33s:%-37s|\n",
|
|
"report_eos_event", ((adec_proc->report_eos_event) == TD_TRUE) ? "true" : "false");
|
|
osal_seq_printf(file, "%-33s:%-37d|\n", "not_enough_buf_cnt", adec_proc->not_enough_buf_cnt);
|
|
}
|
|
|
|
static td_s32 adec_read_proc(td_void *file, td_void *private)
|
|
{
|
|
adec_instance *adec = (adec_instance *)private;
|
|
if (adec == TD_NULL) {
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
if (adec->proc_addr == TD_NULL) {
|
|
osal_seq_printf(file, " adec[%02d] proc not init\n", adec->id);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
osal_seq_printf(file, "[adec]%s\n", VERSION_STRING);
|
|
osal_seq_printf(file, "------------------------------adec%02d state", adec->id);
|
|
osal_seq_printf(file, "------------------------------\n");
|
|
|
|
adec_read_proc_decoder_info(file, adec->proc_addr);
|
|
adec_read_proc_input_buf(file, adec->proc_addr);
|
|
adec_read_proc_output_buf(file, adec->proc_addr);
|
|
adec_read_proc_dbg_count(file, adec->proc_addr);
|
|
osal_seq_printf(file, "========================================================================\n");
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 adec_write_proc_save_es(td_u32 argc, td_char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
td_s32 ret;
|
|
adec_proc_item *adec_proc = TD_NULL;
|
|
adec_instance *adec = (adec_instance *)private;
|
|
if ((adec == TD_NULL) || (adec->proc_addr == TD_NULL)) {
|
|
soc_log_err("adec proc not init\n");
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
adec_proc = adec->proc_addr;
|
|
|
|
if (osal_strncmp("save_es", argv[0], strlen(argv[0])) != 0) {
|
|
return SOC_ERR_ADEC_INVALID_PARA;
|
|
}
|
|
|
|
if (osal_strncmp("start", argv[1], strlen(argv[1])) == 0) {
|
|
ret = snprintf_s(adec_proc->es_file_path, sizeof(adec_proc->es_file_path),
|
|
sizeof(adec_proc->es_file_path) - 1, "/mnt/adec%02d.es", adec->id);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (adec_proc->es_ctrl_state != ADEC_CMD_CTRL_START) {
|
|
adec_proc->save_es_cnt++;
|
|
adec_proc->es_ctrl_state = ADEC_CMD_CTRL_START;
|
|
osal_printk("started saving adec es data to %s\n", adec_proc->es_file_path);
|
|
} else {
|
|
osal_printk("started saving adec es data already.\n");
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (osal_strncmp("stop", argv[1], strlen(argv[1])) == 0) {
|
|
osal_printk("finished saving adec es data.\n");
|
|
adec_proc->es_ctrl_state = ADEC_CMD_CTRL_STOP;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
return SOC_ERR_ADEC_INVALID_PARA;
|
|
}
|
|
|
|
static td_s32 adec_write_proc_save_pcm(td_u32 argc, td_char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
|
|
{
|
|
td_s32 ret;
|
|
adec_proc_item *adec_proc = TD_NULL;
|
|
adec_instance *adec_pcm = (adec_instance *)private;
|
|
if ((adec_pcm == TD_NULL) || (adec_pcm->proc_addr == TD_NULL)) {
|
|
soc_log_err("ADEC PCM PROC not init\n");
|
|
return SOC_ERR_ADEC_NULL_PTR;
|
|
}
|
|
|
|
adec_proc = adec_pcm->proc_addr;
|
|
|
|
if (osal_strncmp("save_pcm", argv[0], strlen(argv[0])) != 0) {
|
|
return SOC_ERR_ADEC_INVALID_PARA;
|
|
}
|
|
|
|
if (osal_strncmp("start", argv[1], strlen(argv[1])) == 0) {
|
|
ret = snprintf_s(adec_proc->pcm_file_path, sizeof(adec_proc->pcm_file_path),
|
|
sizeof(adec_proc->pcm_file_path) - 1, "/mnt/adec%02d.pcm", adec_pcm->id);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (adec_proc->pcm_ctrl_state != ADEC_CMD_CTRL_START) {
|
|
adec_proc->save_pcm_cnt++;
|
|
adec_proc->pcm_ctrl_state = ADEC_CMD_CTRL_START;
|
|
osal_printk("started saving adec pcm data to %s\n", adec_proc->pcm_file_path);
|
|
} else {
|
|
osal_printk("started saving adec pcm data already.\n");
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (osal_strncmp("stop", argv[1], strlen(argv[1])) == 0) {
|
|
osal_printk("finished saving adec pcm data.\n");
|
|
adec_proc->pcm_ctrl_state = ADEC_CMD_CTRL_STOP;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
return SOC_ERR_ADEC_INVALID_PARA;
|
|
}
|
|
|
|
static osal_proc_cmd g_adec_proc_cmd[] = {
|
|
{ "save_es", adec_write_proc_save_es },
|
|
{ "save_pcm", adec_write_proc_save_pcm },
|
|
{ "help", adec_proc_how_help },
|
|
};
|
|
|
|
static td_void adec_unreg_proc(const adec_instance *adec)
|
|
{
|
|
td_s32 ret;
|
|
td_char buf[ADEC_PROC_NAME_LEN];
|
|
|
|
ret = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "adec%02d", adec->id);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return;
|
|
}
|
|
|
|
osal_proc_remove(buf, strlen(buf));
|
|
}
|
|
|
|
static td_void adec_reg_proc(const adec_instance *adec)
|
|
{
|
|
td_s32 ret;
|
|
td_char buf[ADEC_PROC_NAME_LEN];
|
|
osal_proc_entry *item = TD_NULL;
|
|
|
|
/* create proc */
|
|
ret = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "adec%02d", adec->id);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return;
|
|
}
|
|
|
|
item = osal_proc_add(buf, strlen(buf));
|
|
if (item == TD_NULL) {
|
|
soc_log_err("call osal_proc_add failed\n");
|
|
return;
|
|
}
|
|
|
|
/* set functions */
|
|
item->read = adec_read_proc;
|
|
item->cmd_list = g_adec_proc_cmd;
|
|
item->cmd_cnt = sizeof(g_adec_proc_cmd) / sizeof(g_adec_proc_cmd[0]);
|
|
item->private = (td_void *)adec;
|
|
|
|
soc_log_info("create adec proc entry OK!\n");
|
|
}
|
|
|
|
static osal_ioctl_cmd g_adec_cmd_list[] = {
|
|
{ DRV_ADEC_PROC_INIT, adec_drv_ioctl },
|
|
{ DRV_ADEC_PROC_EXIT, adec_drv_ioctl },
|
|
};
|
|
|
|
static osal_fileops g_adec_fops = {
|
|
.open = adec_drv_open,
|
|
.write = TD_NULL,
|
|
.llseek = TD_NULL,
|
|
.release = adec_drv_release,
|
|
.poll = TD_NULL,
|
|
.mmap = TD_NULL,
|
|
.cmd_list = g_adec_cmd_list,
|
|
.cmd_cnt = sizeof(g_adec_cmd_list) / sizeof(g_adec_cmd_list[0]),
|
|
};
|
|
|
|
static osal_dev g_adec_dev = {
|
|
.name = SOC_DEV_ADEC_NAME,
|
|
.minor = SOC_DEV_ADEC_MINOR,
|
|
.fops = &g_adec_fops,
|
|
.pmops = TD_NULL,
|
|
.dev = TD_NULL,
|
|
};
|
|
|
|
td_s32 adec_drv_mod_init(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_sem_init(&g_adec_mutex, 1);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call osal_sem_init failed\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_exportfunc_register(SOC_ID_ADEC, ADEC_NAME, TD_NULL);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call osal_exportfunc_register failed(0x%x)\n", ret);
|
|
goto out0;
|
|
}
|
|
|
|
ret = osal_dev_register(&g_adec_dev);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_fatal("call osal_dev_register failed(0x%x)\n", ret);
|
|
goto out1;
|
|
}
|
|
|
|
#ifdef MODULE
|
|
soc_print("Load soc_adec.ko success. \t(%s)\n", VERSION_STRING);
|
|
#endif
|
|
|
|
return TD_SUCCESS;
|
|
|
|
out1:
|
|
osal_exportfunc_unregister(SOC_ID_ADEC);
|
|
|
|
out0:
|
|
osal_sem_destroy(&g_adec_mutex);
|
|
return ret;
|
|
}
|
|
|
|
td_void adec_drv_mod_exit(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
osal_dev_unregister(&g_adec_dev);
|
|
ret = osal_exportfunc_unregister(SOC_ID_ADEC);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_exportfunc_unregister, ret);
|
|
}
|
|
|
|
osal_sem_destroy(&g_adec_mutex);
|
|
}
|
|
|
|
#ifdef MODULE
|
|
module_init(adec_drv_mod_init);
|
|
module_exit(adec_drv_mod_exit);
|
|
#else
|
|
|
|
#ifndef CONFIG_SOCT_RECOVERY_SUPPORT
|
|
soc_initcall(adec_drv_mod_init);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
MODULE_AUTHOR("HUANGLONG");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("ADEC DRIVER");
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|