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.

2031 lines
59 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: sif drv
* Author: Audio
* Create: 2020-04-16
*/
#include "drv_sif.h"
#include "soc_log.h"
#include "osal_ext.h"
#include "soc_errno.h"
#include "soc_module.h"
#include "drv_sys_ext.h"
#include "linux/huanglong/securec.h"
#include "drv_sif_hal.h"
#include "drv_ioctl_sif.h"
#include "drv_sif_private.h"
#include "drv_sif_hal_v4_0.h"
#define SIGN_BIT 0x8000
#define REG_MAX_16BITS 0xffff
#define SIF_SAMPLE_FREQ 18432 /* 18.432M */
sif_drv_ctx g_sif_drv_dev = {0};
static td_s32 g_sif_suspend_flag = 0;
static td_s32 g_sif_resume_flag = 0;
static osal_atomic g_sif_open_cnt = {TD_NULL};
static osal_semaphore g_sif_mutex = {TD_NULL};
/**************************************************************************
addr value
0x02 0x00 set sample rate
0x09 0x05 set AAOS control and AAOS mode
0x80 0x08 set demulator mode:4.5_m_hz or 6.5_m_hz
0x00 0x00 set attributes relate to ASD:ASD atuo or system select
0x41 0x04 set mute ctl:mute override,left muted or right muted setting
***************************************************************************/
static td_s32 sif_get_carri_shift_value(td_u32 *shift_value);
static td_u32 sif_get_quality1(td_void);
static td_u32 sif_get_quality2(td_void);
static td_s32 sif_get_out_mode(ext_sif_aaos_mode *paaos_mode);
static td_s32 sif_set_over_mode(ext_sif_over_deviation over_mode);
static td_s32 sif_get_over_mode(ext_sif_over_deviation *over_mode);
static td_void sif_get_btsc_support(td_bool *support);
static td_s32 sif_suspend(td_void);
static td_s32 sif_resume(td_void);
td_void sif_proc_show_help(td_void)
{
osal_proc_echo("=============================================sif"
"================================================\n");
osal_proc_echo("echo command para path "
"explanation\n");
osal_proc_echo("echo syssel DK > /proc/msp/sif "
"set system select para(DK/BG/I/KOREA/BTSC/EIAJ)\n");
osal_proc_echo("echo overmode 50 > /proc/msp/sif "
"set over modulation para(50k/100k/200k/384k/540k)\n");
osal_proc_echo("echo ascs 1 > /proc/msp/sif "
"ascs on\n");
osal_proc_echo("echo ascs 0 > /proc/msp/sif "
"ascs off\n");
osal_proc_echo("==============================================="
"=================================================\n");
}
static td_u8 *sys_sel_to_str(td_void)
{
sif_sys_sel sys_sel = sif_hal_get_det_standard();
switch (sys_sel) {
case SIF_SYS_SEL_BG_FM:
return "BG_FM";
case SIF_SYS_SEL_BG_NICAM:
return "bg_nicam";
case SIF_SYS_SEL_L:
return "secam_l";
case SIF_SYS_SEL_I:
return "sys_i";
case SIF_SYS_SEL_DK1:
return "dk1";
case SIF_SYS_SEL_DK2:
return "dk2";
case SIF_SYS_SEL_DK3:
return "dk3";
case SIF_SYS_SEL_DK_NICAM:
return "nicam_dk";
case SIF_SYS_SEL_KOREA:
return "korea";
case SIF_SYS_SEL_EIAJ:
return "eiaj";
case SIF_SYS_SEL_BTSC:
return "btsc";
default:
return "sys_sel_no";
}
}
static td_u8 *en_asdctl45_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->asd45_ctl) {
case SIF_ASDCTL_45M_BTSC:
return "btsc";
case SIF_ASDCTL_45M_EIAJ:
return "eiaj";
case SIF_ASDCTL_45M_M_KOREA:
return "korea";
case SIF_ASDCTL_45M_PAL_SUM:
return "pal_sum";
default:
return "radio";
}
}
static td_u8 *en_asdctl65_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->asd65_ctl) {
case SIF_ASDCTL_65M_SECAM_L:
return "secam_l";
case SIF_ASDCTL_65M_DK:
return "DK";
default:
return "NONE";
}
}
static td_u8 *en_filter1_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->flt1) {
case SIF_DEMOD1_FILTER_50K:
return "50K";
case SIF_DEMOD1_FILTER_100K:
return "100K";
case SIF_DEMOD1_FILTER_384K:
return "384K";
case SIF_DEMOD1_FILTER_540K:
return "540K";
case SIF_DEMOD1_FILTER_200K:
return "200K";
case SIF_DEMOD1_FILTER_BUTT:
default:
return "";
}
}
static td_u8 *en_carri_status1_to_str(ext_sif_aaos_mode aaos_mode)
{
switch (aaos_mode) {
case EXT_SIF_AAOS_MODE_MONO:
return "mono";
case EXT_SIF_AAOS_MODE_STEREO:
return "stereo";
case EXT_SIF_AAOS_MODE_DUAL:
return "dual";
case EXT_SIF_AAOS_MODE_MONO_SAP:
return "mono_sap";
case EXT_SIF_AAOS_MODE_STEREO_SAP:
return "stereo_sap";
case EXT_SIF_AAOS_MODE_NICAM_MONO:
return "nicam_mono";
case EXT_SIF_AAOS_MODE_NICAM_STEREO:
return "nicam_stereo";
case EXT_SIF_AAOS_MODE_NICAM_DUAL:
return "nicam_dual";
case EXT_SIF_AAOS_MODE_NICAM_FM_MOMO:
return "nicam_fm_mono";
case EXT_SIF_AAOS_MODE_MAX:
default:
return "";
}
}
static td_u8 *deviation1_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->deviation1) {
case SIF_DEVIATION_50K:
return "50K";
case SIF_DEVIATION_100K:
return "100K";
case SIF_DEVIATION_384K:
return "384K";
case SIF_DEVIATION_540K:
return "540K";
case SIF_DEVIATION_200K:
return "200K";
case SIF_DEVIATION_BUTT:
default:
return "";
}
}
static td_u8 *en_dem_mode_to_str(sif_hal_attr *pdev_attr)
{
sif_hal_get_demulator_mode(&pdev_attr->demula_mode);
switch (pdev_attr->demula_mode) {
case SIF_DEMOD1_MODE_FM:
return "fm";
case SIF_DEMOD1_MODE_AM:
return "am";
case SIF_DEMOD1_MODE_BUTT:
default:
return "";
}
}
static td_u8 *en_out_to_str(sif_aaos_outmode output)
{
switch (output) {
case SIF_AAOS_OUTMODE_MONO:
return "mono";
case SIF_AAOS_OUTMODE_L_OR_R:
return "LR";
case SIF_AAOS_OUTMODE_A:
return "A";
case SIF_AAOS_OUTMODE_B:
return "B";
case SIF_AAOS_OUTMODE_BUTT:
default:
return "";
}
}
static td_u8 *en_ascs_mode_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->ascs_chg_mode) {
case SIF_ASCS_CHGMODE_NOT_AUTO:
return "no_auto";
case SIF_ASCS_CHGMODE_AFTER_RST:
return "aft_rst";
case SIF_ASCS_CHGMODE_AUTO:
return "auto";
case SIF_ASCS_CHGMODE_AUTO1:
return "auto1";
case SIF_ASCS_CHGMODE_BUTT:
default:
return "";
}
}
static td_u8 *en_ascs_ctl_to_str(const sif_hal_attr *pdev_attr)
{
switch (pdev_attr->ascs_ctl) {
case SIF_ASCS_MODE_DISABLE:
return "disable";
case SIF_ASCS_MODE_ONETIME:
return "one_time";
case SIF_ASCS_MODE_ALWAYS:
return "always";
case SIF_ASCS_MODE_ALWAYS1:
return "always1";
case SIF_ASCS_MODE_BUTT:
default:
return "";
}
}
static td_u8 *en_carri1_to_str(sif_hal_attr *pdev_attr)
{
td_u32 carri_freq = sif_hal_get_carri1_freq();
switch (carri_freq) {
case SIF_DEMOD1_45M_18432M:
return "4.5M";
case SIF_DEMOD1_55M_18432M:
return "5.5M";
case SIF_DEMOD1_60M_18432M:
return "6.0M";
case SIF_DEMOD1_65M_18432M:
return "6.5M";
default:
return "no_freq";
}
}
static td_u8 *en_carri2_to_str(sif_hal_attr *pdev_attr)
{
td_u32 carri_freq = sif_hal_get_carri12_freq();
switch (carri_freq) {
case SIF_DEMOD2_4_724212M_18432M:
return "4.724M";
case SIF_DEMOD2_57421875M_18432M:
return "5.742M";
case SIF_DEMOD2_585M_18432M:
return "5.85M";
case SIF_DEMOD2_62578125M_18432M:
return "6.26M";
case SIF_DEMOD2_6552M_18432M:
return "6.55M";
case SIF_DEMOD2_6741875M_18432M:
return "6.74M";
default:
return "no_freq";
}
}
static const td_char *en_quality_to_str(td_u32 quality)
{
td_u32 i;
const struct {
td_u32 down_quality;
td_u32 up_quality;
const td_char *str;
} quality_str[] = {
{ 0, 0x0001, "<-36dB" },
{ 0x0001, 0x0004, "-36~-24dB" },
{ 0x0004, 0x0010, "-24~-12dB" },
{ 0x0010, 0x0040, "-12~0dB" },
{ 0x0040, 0x0100, "0~12dB" },
{ 0x0100, 0x0400, "12~24dB" },
{ 0x0400, 0x1000, "24~36dB" },
{ 0x1000, 0x4000, "36~48dB" },
{ 0x4000, 0xFFFF, "48~60dB" },
};
for (i = 0; i < (sizeof(quality_str) / sizeof(quality_str[0])); i++) {
if ((quality >= quality_str[i].down_quality) && (quality < quality_str[i].up_quality)) {
return quality_str[i].str;
}
}
return ">60dB";
}
#define SIF_PROC_TITLE_LINE_LENGTH 72
static td_void sif_repeat_char_print(td_void *s, const td_char *t, td_u32 len)
{
td_u32 i;
for (i = 0; i < len; i++) {
if (s != TD_NULL) {
osal_seq_printf(s, "%s", t);
} else {
osal_proc_echo("%s", t);
}
}
}
static td_void sif_proc_title_print(td_void *s, const td_char *str, td_u32 len)
{
td_u32 len1;
td_u32 len2;
len1 = (len - strlen(str)) / 2; /* 2: div 2 */
len2 = len - len1 - strlen(str);
sif_repeat_char_print(s, "-", len1);
osal_seq_printf(s, "%s", str);
sif_repeat_char_print(s, "-", len2);
osal_seq_printf(s, "\n");
}
static td_void sif_proc_tail_print(td_void *s, td_u32 len)
{
sif_repeat_char_print(s, "=", len);
osal_seq_printf(s, "\n");
}
static td_void sif_proc_show_base(td_void *s, sif_hal_attr *pdev_attr)
{
td_s32 ret;
ext_sif_aaos_mode aaos_mode = EXT_SIF_AAOS_MODE_MONO;
ret = sif_get_out_mode(&aaos_mode);
if (ret != TD_SUCCESS) {
soc_log_err("get_out_mode is failed!\n");
return;
}
osal_seq_printf(s, "[sif]%s\n", VERSION_STRING);
sif_proc_title_print(s, "sif", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-56s|\n", "carrier", en_carri_status1_to_str(aaos_mode));
sif_proc_title_print(s, "deviation", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8s|", "filter1", en_filter1_to_str(pdev_attr));
osal_seq_printf(s, "%-14s:%-8s|", "deviation", deviation1_to_str(pdev_attr));
osal_seq_printf(s, "%-14s:%-8s|\n", "fm_mode", en_dem_mode_to_str(pdev_attr));
sif_proc_title_print(s, "system", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8s|", "sys_sel", sys_sel_to_str());
osal_seq_printf(s, "%-14s:%-8s|", "asd_ctl45", en_asdctl45_to_str(pdev_attr));
osal_seq_printf(s, "%-14s:%-8s|\n", "asd_ctl65", en_asdctl65_to_str(pdev_attr));
sif_proc_title_print(s, "aaos", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8d|", "aaos_en", pdev_attr->aaos_en);
osal_seq_printf(s, "%-14s:%-8s|", "l_out", en_out_to_str(pdev_attr->l_output));
osal_seq_printf(s, "%-14s:%-8s|\n", "r_out", en_out_to_str(pdev_attr->r_output));
sif_proc_title_print(s, "ascs", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8s|", "ascs_mode", en_ascs_mode_to_str(pdev_attr));
osal_seq_printf(s, "%-14s:%-8s|", "ascs_ctl", en_ascs_ctl_to_str(pdev_attr));
osal_seq_printf(s, "%24s\n", "|");
sif_proc_title_print(s, "mutectl", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8d|", "mute_en", pdev_attr->mute_en);
osal_seq_printf(s, "%-14s:%-8d|", "mute_l", pdev_attr->mute_l);
osal_seq_printf(s, "%-14s:%-8d|\n", "mute_r", pdev_attr->mute_r);
sif_proc_title_print(s, "carrier", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8s|", "carrier1", en_carri1_to_str(pdev_attr));
osal_seq_printf(s, "%-14s:%-8s|", "carrier2", en_carri2_to_str(pdev_attr));
osal_seq_printf(s, "%24s\n", "|");
}
static td_void sif_proc_show(td_void *s)
{
td_s32 ret;
sif_hal_attr *pdev_attr = TD_NULL;
td_u32 shfit_value = 0;
td_u32 deviation;
td_u32 negative = TD_FALSE;
td_bool btsc_support = TD_FALSE;
if (g_sif_drv_dev.dev_open == TD_FALSE) {
sif_proc_title_print(s, "sif", SIF_PROC_TITLE_LINE_LENGTH);
sif_proc_tail_print(s, SIF_PROC_TITLE_LINE_LENGTH);
return;
}
pdev_attr = &g_sif_drv_dev.dev_attr;
sif_proc_show_base(s, pdev_attr);
/* quality */
ret = sif_get_carri_shift_value(&shfit_value);
if (ret != TD_SUCCESS) {
soc_log_err("get_carri_shift_value is failed!\n");
}
deviation = sif_hal_get_phase_value();
if ((shfit_value) & SIGN_BIT) {
negative = TD_TRUE;
shfit_value = REG_MAX_16BITS - shfit_value;
}
shfit_value = shfit_value * SIF_SAMPLE_FREQ / (1 << 20); /* (shfit * fs) / 2^20 */
deviation = deviation * SIF_SAMPLE_FREQ / (1 << 20); /* (phase * FS) / 2^20 */
sif_proc_title_print(s, "nonstandard", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%c%-7d|", "shift1_khz", (negative == TD_TRUE) ? '-' : '+', shfit_value);
osal_seq_printf(s, "%-14s:%-8d|", "deviation_khz", deviation);
osal_seq_printf(s, "%24s\n", "|");
sif_proc_title_print(s, "quality", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-8s|", "qual1", en_quality_to_str(sif_get_quality1()));
osal_seq_printf(s, "%-14s:%-8s|", "qual2", en_quality_to_str(sif_get_quality2()));
osal_seq_printf(s, "%-14s:0x%-6x|\n", "qual_comp1", ((sif_get_quality1()) & (REG_MAX_16BITS)) >> 3); /* /2^3 */
osal_seq_printf(s, "%-14s:0x%-6x|", "qual_comp2", ((sif_get_quality2()) & (REG_MAX_16BITS)) >> 3); /* /2^3 */
osal_seq_printf(s, "%24s%24s\n", "|", "|");
sif_get_btsc_support(&btsc_support);
sif_proc_title_print(s, "otp", SIF_PROC_TITLE_LINE_LENGTH);
osal_seq_printf(s, "%-14s:%-56s|\n", "btsc", (btsc_support == TD_TRUE) ? "support" : "unsupport");
sif_proc_tail_print(s, SIF_PROC_TITLE_LINE_LENGTH);
osal_proc_echo("\n");
}
td_s32 sif_drv_read_proc(td_void *s, td_void *data)
{
td_s32 ret;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_err("lock g_sif_mutex failed\n");
return ret;
}
if (s == TD_NULL) {
soc_log_err("s is null\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_NULL_PTR;
}
sif_proc_show(s);
osal_sem_up(&g_sif_mutex);
return TD_SUCCESS;
}
td_s32 drv_sif_proc_cmd_syssel(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
{
td_s32 ret;
ext_sif_standard_type sys_sel = EXT_SIF_STANDARD_DK;
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_notice("current state is not open, can not set syssel!\n");
return TD_SUCCESS;
}
if (argc != 2) { /* 2 is argc num. */
soc_log_err("the number of param should be 2.\n");
return TD_FAILURE;
}
if (argv == TD_NULL) {
return TD_FAILURE;
}
if (!strncmp(argv[1], "DK", 2)) { /* 2 is number of characters to compare */
sys_sel = EXT_SIF_STANDARD_DK;
} else if (!strncmp(argv[1], "BG", 2)) { /* 2 is number of characters to compare */
sys_sel = EXT_SIF_STANDARD_BG;
} else if (!strncmp(argv[1], "I", 1)) {
sys_sel = EXT_SIF_STANDARD_I;
} else if (!strncmp(argv[1], "L", 1)) {
sys_sel = EXT_SIF_STANDARD_L;
} else if (!strncmp(argv[1], "KOREA", 5)) { /* 5 is number of characters to compare */
sys_sel = EXT_SIF_STANDARD_M_A2;
} else if (!strncmp(argv[1], "BTSC", 4)) { /* 4 is number of characters to compare */
sys_sel = EXT_SIF_STANDARD_M_BTSC;
} else if (!strncmp(argv[1], "EIAJ", 4)) { /* 4 is number of characters to compare */
sys_sel = EXT_SIF_STANDARD_M_EIA_J;
} else {
soc_log_err("the SIF sys_sel is not valid, can not set sys_sel!\n");
return TD_FAILURE;
}
ret = dspreg_sif_set_sys_sel(sys_sel);
if (ret != TD_SUCCESS) {
soc_log_err("set syssel failure!\n");
soc_err_print_err_code(ret);
return ret;
}
return TD_SUCCESS;
}
td_s32 drv_sif_proc_cmd_overmode(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
{
td_s32 ret;
ext_sif_over_deviation over_mode = EXT_SIF_OVER_DEVIATION_50K;
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_notice("current state is not open, can not set overmode!\n");
return TD_SUCCESS;
}
if (argc != 2) { /* 2 is argc num. */
soc_log_err("the number of param should be 2.\n");
return TD_FAILURE;
}
if (argv == TD_NULL) {
return TD_FAILURE;
}
if (strstr(argv[1], "50k")) {
over_mode = EXT_SIF_OVER_DEVIATION_50K;
} else if (strstr(argv[1], "100k")) {
over_mode = EXT_SIF_OVER_DEVIATION_100K;
} else if (strstr(argv[1], "200k")) {
over_mode = EXT_SIF_OVER_DEVIATION_200K;
} else if (strstr(argv[1], "384k")) {
over_mode = EXT_SIF_OVER_DEVIATION_384K;
} else if (strstr(argv[1], "540k")) {
over_mode = EXT_SIF_OVER_DEVIATION_540K;
} else {
soc_log_err("the SIF over_mode is not valid, can not set over_mode!\n");
return TD_FAILURE;
}
ret = sif_set_over_mode(over_mode);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(sif_set_over_mode, ret);
return ret;
}
return TD_SUCCESS;
}
td_s32 drv_sif_proc_cmd_ascs(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
{
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_notice("current state is not open, can not set ascs!\n");
return TD_SUCCESS;
}
if (argc != 2) { /* 2 is argc num. */
soc_log_err("the number of param should be 2.\n");
return TD_FAILURE;
}
if (argv == TD_NULL) {
return TD_FAILURE;
}
if (strstr(argv[1], "1")) {
g_sif_drv_dev.dev_attr.ascs_chg_mode = SIF_ASCS_CHGMODE_AUTO;
g_sif_drv_dev.dev_attr.ascs_ctl = SIF_ASCS_MODE_ALWAYS;
sif_hal_set_ascs_chg_mod(g_sif_drv_dev.dev_attr.ascs_chg_mode);
sif_hal_set_ascs_en(g_sif_drv_dev.dev_attr.ascs_ctl);
} else if (strstr(argv[1], "0")) {
g_sif_drv_dev.dev_attr.ascs_chg_mode = SIF_ASCS_CHGMODE_NOT_AUTO;
g_sif_drv_dev.dev_attr.ascs_ctl = SIF_ASCS_MODE_DISABLE;
sif_hal_set_ascs_chg_mod(g_sif_drv_dev.dev_attr.ascs_chg_mode);
sif_hal_set_ascs_en(g_sif_drv_dev.dev_attr.ascs_ctl);
} else {
soc_log_err("switch ascs param is valid, can not switch ascs on|off!\n");
return TD_FAILURE;
}
return TD_SUCCESS;
}
int drv_sif_proc_cmd_save_help(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], td_void *private)
{
sif_proc_show_help();
return TD_SUCCESS;
}
static struct {
ext_chip_name_id chip_name_id;
ext_chip_revision chip_revision;
} g_sif_chip_info = {
.chip_name_id = 0,
.chip_revision = CHIP_REVISION_MAX,
};
static const sif_chip_compatible g_sif_chip_compatible[] = {
{CHIP_NAME_RESERVED5},
{CHIP_NAME_RESERVED2},
{CHIP_NAME_RESERVED17},
{CHIP_NAME_RESERVED19},
{CHIP_NAME_HI3751V811},
};
td_bool sif_check_reserved5_reserved17_compatible(td_void)
{
td_u32 i;
for (i = 0; i < (sizeof(g_sif_chip_compatible) / sizeof(g_sif_chip_compatible[0])); i++) {
if (g_sif_chip_compatible[i].chip_name_id == g_sif_chip_info.chip_name_id) {
return TD_TRUE;
}
}
return TD_FALSE;
}
td_bool sif_check_reserved9_compatible(td_void)
{
#if defined(CONFIG_SOCT_TEE_SUPPORT)
if (((g_sif_chip_info.chip_name_id == CHIP_NAME_RESERVED9) ||
(g_sif_chip_info.chip_name_id == CHIP_NAME_RESERVED8)) &&
((g_sif_chip_info.chip_revision == CHIP_REVISION_B) ||
(g_sif_chip_info.chip_revision == CHIP_REVISION_C))) {
return TD_TRUE;
}
#endif
return TD_FALSE;
}
static td_s32 sif_open_dev(td_void)
{
td_s32 ret;
ext_drv_sys_get_chip_name_id(&g_sif_chip_info.chip_name_id);
ext_drv_sys_get_chip_revision(&g_sif_chip_info.chip_revision);
if ((sif_check_reserved5_reserved17_compatible() == TD_FALSE) &&
(sif_check_reserved9_compatible() == TD_FALSE)) {
soc_log_err("not support sif!\n");
return SOC_ERR_SIF_NOTSUPPORT;
}
ret = sif_hal_init();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(sif_hal_init, ret);
return ret;
}
ret = dspreg_sif_init();
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(dspreg_sif_init, ret);
sif_hal_deinit();
return ret;
}
return ret;
}
static td_s32 sif_close_dev(td_void)
{
dspreg_sif_deinit();
sif_hal_deinit();
return TD_SUCCESS;
}
td_void sif_osal_init(td_void)
{
td_s32 ret;
ret = osal_sem_init(&g_sif_mutex, 1);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(osal_sem_init, ret);
}
osal_atomic_init(&g_sif_open_cnt);
}
td_void sif_osal_deinit(td_void)
{
osal_atomic_destroy(&g_sif_open_cnt);
osal_sem_destroy(&g_sif_mutex);
}
td_s32 sif_drv_open(td_void *private_data)
{
td_s32 ret;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_err("lock g_sif_mutex failed\n");
return ret;
}
memset_s(&g_sif_drv_dev, sizeof(sif_drv_ctx), 0, sizeof(sif_drv_ctx));
if (osal_atomic_inc_return(&g_sif_open_cnt) == 1) {
if (sif_open_dev() != TD_SUCCESS) {
soc_log_fatal("sif_open_dev err!\n");
osal_atomic_dec(&g_sif_open_cnt);
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_DEV_OPENED;
}
soc_sif_asd_init(&g_sif_drv_dev.asd_drvier);
g_sif_drv_dev.asd_drvier.asd_thread =
osal_kthread_create(asd_thread_work, &g_sif_drv_dev.asd_drvier, "asd_thread", 0);
if (g_sif_drv_dev.asd_drvier.asd_thread == TD_NULL) {
soc_log_err("creat asd_thread_work failed\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_NULL_PTR;
}
if (sif_check_reserved9_compatible() == TD_TRUE) {
if (sif_work_init() != TD_SUCCESS) {
soc_log_err("call sif_work_init failed!\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_INVALID_PARA;
}
}
}
g_sif_drv_dev.dev_open = TD_FALSE;
osal_sem_up(&g_sif_mutex);
return TD_SUCCESS;
}
td_s32 sif_drv_close(td_void *private_data)
{
td_s32 ret;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_err("lock g_sif_mutex failed\n");
return ret;
}
if ((osal_atomic_read(&g_sif_open_cnt) != 0) && osal_atomic_dec_and_test(&g_sif_open_cnt)) {
if (sif_check_reserved9_compatible() == TD_TRUE) {
sif_work_deinit();
}
if (sif_close_dev() != TD_SUCCESS) {
soc_log_fatal("sif_close_dev err!\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_DEV_CLOSED;
}
osal_kthread_destroy(g_sif_drv_dev.asd_drvier.asd_thread, 1);
}
g_sif_drv_dev.dev_open = TD_FALSE;
osal_sem_up(&g_sif_mutex);
return TD_SUCCESS;
}
static td_s32 sif_drv_suspend(td_void *private_data)
{
td_s32 ret;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_err("lock g_sif_mutex failed\n");
return ret;
}
if (osal_atomic_read(&g_sif_open_cnt) != 0) {
ret = sif_suspend();
if (ret != TD_SUCCESS) {
soc_log_fatal("SIF suspend fail\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_DEVICE_BUSY;
}
}
osal_sem_up(&g_sif_mutex);
return TD_SUCCESS;
}
td_s32 sif_pm_suspend(td_void *private_data)
{
td_s32 ret;
ret = sif_drv_suspend(private_data);
if (ret == TD_SUCCESS) {
soc_print("SIF suspend OK\n");
}
return ret;
}
td_s32 sif_pm_lowpower_enter(td_void *private_data)
{
td_s32 ret;
ret = sif_drv_suspend(private_data);
if (ret == TD_SUCCESS) {
soc_print("SIF lowpower enter OK\n");
}
return ret;
}
static td_s32 sif_drv_resume(td_void *private_data)
{
td_s32 ret;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_err("lock g_sif_mutex failed\n");
return ret;
}
if (osal_atomic_read(&g_sif_open_cnt) != 0) {
ret = sif_resume();
if (ret != TD_SUCCESS) {
soc_log_fatal("SIF resume fail\n");
osal_sem_up(&g_sif_mutex);
return SOC_ERR_SIF_DEVICE_BUSY;
}
}
osal_sem_up(&g_sif_mutex);
return TD_SUCCESS;
}
td_s32 sif_pm_resume(td_void *private_data)
{
td_s32 ret;
ret = sif_drv_resume(private_data);
if (ret == TD_SUCCESS) {
soc_print("SIF resume OK\n");
}
return ret;
}
td_s32 sif_pm_lowpower_exit(td_void *private_data)
{
td_s32 ret;
ret = sif_drv_resume(private_data);
if (ret == TD_SUCCESS) {
soc_print("SIF lowpower exit OK\n");
}
return ret;
}
static td_s32 sif_check_dev_status(td_void)
{
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not get syssel!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not get syssel!\n");
return SOC_ERR_SIF_NOT_START;
}
return TD_SUCCESS;
}
static td_void sif_get_sys_sel_val(sif_sys_sel sys_sel, ext_sif_standard_type *psys_sel)
{
switch (sys_sel) {
case SIF_SYS_SEL_BG_FM:
*psys_sel = EXT_SIF_STANDARD_BG_A2;
break;
case SIF_SYS_SEL_BG_NICAM:
*psys_sel = EXT_SIF_STANDARD_BG_NICAM;
break;
case SIF_SYS_SEL_I:
*psys_sel = EXT_SIF_STANDARD_I;
break;
case SIF_SYS_SEL_DK1:
*psys_sel = EXT_SIF_STANDARD_DK1_A2;
break;
case SIF_SYS_SEL_DK2:
*psys_sel = EXT_SIF_STANDARD_DK2_A2;
break;
case SIF_SYS_SEL_DK3:
*psys_sel = EXT_SIF_STANDARD_DK3_A2;
break;
case SIF_SYS_SEL_DK_NICAM:
*psys_sel = EXT_SIF_STANDARD_DK_NICAM;
break;
case SIF_SYS_SEL_L:
*psys_sel = EXT_SIF_STANDARD_L;
break;
case SIF_SYS_SEL_BTSC:
*psys_sel = EXT_SIF_STANDARD_M_BTSC;
break;
case SIF_SYS_SEL_KOREA:
*psys_sel = EXT_SIF_STANDARD_M_A2;
break;
case SIF_SYS_SEL_EIAJ:
*psys_sel = EXT_SIF_STANDARD_M_EIA_J;
break;
case SIF_SYS_SEL_FM_RADIO_EUROPE:
case SIF_SYS_SEL_FM_RADIO_US:
case SIF_SYS_SEL_FM_RADIO_EUROPE1:
case SIF_SYS_SEL_FM_RADIO_EUROPE2:
*psys_sel = EXT_SIF_STANDARD_NOTSTANDARD;
break;
case SIF_SYS_SEL_FM_RADIO_EUROPE3:
*psys_sel = EXT_SIF_STANDARD_UNKNOW; /* try to decode nostandard signal */
break;
default:
*psys_sel = EXT_SIF_STANDARD_UNKNOW;
break;
}
}
static td_void sif_get_need_ascs_detect_status(td_bool *need_ascs_detect)
{
if ((g_sif_drv_dev.dev_attr.sys_sel >= SIF_SYS_SEL_BG_FM) &&
(g_sif_drv_dev.dev_attr.sys_sel <= SIF_SYS_SEL_BG_NICAM)) {
*need_ascs_detect = TD_TRUE;
}
if ((g_sif_drv_dev.dev_attr.sys_sel >= SIF_SYS_SEL_DK1) &&
(g_sif_drv_dev.dev_attr.sys_sel <= SIF_SYS_SEL_DK_NICAM)) {
*need_ascs_detect = TD_TRUE;
}
if ((g_sif_drv_dev.aaos_mode != EXT_SIF_AAOS_MODE_MONO) &&
(g_sif_drv_dev.aaos_mode != EXT_SIF_AAOS_MODE_NICAM_MONO)) {
*need_ascs_detect = TD_FALSE;
}
}
static td_s32 sif_get_sys_sel(ext_sif_standard_type *psys_sel)
{
td_s32 ret;
sif_sys_sel sys_sel = SIF_SYS_SEL_BUTT;
td_bool need_ascs_detect = TD_FALSE;
static td_u32 wait_ascs_cnt = 0;
sif_sys_sel ascs_sys_sel = SIF_SYS_SEL_BUTT;
td_bool get_sys_sel_from_ascs = TD_FALSE;
soc_dbg_func_enter();
if (psys_sel == TD_NULL) {
soc_log_err("psys_sel is null!\n");
return SOC_ERR_SIF_NULL_PTR;
}
ret = sif_check_dev_status();
if (ret != TD_SUCCESS) {
return ret;
}
sif_get_need_ascs_detect_status(&need_ascs_detect);
if (need_ascs_detect == TD_TRUE) {
osal_msleep(5); /* 5 is sleep time. */
wait_ascs_cnt++;
if (wait_ascs_cnt > 40) { /* 40 is a threshold */
wait_ascs_cnt = 0;
sif_hal_set_ascs_en(SIF_ASCS_MODE_ONETIME);
osal_msleep(20); /* 20 is sleep time. */
}
ascs_sys_sel = (sif_sys_sel)sif_hal_get_ascs_result();
if ((ascs_sys_sel != SIF_SYS_SEL_FM_RADIO_EUROPE3) && (g_sif_drv_dev.dev_attr.sys_sel != ascs_sys_sel)) {
get_sys_sel_from_ascs = TD_TRUE;
}
}
if (get_sys_sel_from_ascs == TD_TRUE) {
soc_log_info("ASCS result: syssel\n");
soc_info_print_s32(ascs_sys_sel);
sys_sel = ascs_sys_sel;
} else {
sys_sel = sif_hal_get_det_standard();
}
sif_get_sys_sel_val(sys_sel, psys_sel);
g_sif_drv_dev.dev_attr.sys_sel = sys_sel;
g_sif_drv_dev.sif_stand = *psys_sel;
soc_dbg_func_exit();
return TD_SUCCESS;
}
static td_void sif_get_btsc_support(td_bool *support)
{
sif_hal_get_btsc_support(support);
}
static td_void sif_btsc_get_out_mode(ext_sif_aaos_mode *pen_mode)
{
td_bool stereo;
td_bool sap;
stereo = sif_hal_is_stereo();
sap = sif_hal_is_bi_sap();
if (sap == TD_TRUE) {
*pen_mode = stereo ? EXT_SIF_AAOS_MODE_STEREO_SAP : EXT_SIF_AAOS_MODE_MONO_SAP;
} else {
*pen_mode = stereo ? EXT_SIF_AAOS_MODE_STEREO : EXT_SIF_AAOS_MODE_MONO;
}
}
static td_void sif_a2_get_out_mode(ext_sif_aaos_mode *pen_mode)
{
td_bool det_out_mode;
sif_audmode_det aud_mode;
*pen_mode = EXT_SIF_AAOS_MODE_MONO;
det_out_mode = sif_hal_is_sec_car_exist();
if (det_out_mode == TD_FALSE) {
return;
}
aud_mode = sif_hal_get_aud_mod_det();
switch (aud_mode) {
case SIF_AUDMODE_MONO:
*pen_mode = EXT_SIF_AAOS_MODE_MONO;
break;
case SIF_AUDMODE_STEREO:
if (sif_hal_is_stereo() != TD_TRUE) {
break;
}
*pen_mode = EXT_SIF_AAOS_MODE_STEREO;
break;
case SIF_AUDMODE_BILIGUAL:
if (sif_hal_is_bi_sap() != TD_TRUE) {
break;
}
*pen_mode = EXT_SIF_AAOS_MODE_DUAL;
break;
default:
*pen_mode = EXT_SIF_AAOS_MODE_MONO;
break;
}
}
static td_void sif_nicam_get_out_mode(ext_sif_aaos_mode *pen_mode)
{
sif_nicam_ctrl nicam_ctl;
sif_anadig_status ana_mode;
ana_mode = sif_hal_get_ana_dig_status();
if (ana_mode != SIF_ANADIG_STATUS_DIG) {
return;
}
nicam_ctl = sif_hal_get_nicam_ctrl();
switch (nicam_ctl) {
case SIF_NICAM_CTRL_STEREO:
*pen_mode = EXT_SIF_AAOS_MODE_NICAM_STEREO;
break;
case SIF_NICAM_CTRL_MONODATA:
*pen_mode = EXT_SIF_AAOS_MODE_NICAM_MONO;
break;
case SIF_NICAM_CTRL_DUALMONO:
*pen_mode = EXT_SIF_AAOS_MODE_NICAM_DUAL;
break;
default:
break;
}
}
static td_void sif_eiaj_get_out_mode(ext_sif_aaos_mode *pen_mode)
{
td_bool det_out_mode;
sif_audmode_det aud_mode;
det_out_mode = sif_hal_is_prm_car_exist();
if (det_out_mode == TD_FALSE) {
return;
}
aud_mode = sif_hal_get_aud_mod_det();
switch (aud_mode) {
case SIF_AUDMODE_MONO:
*pen_mode = EXT_SIF_AAOS_MODE_MONO;
break;
case SIF_AUDMODE_BILIGUAL:
*pen_mode = EXT_SIF_AAOS_MODE_DUAL;
break;
case SIF_AUDMODE_STEREO:
*pen_mode = EXT_SIF_AAOS_MODE_STEREO;
break;
default:
*pen_mode = EXT_SIF_AAOS_MODE_MONO;
break;
}
}
static td_s32 sif_get_out_mode(ext_sif_aaos_mode *paaos_mode)
{
td_s32 ret;
ext_sif_aaos_mode mode = EXT_SIF_AAOS_MODE_MONO;
ext_sif_standard_type sys_sel = EXT_SIF_STANDARD_UNKNOW;
soc_dbg_func_enter();
ret = sif_check_dev_status();
if (ret != TD_SUCCESS) {
return ret;
}
ret = sif_get_sys_sel(&sys_sel);
if (ret != TD_SUCCESS) {
soc_log_err("get_sys_sel is failed!\n");
}
switch (g_sif_drv_dev.dev_attr.sys_sel) {
case SIF_SYS_SEL_BTSC:
sif_btsc_get_out_mode(&mode);
break;
case SIF_SYS_SEL_BG_FM:
case SIF_SYS_SEL_DK1:
case SIF_SYS_SEL_DK2:
case SIF_SYS_SEL_DK3:
case SIF_SYS_SEL_KOREA: /* FM-korea */
sif_a2_get_out_mode(&mode);
break;
case SIF_SYS_SEL_L:
case SIF_SYS_SEL_BG_NICAM:
case SIF_SYS_SEL_DK_NICAM:
case SIF_SYS_SEL_I:
sif_nicam_get_out_mode(&mode);
break;
case SIF_SYS_SEL_EIAJ:
sif_eiaj_get_out_mode(&mode);
break;
case SIF_SYS_SEL_FM_RADIO_US:
case SIF_SYS_SEL_FM_RADIO_EUROPE1:
case SIF_SYS_SEL_FM_RADIO_EUROPE2:
case SIF_SYS_SEL_FM_RADIO_EUROPE3:
mode = EXT_SIF_AAOS_MODE_MONO;
break;
default:
mode = EXT_SIF_AAOS_MODE_MONO;
break;
}
g_sif_drv_dev.aaos_mode = mode;
*paaos_mode = mode;
soc_dbg_func_exit();
return TD_SUCCESS;
}
static inline td_void sif_get_aaos_nicam_forced_mono(td_void)
{
if (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) {
g_sif_drv_dev.dev_attr.btsc_sap = TD_FALSE;
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_STEREO);
}
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.aaos_en = TD_FALSE;
}
static inline td_void sif_get_aaos_nicam_stereo(td_void)
{
if (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) {
g_sif_drv_dev.dev_attr.btsc_sap = TD_FALSE;
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_STEREO);
}
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
}
static inline td_void sif_get_aaos_nicam_dual_b(td_void)
{
if (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) {
g_sif_drv_dev.dev_attr.btsc_sap = TD_TRUE;
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_SAP);
}
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_B;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_B;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
}
static inline td_void sif_get_aaos_btsc_sap(td_void)
{
if (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) {
g_sif_drv_dev.dev_attr.btsc_sap = TD_TRUE;
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_SAP);
}
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_B;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_B;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
}
static inline td_void sif_get_aaos_nicam_dual_ab(td_void)
{
if (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) {
g_sif_drv_dev.dev_attr.btsc_sap = TD_TRUE;
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_SAP);
}
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_A;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_B;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
}
static inline td_void sif_get_aaos_btsc_stereo(td_void)
{
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
}
static td_void sif_get_aaos_by_outmode(ext_sif_out_mode out_mode)
{
switch (out_mode) {
case EXT_SIF_OUT_MODE_MONO:
case EXT_SIF_OUT_MODE_NICAM_MONO:
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
break;
case EXT_SIF_OUT_MODE_BTSC_MONO:
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_MONO;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
break;
case EXT_SIF_OUT_MODE_NICAM_FORCED_MONO:
sif_get_aaos_nicam_forced_mono();
break;
case EXT_SIF_OUT_MODE_STEREO:
case EXT_SIF_OUT_MODE_NICAM_STEREO:
sif_get_aaos_nicam_stereo();
break;
case EXT_SIF_OUT_MODE_BTSC_STEREO:
sif_get_aaos_btsc_stereo();
break;
case EXT_SIF_OUT_MODE_DUAL_A:
case EXT_SIF_OUT_MODE_NICAM_DUAL_A:
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_A;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_A;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
break;
case EXT_SIF_OUT_MODE_DUAL_B:
case EXT_SIF_OUT_MODE_NICAM_DUAL_B:
sif_get_aaos_nicam_dual_b();
break;
case EXT_SIF_OUT_MODE_BTSC_SAP:
sif_get_aaos_btsc_sap();
break;
case EXT_SIF_OUT_MODE_DUAL_AB:
case EXT_SIF_OUT_MODE_NICAM_DUAL_AB:
sif_get_aaos_nicam_dual_ab();
break;
default:
soc_log_warn("set invalid out mode:\n");
soc_warn_print_u32(out_mode);
g_sif_drv_dev.dev_attr.l_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.r_output = SIF_AAOS_OUTMODE_L_OR_R;
g_sif_drv_dev.dev_attr.aaos_en = TD_TRUE;
break;
}
}
static td_s32 sif_set_out_mode(ext_sif_out_mode out_mode)
{
td_s32 ret;
ext_sif_standard_type sys_sel_type = EXT_SIF_STANDARD_UNKNOW;
soc_dbg_func_enter();
ret = sif_get_sys_sel(&sys_sel_type);
if (ret != TD_SUCCESS) {
soc_log_err("get_sys_sel is failed!\n");
}
ret = sif_check_dev_status();
if (ret != TD_SUCCESS) {
return ret;
}
sif_get_aaos_by_outmode(out_mode);
sif_hal_set_aaos_lf_sel(g_sif_drv_dev.dev_attr.l_output);
sif_hal_set_aaos_rt_sel(g_sif_drv_dev.dev_attr.r_output);
sif_hal_aaos_en(g_sif_drv_dev.dev_attr.aaos_en);
soc_dbg_func_exit();
return TD_SUCCESS;
}
static td_s32 sif_set_carri_shift(td_u32 carri_shift)
{
soc_info_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not set carrier shift!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not set carrier shift!\n");
return SOC_ERR_SIF_NOT_START;
}
g_sif_drv_dev.dev_attr.crri_freq1 = carri_shift;
sif_hal_set_demod_carri_freq1(g_sif_drv_dev.dev_attr.crri_freq1);
soc_info_func_exit();
return TD_SUCCESS;
}
/* the order of value is wrong on logic, should exchange here */
static ext_sif_over_deviation g_real_over_mode[EXT_SIF_OVER_DEVIATION_MAX] = {
EXT_SIF_OVER_DEVIATION_50K,
EXT_SIF_OVER_DEVIATION_100K,
EXT_SIF_OVER_DEVIATION_540K,
EXT_SIF_OVER_DEVIATION_200K,
EXT_SIF_OVER_DEVIATION_384K,
};
static td_s32 sif_set_over_mode(ext_sif_over_deviation over_mode)
{
soc_info_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not set over mode!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not set over mode!\n");
return SOC_ERR_SIF_NOT_START;
}
if (over_mode >= EXT_SIF_OVER_DEVIATION_MAX) {
soc_log_err("invalid over mode param error: \n");
soc_err_print_u32(over_mode);
return SOC_ERR_SIF_INVALID_PARA;
}
if ((g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_BTSC) || (g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_EIAJ) ||
(g_sif_drv_dev.dev_attr.sys_sel == SIF_SYS_SEL_KOREA)) {
g_sif_drv_dev.dev_attr.flt1 = SIF_DEMOD1_FILTER_100K;
g_sif_drv_dev.dev_attr.deviation1 = SIF_DEVIATION_100K;
} else {
g_sif_drv_dev.dev_attr.flt1 = (sif_filter1)g_real_over_mode[over_mode];
g_sif_drv_dev.dev_attr.deviation1 = (sif_deviation1)g_real_over_mode[over_mode];
}
sif_hal_set_filter1(g_sif_drv_dev.dev_attr.flt1);
sif_hal_set_deviation1(g_sif_drv_dev.dev_attr.deviation1);
sif_hal_set_deviation2(g_sif_drv_dev.dev_attr.deviation1);
soc_info_func_exit();
return TD_SUCCESS;
}
/* the order of value is wrong on logic, should exchange here */
static sif_deviation1 g_real_deviation1[SIF_DEVIATION_BUTT] = {
EXT_SIF_OVER_DEVIATION_50K,
EXT_SIF_OVER_DEVIATION_100K,
EXT_SIF_OVER_DEVIATION_384K,
EXT_SIF_OVER_DEVIATION_540K,
EXT_SIF_OVER_DEVIATION_200K,
};
static td_s32 sif_get_over_mode(ext_sif_over_deviation *pover_mode)
{
sif_deviation1 deviation1 = SIF_DEVIATION_BUTT;
soc_info_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not start ASD detect!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not stop, can not set attr!\n");
return SOC_ERR_SIF_NOT_START;
}
sif_hal_get_deviation1(&deviation1);
*pover_mode = (ext_sif_over_deviation)g_real_deviation1[deviation1];
soc_info_func_exit();
return TD_SUCCESS;
}
static td_s32 sif_set_auto_mute(td_bool auto_mute)
{
if (auto_mute == TD_FALSE) {
sif_hal_set_mute_right(TD_FALSE);
sif_hal_set_mute_left(TD_FALSE);
}
sif_hal_set_mute_auto(auto_mute);
return TD_SUCCESS;
}
static td_s32 sif_set_freq_error(ext_sif_freq_err_threshold freq_err)
{
sif_freq_err_threshold hal_freq_err = SIF_FREQ_ERR_THRESHOLD_27K;
switch (freq_err) {
case EXT_SIF_FREQ_ERR_THRESHOLD_10K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_10K;
break;
case EXT_SIF_FREQ_ERR_THRESHOLD_20K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_20K;
break;
case EXT_SIF_FREQ_ERR_THRESHOLD_27K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_27K;
break;
case EXT_SIF_FREQ_ERR_THRESHOLD_30K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_30K;
break;
case EXT_SIF_FREQ_ERR_THRESHOLD_40K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_40K;
break;
case EXT_SIF_FREQ_ERR_THRESHOLD_50K:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_50K;
break;
default:
hal_freq_err = SIF_FREQ_ERR_THRESHOLD_27K;
break;
}
sif_hal_set_freq_err(hal_freq_err);
return TD_SUCCESS;
}
static td_s32 sif_set_attr(ext_sif_attr attr)
{
td_s32 ret;
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not set attr!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_STOP) {
soc_log_err("current state is not stop, can not set attr!\n");
return SOC_ERR_SIF_NOT_STOP;
}
ret = memcpy_s(&g_sif_drv_dev.attr, sizeof(ext_sif_attr), &attr, sizeof(attr));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed");
return ret;
}
ret = sif_set_freq_error(g_sif_drv_dev.attr.freq_threshold);
if (ret != TD_SUCCESS) {
soc_log_err("sif_set_freq_error is failed!\n");
}
ret = sif_set_auto_mute(g_sif_drv_dev.attr.auto_mute);
if (ret != TD_SUCCESS) {
soc_log_err("sif_set_auto_mute is failed!\n");
}
return TD_SUCCESS;
}
static td_s32 sif_get_attr(ext_sif_attr *attr)
{
td_s32 ret;
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not get attr!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not get attr!\n");
return SOC_ERR_SIF_NOT_START;
}
ret = memcpy_s(attr, sizeof(ext_sif_attr), &g_sif_drv_dev.attr, sizeof(g_sif_drv_dev.attr));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed");
return ret;
}
return TD_SUCCESS;
}
static td_s32 sif_open(td_void)
{
soc_info_func_enter();
g_sif_drv_dev.curn_status = SIF_CHANNEL_STATUS_STOP;
g_sif_drv_dev.dev_open = TD_TRUE;
soc_info_func_exit();
return TD_SUCCESS;
}
static td_s32 sif_close(td_void)
{
soc_info_func_enter();
/* 复位即ok */
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_STOP) {
soc_log_err("current state is not stop, can not close sif!\n");
return SOC_ERR_SIF_NOT_STOP;
}
g_sif_drv_dev.dev_open = TD_FALSE;
soc_info_func_exit();
return TD_SUCCESS;
}
static td_s32 sif_start(td_void)
{
soc_info_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not start sif!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
g_sif_drv_dev.dev_attr.ascs_chg_mode = SIF_ASCS_CHGMODE_AFTER_RST;
g_sif_drv_dev.dev_attr.ascs_ctl = SIF_ASCS_MODE_DISABLE;
sif_hal_set_ascs_chg_mod(g_sif_drv_dev.dev_attr.ascs_chg_mode);
sif_hal_set_ascs_en(g_sif_drv_dev.dev_attr.ascs_ctl);
g_sif_drv_dev.curn_status = SIF_CHANNEL_STATUS_START;
soc_info_func_exit();
return TD_SUCCESS;
}
static td_s32 sif_stop(td_void)
{
soc_info_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not stop sif!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
g_sif_drv_dev.curn_status = SIF_CHANNEL_STATUS_STOP;
soc_info_func_exit();
return TD_SUCCESS;
}
static td_u32 sif_get_quality1(td_void)
{
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not get quality1!\n");
return SOC_ERR_SIF_NOT_START;
}
return sif_hal_get_quality1();
}
static td_u32 sif_get_quality2(td_void)
{
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not get quality2!\n");
return SOC_ERR_SIF_NOT_START;
}
return sif_hal_get_quality2();
}
static td_s32 sif_get_carri_shift_value(td_u32 *shift_value)
{
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not get carrier shift value!\n");
return SOC_ERR_SIF_NOT_START;
}
*shift_value = sif_hal_get_carrier_shift_value();
g_sif_drv_dev.dev_attr.carri_shift_value = *shift_value;
return TD_SUCCESS;
}
static td_s32 sif_suspend(td_void)
{
td_s32 ret;
ext_sif_standard_type sys_sel = EXT_SIF_STANDARD_UNKNOW;
if (!g_sif_suspend_flag) {
g_sif_suspend_flag = 1;
}
/* 7. sap状态 */
/* 仅在设置输出时设置默认为解stereo,没有改变就无需设置 */
/* 6. auto mute */
/* 设置属性中已经保存该值 */
/* 5. 输出选择,从寄存器中获取状态 */
g_sif_drv_dev.dev_attr.l_output = sif_hal_get_aaos_lf_sel();
g_sif_drv_dev.dev_attr.r_output = sif_hal_get_aaos_rt_sel();
g_sif_drv_dev.dev_attr.aaos_en = sif_hal_get_aaos_en();
/* 4. 制式 */
ret = sif_get_sys_sel(&sys_sel);
if (ret != TD_SUCCESS) {
soc_log_err("get_sys_sel is failed!\n");
}
dspreg_sif_deinit();
g_sif_resume_flag = 0;
return TD_SUCCESS;
}
static td_s32 sif_resume(td_void)
{
if (!g_sif_resume_flag) {
dspreg_sif_init();
/* 3. 阈值 */
sif_set_freq_error(g_sif_drv_dev.attr.freq_threshold);
/* 4. 制式 */
dspreg_sif_set_sys_sel(g_sif_drv_dev.sif_stand);
/* 5. 设置自动载波跟随 */
sif_hal_set_ascs_chg_mod(g_sif_drv_dev.dev_attr.ascs_chg_mode);
sif_hal_set_ascs_en(g_sif_drv_dev.dev_attr.ascs_ctl);
/* 6. 输出选择 */
sif_hal_set_aaos_lf_sel(g_sif_drv_dev.dev_attr.l_output);
sif_hal_set_aaos_rt_sel(g_sif_drv_dev.dev_attr.r_output);
sif_hal_aaos_en(g_sif_drv_dev.dev_attr.aaos_en);
/* 7. auto mute */
sif_set_auto_mute(g_sif_drv_dev.dev_attr.auto_mute);
/* 8. sap状态 */
if (g_sif_drv_dev.dev_attr.btsc_sap == TD_TRUE) {
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_SAP);
}
g_sif_resume_flag = 1;
}
g_sif_suspend_flag = 0;
return TD_SUCCESS;
}
static td_void sif_reset(td_void)
{
td_s32 ret;
/* 保存原来的输出模式 */
g_sif_drv_dev.dev_attr.l_output = sif_hal_get_aaos_lf_sel();
g_sif_drv_dev.dev_attr.r_output = sif_hal_get_aaos_rt_sel();
g_sif_drv_dev.dev_attr.aaos_en = sif_hal_get_aaos_en();
osal_msleep(2); /* 2 is time for sleep */
/* 恢复 阈值 */
ret = sif_set_freq_error(g_sif_drv_dev.attr.freq_threshold);
if (ret != TD_SUCCESS) {
soc_log_err("sif_set_freq_error is failed!\n");
}
/* 恢复自动载波跟随 */
sif_hal_set_ascs_chg_mod(g_sif_drv_dev.dev_attr.ascs_chg_mode);
sif_hal_set_ascs_en(g_sif_drv_dev.dev_attr.ascs_ctl);
/* 输出选择 */
sif_hal_set_aaos_lf_sel(g_sif_drv_dev.dev_attr.l_output);
sif_hal_set_aaos_rt_sel(g_sif_drv_dev.dev_attr.r_output);
sif_hal_aaos_en(g_sif_drv_dev.dev_attr.aaos_en);
/* 恢复自动mute */
ret = sif_set_auto_mute(g_sif_drv_dev.dev_attr.auto_mute);
if (ret != TD_SUCCESS) {
soc_log_err("sif_set_auto_mute is failed!\n");
}
/* 恢复sap */
if (g_sif_drv_dev.dev_attr.btsc_sap == TD_TRUE) {
sif_hal_set_btsc_sap(SIF_SIGSEL_BTSC_SAP);
}
return;
}
static int sif_drv_ioctl_standard_type(unsigned int cmd, td_void *arg)
{
td_s32 ret = TD_FAILURE;
sif_standard_type_param *sys_sel = (sif_standard_type_param *)arg;
switch (cmd) {
case CMD_SIF_SET_STANDDARD:
sif_reset();
ret = dspreg_sif_set_sys_sel(sys_sel->stand);
break;
case CMD_SIF_GET_ASD_RESULT:
ret = dspreg_sif_get_asd_result(&sys_sel->stand);
break;
case CMD_SIF_GET_STANDARD:
ret = sif_get_sys_sel(&sys_sel->stand);
break;
default:
soc_log_err("invalid parameter!\n");
break;
}
return ret;
}
static int sif_drv_ioctl_over_deviation(unsigned int cmd, td_void *arg)
{
td_s32 ret = TD_FAILURE;
sif_over_deviation_param *over_mod = (sif_over_deviation_param *)arg;
switch (cmd) {
case CMD_SIF_SET_OVER_DEV:
ret = sif_set_over_mode(over_mod->over_mode);
break;
case CMD_SIF_GET_OVER_DEV:
ret = sif_get_over_mode(&over_mod->over_mode);
break;
default:
soc_log_err("invalid parameter!\n");
break;
}
return ret;
}
static const struct {
sif_sys_sel sys_sel;
ext_sif_standard_type standard_type;
} g_sif_sys_to_standard[] = {
{SIF_SYS_SEL_BG_FM, EXT_SIF_STANDARD_BG_A2},
{SIF_SYS_SEL_BG_NICAM, EXT_SIF_STANDARD_BG_NICAM},
{SIF_SYS_SEL_I, EXT_SIF_STANDARD_I},
{SIF_SYS_SEL_DK1, EXT_SIF_STANDARD_DK1_A2},
{SIF_SYS_SEL_DK2, EXT_SIF_STANDARD_DK2_A2},
{SIF_SYS_SEL_DK3, EXT_SIF_STANDARD_DK3_A2},
{SIF_SYS_SEL_DK_NICAM, EXT_SIF_STANDARD_DK_NICAM},
{SIF_SYS_SEL_L, EXT_SIF_STANDARD_L},
{SIF_SYS_SEL_BTSC, EXT_SIF_STANDARD_M_BTSC},
{SIF_SYS_SEL_KOREA, EXT_SIF_STANDARD_M_A2},
{SIF_SYS_SEL_EIAJ, EXT_SIF_STANDARD_M_EIA_J},
{SIF_SYS_SEL_FM_RADIO_EUROPE, EXT_SIF_STANDARD_NOTSTANDARD},
{SIF_SYS_SEL_FM_RADIO_US, EXT_SIF_STANDARD_NOTSTANDARD},
{SIF_SYS_SEL_FM_RADIO_EUROPE1, EXT_SIF_STANDARD_NOTSTANDARD},
{SIF_SYS_SEL_FM_RADIO_EUROPE2, EXT_SIF_STANDARD_NOTSTANDARD},
{SIF_SYS_SEL_FM_RADIO_EUROPE3, EXT_SIF_STANDARD_UNKNOW},
};
static const struct {
ext_sif_standard_type standard_type;
sif_sys_sel sys_sel;
} g_sif_standard_to_sys[] = {
{EXT_SIF_STANDARD_BG, SIF_SYS_SEL_BG_FM},
{EXT_SIF_STANDARD_BG_A2, SIF_SYS_SEL_BG_FM},
{EXT_SIF_STANDARD_BG_NICAM, SIF_SYS_SEL_BG_NICAM},
{EXT_SIF_STANDARD_I, SIF_SYS_SEL_I},
{EXT_SIF_STANDARD_DK, SIF_SYS_SEL_DK3},
{EXT_SIF_STANDARD_DK3_A2, SIF_SYS_SEL_DK3},
{EXT_SIF_STANDARD_DK1_A2, SIF_SYS_SEL_DK1},
{EXT_SIF_STANDARD_DK2_A2, SIF_SYS_SEL_DK2},
{EXT_SIF_STANDARD_DK_NICAM, SIF_SYS_SEL_DK_NICAM},
{EXT_SIF_STANDARD_M, SIF_SYS_SEL_KOREA},
{EXT_SIF_STANDARD_M_A2, SIF_SYS_SEL_KOREA},
{EXT_SIF_STANDARD_M_BTSC, SIF_SYS_SEL_BTSC},
{EXT_SIF_STANDARD_M_EIA_J, SIF_SYS_SEL_EIAJ},
{EXT_SIF_STANDARD_L, SIF_SYS_SEL_L},
};
static td_s32 sif_get_standard_try(ext_sif_carrier_attr *attr)
{
td_s32 i;
td_s32 ret;
soc_dbg_func_enter();
if (g_sif_drv_dev.dev_open == TD_FALSE) {
soc_log_err("current state is not open, can not try standard!\n");
return SOC_ERR_SIF_NOT_OPEN;
}
if (g_sif_drv_dev.curn_status != SIF_CHANNEL_STATUS_START) {
soc_log_err("current state is not start, can not try standard!\n");
return SOC_ERR_SIF_NOT_START;
}
ret = sif_hal_get_standard_try((sif_hal_carrier_attr *)attr);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(sif_hal_get_standard_try, ret);
return ret;
}
for (i = 0; i < sizeof(g_sif_sys_to_standard) / sizeof(g_sif_sys_to_standard[0]); i++) {
if (attr->standard_type == (ext_sif_standard_type)g_sif_sys_to_standard[i].sys_sel) {
attr->standard_type = g_sif_sys_to_standard[i].standard_type;
break;
}
}
if (i == sizeof(g_sif_sys_to_standard) / sizeof(g_sif_sys_to_standard[0])) {
attr->standard_type = EXT_SIF_STANDARD_UNKNOW;
}
soc_dbg_func_exit();
return TD_SUCCESS;
}
static td_u32 sif_set_standard_try_priority(ext_sif_standard_priority_list *priority_list)
{
td_u32 i;
td_u32 j;
td_s32 ret;
td_u32 list_len = priority_list->list_len;
if (list_len > EXT_SIF_STANDARD_MAX) {
soc_log_err("standardtry list length is too big!\n");
return SOC_ERR_SIF_INVALID_PARA;
}
for (i = 0; i < list_len; i++) {
for (j = 0; j < sizeof(g_sif_standard_to_sys) / sizeof(g_sif_standard_to_sys[0]); j++) {
if (priority_list->priority_list[i] == g_sif_standard_to_sys[j].standard_type) {
priority_list->priority_list[i] = (ext_sif_standard_type)g_sif_standard_to_sys[j].sys_sel;
break;
}
}
if (j == sizeof(g_sif_standard_to_sys) / sizeof(g_sif_standard_to_sys[0])) {
priority_list->priority_list[i] = (ext_sif_standard_type)SIF_SYS_SEL_FM_RADIO_EUROPE3;
}
}
ret = sif_hal_set_standard_try_priority((sif_hal_syssel_priority_list *)priority_list);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(sif_set_standard_try_priority, ret);
return ret;
}
return TD_SUCCESS;
}
static int sif_drv_ioctl_try_standard(td_void *arg)
{
sif_carrier_attr_param *attr = (sif_carrier_attr_param *)arg;
return sif_get_standard_try(&(attr->carrier_attr));
}
static int sif_drv_ioctl_standard_list(const td_void *arg)
{
sif_standard_list_param *standard_list_param = (sif_standard_list_param *)arg;
return sif_set_standard_try_priority(&(standard_list_param->priority_list));
}
static int sif_drv_ioctl_start_asd(const td_void *arg)
{
sif_sysctl_param *sys_ctl = (sif_sysctl_param *)arg;
hal_set_core_reset(TD_TRUE);
hal_set_core_reset(TD_FALSE);
return dspreg_sif_start_asd_detect(sys_ctl->sys_ctl);
}
static int sif_drv_ioctl_asd_cmpl(td_void *arg)
{
sif_asd_complete_param *asd_cmpl = (sif_asd_complete_param *)arg;
return dspreg_sif_get_asd_complete(&asd_cmpl->asd_complete);
}
int sif_drv_ioctl_inner_ext(unsigned int cmd, td_void *arg, td_void *private_data)
{
td_s32 ret;
sif_attr_param *attr = TD_NULL;
soc_dbg_func_enter();
if (arg == TD_NULL) {
soc_log_err("arg is null!\n");
return SOC_ERR_SIF_NULL_PTR;
}
attr = (sif_attr_param *)arg;
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_fatal("lock g_sif_mutex failed\n");
return ret;
}
switch (cmd) {
case CMD_SIF_SET_ATTR:
ret = sif_set_attr(attr->sif_attr);
break;
case CMD_SIF_GET_ATTR:
ret = sif_get_attr(&attr->sif_attr);
break;
case CMD_SIF_OPEN: { /* fall-through */
ret = sif_open();
break;
}
case CMD_SIF_CLOSE:
ret = sif_close();
break;
case CMD_SIF_SET_START:
ret = sif_start();
break;
case CMD_SIF_SET_STOP:
ret = sif_stop();
break;
case CMD_SIF_TRY_STANDARD:
ret = sif_drv_ioctl_try_standard(arg);
break;
case CMD_SIF_SET_STANDARD_LIST:
ret = sif_drv_ioctl_standard_list(arg);
break;
default:
soc_log_err("INVALID IOCTL CMD: %#x\n", cmd);
ret = SOC_ERR_SIF_INVALID_PARA;
break;
}
osal_sem_up(&g_sif_mutex);
soc_dbg_func_exit();
return ret;
}
static td_s32 sif_drv_ioctl_outmode(unsigned int cmd, td_void *arg)
{
switch (cmd) {
case CMD_SIF_SET_OUTMODE: {
sif_out_mode_param *out_mode = (sif_out_mode_param *)arg;
return sif_set_out_mode(out_mode->out_mode);
}
case CMD_SIF_GET_OUTMODE: {
sif_aaos_mode_param *aaos_mode = (sif_aaos_mode_param *)arg;
return sif_get_out_mode(&aaos_mode->aaos_mode);
}
default:
soc_log_err("invalid parameter!\n");
return SOC_ERR_SIF_INVALID_PARA;
}
}
int sif_drv_ioctl_inner(unsigned int cmd, td_void *arg, td_void *private_data)
{
td_s32 ret;
sif_carri_shift_param *carri_shift = (sif_carri_shift_param *)arg;
soc_dbg_func_enter();
if (arg == TD_NULL) {
soc_log_err("arg is null!\n");
return SOC_ERR_SIF_NULL_PTR;
}
ret = osal_sem_down_interruptible(&g_sif_mutex);
if (ret != TD_SUCCESS) {
soc_log_fatal("lock g_sif_mutex failed\n");
return ret;
}
switch (cmd) {
case CMD_SIF_START_ASD:
ret = sif_drv_ioctl_start_asd(arg);
break;
case CMD_SIF_SET_STANDDARD:
case CMD_SIF_GET_ASD_RESULT:
case CMD_SIF_GET_STANDARD:
ret = sif_drv_ioctl_standard_type(cmd, arg);
break;
case CMD_SIF_SET_OVER_DEV:
case CMD_SIF_GET_OVER_DEV:
ret = sif_drv_ioctl_over_deviation(cmd, arg);
break;
case CMD_SIF_SET_CARRI_SHIFT:
ret = sif_set_carri_shift(carri_shift->carri_shift);
break;
case CMD_SIF_SET_OUTMODE:
case CMD_SIF_GET_OUTMODE: /* fall-through */
ret = sif_drv_ioctl_outmode(cmd, arg);
break;
case CMD_SIF_GET_ASD_CMPL:
ret = sif_drv_ioctl_asd_cmpl(arg);
break;
default:
soc_log_err("ERR IOCTL CMD: %#x\n", cmd);
ret = SOC_ERR_SIF_INVALID_PARA;
break;
}
osal_sem_up(&g_sif_mutex);
soc_dbg_func_exit();
return ret;
}
sif_drv_ctx* get_sif_drv_dev(void)
{
return &g_sif_drv_dev;
}