ccci_ld_md_tel.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <sys/types.h>
  32. #include <ctype.h>
  33. #include <stdint.h>
  34. #include <platform/partition.h>
  35. #include <platform/mt_typedefs.h>
  36. #include <platform/boot_mode.h>
  37. #include <platform/mt_reg_base.h>
  38. #include <platform/errno.h>
  39. #include <printf.h>
  40. #include <string.h>
  41. #include <malloc.h>
  42. #include <libfdt.h>
  43. #include <platform/mt_gpt.h>
  44. #include <debug.h>
  45. #include "ccci_ld_md_core.h"
  46. #include "ccci_ld_md_errno.h"
  47. #include <lk_load_md_wrapper.h>
  48. #include <fdt_op.h>
  49. #include <lk_builtin_dtb.h>
  50. #define MODULE_NAME "LK_LD_MD"
  51. /***************************************************************************************************
  52. ** Sub section:
  53. ** Telephony operation parsing and prepare part
  54. ***************************************************************************************************/
  55. /* For the following option setting, please check config.h after build, or $project.mk */
  56. #ifdef MTK_PROTOCOL1_RAT_CONFIG
  57. #define PS1_RAT_DEFAULT MTK_PROTOCOL1_RAT_CONFIG
  58. #else
  59. #define PS1_RAT_DEFAULT ""
  60. #endif
  61. /**************************************************************************************************************/
  62. /* Global variable or table at this file */
  63. /**************************************************************************************************************/
  64. static struct plat_info default_plat_info[] = {
  65. {"mediatek,MT6570", MD1}, {"mediatek,MT6580", 0}, {"mediatek,MT6763", MD1}, {"mediatek,MT6753", MD1|MD3}, {"mediatek,MT6755", MD1|MD3},
  66. {"mediatek,MT6735", MD1}, {"mediatek,MT6737", MD1}, {"mediatek,MT6750", MD1|MD3}, {"mediatek,MT6757", MD1|MD3},
  67. {"mediatek,MT6739", MD1}, {"mediatek,MT6761", MD1}, {"mediatek,MT6765", MD1}, {"mediatek,MT6768", MD1},
  68. {"mediatek,MT6771", MD1}, {"mediatek,mt6779", MD1}, {"mediatek,MT6785", MD1}, {"mediatek,mt6833", MD1},
  69. {"mediatek,MT6853", MD1}, {"mediatek,MT6873", MD1}, {"mediatek,MT6885", MD1}, {"mediatek,mt6893", MD1},
  70. };
  71. static int strcasecmp(const char *s1, const char *s2)
  72. {
  73. int c1, c2;
  74. do {
  75. c1 = tolower(*s1++);
  76. c2 = tolower(*s2++);
  77. } while (c1 == c2 && c1 != 0);
  78. return c1 - c2;
  79. }
  80. static int radio_cfg_by_name(void *fdt, int offset, char name[])
  81. {
  82. int len = 0;
  83. const void *fdt_tmp;
  84. fdt_tmp = fdt_getprop(fdt, offset, name, &len);
  85. if (!fdt_tmp || !len)
  86. return -1;
  87. return (int)fdt32_to_cpu(*(unsigned int *)fdt_tmp);
  88. }
  89. static char* get_plat_form_dt(void *fdt)
  90. {
  91. int nodeoffset;
  92. int len = 0;
  93. const void* fdt_tmp;
  94. nodeoffset = fdt_path_offset(fdt, "/");
  95. fdt_tmp = fdt_getprop(fdt, nodeoffset, "compatible", &len);
  96. if (!fdt_tmp || !len)
  97. return NULL;
  98. return (char *)(fdt_tmp);
  99. }
  100. static int radio_cap_dts_confirm(void *fdt, int offset, char name[])
  101. {
  102. int len = 0;
  103. const void *fdt_tmp;
  104. fdt_tmp = fdt_getprop(fdt, offset, "compatible", &len);
  105. if (!fdt_tmp || !len)
  106. return -1;
  107. if (strcmp((char*)fdt_tmp, name))
  108. return -1;
  109. return 0;
  110. }
  111. struct radio_md_cap_bit {
  112. char *key;
  113. unsigned int bit;
  114. };
  115. static struct radio_md_cap_bit radio_cap_bitmap_table[] =
  116. {
  117. {"radio_md_g_en", MD_CAP_GSM},
  118. {"radio_md_w_en", MD_CAP_WCDMA},
  119. {"radio_md_t_en", MD_CAP_TDS_CDMA},
  120. {"radio_md_c_en", MD_CAP_CDMA2000},
  121. {"radio_md_lf_en", MD_CAP_FDD_LTE},
  122. {"radio_md_lt_en", MD_CAP_TDD_LTE},
  123. {"radio_md_nr_en", MD_CAP_NR},
  124. };
  125. static int get_radio_cfg_from_dt(void *fdt, unsigned int *radio_cap_bitmap)
  126. {
  127. int nodeoffset;
  128. int ret;
  129. unsigned int i;
  130. if (!radio_cap_bitmap) {
  131. ALWAYS_LOG("cap bitmap is NULL\n");
  132. return -1;
  133. }
  134. nodeoffset = fdt_path_offset(fdt, "/radio_md_cfg");
  135. if (nodeoffset < 0) {
  136. ALWAYS_LOG("/radio_md_cfg disable at dts\n");
  137. return -1;
  138. }
  139. if (radio_cap_dts_confirm(fdt, nodeoffset, "mediatek,radio_md_cfg")) {
  140. ALWAYS_LOG("/radio_md_cfg compatible disable at dts\n");
  141. return -1;
  142. }
  143. for (i = 0; i < sizeof(radio_cap_bitmap_table)/sizeof(struct radio_md_cap_bit); i++) {
  144. ret = radio_cfg_by_name(fdt, nodeoffset, radio_cap_bitmap_table[i].key);
  145. if (ret < 0) {
  146. ALWAYS_LOG("radio cap:%s using default\n", radio_cap_bitmap_table[i].key);
  147. return -1;
  148. }
  149. if (ret > 0)
  150. *radio_cap_bitmap |= radio_cap_bitmap_table[i].bit;
  151. }
  152. return 0;
  153. }
  154. /**************************************************************************************************/
  155. /* Local function for telephony */
  156. /**************************************************************************************************/
  157. static unsigned int get_capability_bit(char cap_str[])
  158. {
  159. if (cap_str == NULL)
  160. return 0;
  161. if ((strcmp(cap_str, "LF") == 0) || (strcmp(cap_str, "Lf") == 0) || (strcmp(cap_str, "lf") == 0))
  162. return MD_CAP_FDD_LTE;
  163. if ((strcmp(cap_str, "LT") == 0) || (strcmp(cap_str, "Lt") == 0) || (strcmp(cap_str, "lt") == 0))
  164. return MD_CAP_TDD_LTE;
  165. if ((strcmp(cap_str, "W") == 0) || (strcmp(cap_str, "w") == 0))
  166. return MD_CAP_WCDMA;
  167. if ((strcmp(cap_str, "C") == 0) || (strcmp(cap_str, "c") == 0))
  168. return MD_CAP_CDMA2000;
  169. if ((strcmp(cap_str, "T") == 0) || (strcmp(cap_str, "t") == 0))
  170. return MD_CAP_TDS_CDMA;
  171. if ((strcmp(cap_str, "G") == 0) || (strcmp(cap_str, "g") == 0))
  172. return MD_CAP_GSM;
  173. return 0;
  174. }
  175. #define MAX_CAP_STR_LENGTH 16
  176. static unsigned int get_capablity_bit_map(char str[])
  177. {
  178. char tmp_str[MAX_CAP_STR_LENGTH];
  179. int tmp_str_curr_pos = 0;
  180. unsigned int capability_bit_map = 0;
  181. int str_len;
  182. int i;
  183. if (str == NULL)
  184. return 0;
  185. str_len = strlen(str);
  186. for (i = 0; i < str_len; i++) {
  187. if (str[i] == ' ')
  188. continue;
  189. if (str[i] == '\t')
  190. continue;
  191. if ((str[i] == '/') || (str[i] == '_')) {
  192. if (tmp_str_curr_pos) {
  193. tmp_str[tmp_str_curr_pos] = 0;
  194. capability_bit_map |= get_capability_bit(tmp_str);
  195. }
  196. tmp_str_curr_pos = 0;
  197. continue;
  198. }
  199. if (tmp_str_curr_pos < (MAX_CAP_STR_LENGTH-1)) {
  200. tmp_str[tmp_str_curr_pos] = str[i];
  201. tmp_str_curr_pos++;
  202. } else
  203. break;
  204. }
  205. if (tmp_str_curr_pos) {
  206. tmp_str[tmp_str_curr_pos] = 0;
  207. capability_bit_map |= get_capability_bit(tmp_str);
  208. }
  209. return capability_bit_map;
  210. }
  211. static int get_md_bitmap(unsigned int tel_cap_bit_map, struct plat_info plat_list[], int num)
  212. {
  213. int i;
  214. const void *fdt_plat;
  215. fdt_plat = get_plat_form_dt(get_lk_overlayed_dtb());
  216. if (!fdt_plat) {
  217. ALWAYS_LOG("error: fdt_plat is NULL; no platform matched\n");
  218. return 0;
  219. }
  220. if (tel_cap_bit_map) {
  221. for (i = 0; i < num; i++) {
  222. if (!strcasecmp(fdt_plat , plat_list[i].plat_name)) {
  223. if (plat_list[i].md_bitmap == MD1)
  224. return MD1;
  225. if (plat_list[i].md_bitmap == (MD1|MD3)){
  226. if(tel_cap_bit_map & MD_CAP_CDMA2000)
  227. return MD1|MD3;
  228. else
  229. return MD1;
  230. }
  231. }
  232. }
  233. if (i == num) {
  234. ALWAYS_LOG("no platform matched\n");
  235. return 0;
  236. }
  237. }
  238. return 0;
  239. }
  240. int ccci_ld_md_tel_init(void)
  241. {
  242. #ifndef LK_NO_SUPPORT_MD_CCCI
  243. int md_bitmap = 0;
  244. unsigned int default_cap_bit_map, dts_cap_bitmap;
  245. unsigned int plat_num = sizeof(default_plat_info)/sizeof(struct plat_info);
  246. /* Prepare default option setting */
  247. dts_cap_bitmap = 0;
  248. if (get_radio_cfg_from_dt(get_lk_overlayed_dtb(), &dts_cap_bitmap) < 0)
  249. default_cap_bit_map = get_capablity_bit_map(PS1_RAT_DEFAULT);
  250. else
  251. default_cap_bit_map = dts_cap_bitmap;
  252. if (default_cap_bit_map)
  253. md_bitmap = get_md_bitmap(default_cap_bit_map, default_plat_info, plat_num);
  254. #endif
  255. return md_bitmap;
  256. }