blob: 42587d716d60454259171b212d77f8cd62ae5c22 [file] [log] [blame]
#include "custom_port.h"
#include "kal_public_defs.h"
#include "kal_general_types.h"
#include "kal_public_api.h"
#include "fs_general_types.h"
#include "fs_general_api.h"
#if defined(__MTK_TARGET__) && defined(__HIF_PCIE_SUPPORT__)
extern kal_uint32 pcie_get_link_state(void);
#else
#define pcie_get_link_state(...) (-1)
#define index(...) (NULL)
#endif
// 76543210 76543210 76543210 76543210
// XXX YY AZ
//
// XXX (MODE) ==> PORT_MODE_NONE or PORT_MODE_USB or PORT_MODE_PCIE or PORT_MODE_USB_AND_PCIE or PORT_MODE_AP
// YY (DIPC configuration) ==> PORT_DIPC_MODE_NOT_SUPPORT or PORT_DIPC_MODE_PCIE_ONLY or PORT_DIPC_MODE_PCIE_ADVANCE or PORT_DIPC_MODE_DUAL_IPC
// A (port enable/disable on PCIE) ==> PORT_PCIE_DISABLE or PORT_PCIE_ENABLE
// Z (pcie link status) ==> PORT_PCIE_STATUS_LINK_DOWN or PORT_PCIE_STATUS_LINK_UP
#if !defined(__DHL_TRACE_ENABLED__)
#define kal_prompt_trace(...)
#endif
#define FILEPATH_SIZE (128)
#define BUFFER_SIZE (1024)
kal_uint32 custom_port(custom_port_user_enum port)
{
kal_uint32 ret = 0;
#if defined(__HIF_USB_SUPPORT__) && defined(__HIF_PCIE_SUPPORT__)
//DUAL IPC load
static kal_bool first = KAL_TRUE;
FS_HANDLE file_handle;
static kal_uint32 config_dual_ipc_mode = PORT_DIPC_MODE_NOT_SUPPORT;
static kal_uint32 config_md_logging_interface = PORT_MODE_NONE;
static kal_uint32 config_md_at_interface = PORT_MODE_PCIE;
static kal_uint32 config_md_pcie_port = 0xffffffff;
kal_uint32 pcie_link_ready = (pcie_get_link_state() == 0) ? 1 : 0;
if (first) {
kal_wchar *filepath = NULL;
kal_uint8 *buffer = NULL;
do {
filepath = (kal_wchar *)get_ctrl_buffer(FILEPATH_SIZE);
buffer = (kal_uint8 *)get_ctrl_buffer(BUFFER_SIZE);
if (filepath == NULL || buffer == NULL) {
//cannot allocate memory for operation
break;
}
kal_wsprintf(filepath, "%s", DIPC_CONFIG_PATH);
if ((file_handle = FS_Open(filepath, FS_READ_ONLY | FS_OPEN_NO_DIR)) >= FS_NO_ERROR) {
kal_uint32 read_size;
memset(buffer, 0, BUFFER_SIZE);
if (FS_Read(file_handle, buffer, BUFFER_SIZE - 1, &read_size) >= FS_NO_ERROR) {
kal_prompt_trace(MOD_NIL, "XXXX %s:%d read_size=%d", __FILE__, __LINE__, read_size);
kal_uint8 *cur_ptr = &buffer[0];
kal_uint8 *tail_ptr = &buffer[read_size];
while (cur_ptr < tail_ptr) {
kal_uint8 key[32];
kal_uint32 val;
kal_uint8 *next_ptr = (kal_uint8 *)index((char *)cur_ptr, '\n');
kal_uint8 *delim_ptr;
if (next_ptr == NULL) {
break;
}
*next_ptr = '\0';
delim_ptr = (kal_uint8 *)index((char *)cur_ptr, ':');
if (delim_ptr == NULL) {
break;
}
*delim_ptr++ = '\0';
sscanf((char *)cur_ptr, "%s\n", (char *)key);
sscanf((char *)delim_ptr, "%u\n", &val);
cur_ptr = next_ptr + 1;
kal_prompt_trace(MOD_NIL, "[%s][%x]", key, val);
if (strcmp(KEY_DUAL_IPC_MODE, (char *)key) == 0) {
switch(val) {
case DIPC_MODE_NOT_CONFIG:
config_dual_ipc_mode = PORT_DIPC_MODE_NOT_SUPPORT;
break;
case DIPC_MODE_PCIE_ADV:
config_dual_ipc_mode = PORT_DIPC_MODE_PCIE_ADVANCE;
break;
case DIPC_MODE_PCIE_ONLY:
config_dual_ipc_mode = PORT_DIPC_MODE_PCIE_ONLY;
break;
case DIPC_MODE_DUAL_IPC:
config_dual_ipc_mode = PORT_DIPC_MODE_DUAL_IPC;
break;
case DIPC_MODE_USB_ONLY:
config_dual_ipc_mode = PORT_DIPC_MODE_USB_ONLY;
break;
}
} else if (strcmp(KEY_MD_LOGGING_INTERFACE, (char *)key) == 0) {
switch(val) {
case DIPC_INTF_USB:
config_md_logging_interface = PORT_MODE_USB;
break;
case DIPC_INTF_PCIE:
config_md_logging_interface = PORT_MODE_PCIE;
break;
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
default:
config_md_logging_interface = PORT_MODE_NONE;
break;
}
} else if (strcmp(KEY_MD_AT_INTERFACE, (char *)key) == 0) {
switch(val) {
case DIPC_INTF_USB:
config_md_at_interface = PORT_MODE_USB;
break;
case DIPC_INTF_PCIE:
config_md_at_interface = PORT_MODE_PCIE;
break;
default:
config_md_at_interface = PORT_MODE_PCIE;
break;
}
} else if (strcmp(KEY_MD_PCIE_PORT_CONFIG, (char *)key) == 0) {
if ((val & DIPC_CONFIG_MD_PORT_LOGGING) == 0) {
config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_LOG);
}
if ((val & DIPC_CONFIG_MD_PORT_META) == 0) {
config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_META);
}
if ((val & DIPC_CONFIG_MD_PORT_BINARY_TOOL) == 0) {
config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_BINARY_TOOL);
config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_MIPC);
}
if ((val & DIPC_CONFIG_MD_PORT_AT) == 0) {
config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_AT);
}
}
}
}
FS_Close(file_handle);
}
first = KAL_FALSE;
} while(0);
if (filepath) {
free_ctrl_buffer(filepath);
filepath = NULL;
}
if (buffer) {
free_ctrl_buffer(buffer);
buffer = NULL;
}
}
if (config_md_pcie_port & (1 << port)) {
ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
}
switch (config_dual_ipc_mode) {
case PORT_DIPC_MODE_PCIE_ADVANCE:
if (pcie_link_ready) {
if (config_md_pcie_port & (1 << port)) {
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
} else {
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
}
} else {
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
}
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
case PORT_DIPC_MODE_PCIE_ONLY:
if (config_md_pcie_port & (1 << port)) {
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
} else {
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
}
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
case PORT_DIPC_MODE_DUAL_IPC:
if (pcie_link_ready) {
switch (port) {
case CUSTOM_PORT_USER_AT:
ret |= (config_md_at_interface << PORT_MODE_SHIFT);
break;
case CUSTOM_PORT_USER_LOG:
if (config_md_logging_interface == PORT_MODE_USB) {
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
} else if ((config_md_logging_interface == PORT_MODE_PCIE) && (config_md_pcie_port & (1 << port))) {
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
} else {
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
}
break;
case CUSTOM_PORT_USER_META:
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
break;
default:
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
break;
}
} else {
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
}
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
case PORT_DIPC_MODE_USB_ONLY:
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
case PORT_DIPC_MODE_NOT_SUPPORT:
if (port == CUSTOM_PORT_USER_LOG) {
#if defined(__ELT_SET_PORT_TO_USB__)
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
#elif defined(__ELT_SET_PORT_TO_PCIE__)
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
#elif defined(__ELT_SET_PORT_TO_DUAL_IPC__)
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
#else
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
#endif
} else if (port == CUSTOM_PORT_USER_META) {
#if defined(__META_SET_PORT_TO_USB__)
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
#elif defined(__META_SET_PORT_TO_PCIE__)
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
#elif defined(__META_SET_PORT_TO_DUAL_IPC__)
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
#else
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
#endif
} else {
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
}
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
default:
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
return ret;
}
#elif defined(__HIF_USB_SUPPORT__)
//support USB only
ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
return ret;
#elif defined(__HIF_PCIE_SUPPORT__)
//support PCIE only
ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
return ret;
#else
#if defined(__ANDROID_MODEM__)
//SP
ret |= (PORT_MODE_AP << PORT_MODE_SHIFT);
return ret;
#else
ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
return ret;
#endif
#endif
}