sim_switch.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #include <ssw.h>
  2. #include <mt-plat/mt_ccci_common.h>
  3. /*--------------Feature option---------------*/
  4. #define __ENABLE_SSW_SYSFS 1
  5. /*--------------SIM mode list----------------*/
  6. #define SINGLE_TALK_MDSYS (0x1)
  7. #define SINGLE_TALK_MDSYS_LITE (0x2)
  8. /*----------------variable define-----------------*/
  9. unsigned int sim_mode_curr = SINGLE_TALK_MDSYS;
  10. struct mutex sim_switch_mutex;
  11. struct pinctrl *ssw_pinctrl = NULL;
  12. struct pinctrl_state *hot_plug_mode1 = NULL;
  13. struct pinctrl_state *hot_plug_mode2 = NULL;
  14. struct pinctrl_state *two_sims_bound_to_md1 = NULL;
  15. struct pinctrl_state *sim1_md3_sim2_md1 = NULL;
  16. static int set_sim_gpio(unsigned int mode);
  17. static int get_current_ssw_mode(void)
  18. {
  19. return sim_mode_curr;
  20. }
  21. unsigned int get_sim_switch_type(void)
  22. {
  23. pr_debug("[ccci/ssw]ssw_single_v2\n");
  24. return SSW_INTERN;
  25. }
  26. /*---------------------------------------------------------------------------*/
  27. /*define sysfs entry for configuring debug level and sysrq*/
  28. static ssize_t ssw_attr_show(struct kobject *kobj, struct attribute *attr,
  29. char *buffer);
  30. static ssize_t ssw_attr_store(struct kobject *kobj, struct attribute *attr,
  31. const char *buffer, size_t size);
  32. static ssize_t ssw_mode_show(struct kobject *kobj, char *page);
  33. static ssize_t ssw_mode_store(struct kobject *kobj, const char *page,
  34. size_t size);
  35. const struct sysfs_ops ssw_sysfs_ops = {
  36. .show = ssw_attr_show,
  37. .store = ssw_attr_store,
  38. };
  39. struct ssw_sys_entry {
  40. struct attribute attr;
  41. ssize_t (*show)(struct kobject *kobj, char *page);
  42. ssize_t (*store)(struct kobject *kobj, const char *page, size_t size);
  43. };
  44. static struct ssw_sys_entry mode_entry = {
  45. {.name = "mode", .mode = S_IRUGO | S_IWUSR}, /*remove .owner = NULL, */
  46. ssw_mode_show,
  47. ssw_mode_store,
  48. };
  49. struct attribute *ssw_attributes[] = {
  50. &mode_entry.attr,
  51. NULL,
  52. };
  53. struct kobj_type ssw_ktype = {
  54. .sysfs_ops = &ssw_sysfs_ops,
  55. .default_attrs = ssw_attributes,
  56. };
  57. static struct ssw_sysobj_t {
  58. struct kobject kobj;
  59. } ssw_sysobj;
  60. int ssw_sysfs_init(void)
  61. {
  62. struct ssw_sysobj_t *obj = &ssw_sysobj;
  63. memset(&obj->kobj, 0x00, sizeof(obj->kobj));
  64. obj->kobj.parent = kernel_kobj;
  65. if (kobject_init_and_add(&obj->kobj, &ssw_ktype, NULL, "mtk_ssw")) {
  66. kobject_put(&obj->kobj);
  67. return -ENOMEM;
  68. }
  69. kobject_uevent(&obj->kobj, KOBJ_ADD);
  70. return 0;
  71. }
  72. static ssize_t ssw_attr_show(struct kobject *kobj, struct attribute *attr,
  73. char *buffer)
  74. {
  75. struct ssw_sys_entry *entry =
  76. container_of(attr, struct ssw_sys_entry, attr);
  77. return entry->show(kobj, buffer);
  78. }
  79. static ssize_t ssw_attr_store(struct kobject *kobj, struct attribute *attr,
  80. const char *buffer, size_t size)
  81. {
  82. struct ssw_sys_entry *entry =
  83. container_of(attr, struct ssw_sys_entry, attr);
  84. return entry->store(kobj, buffer, size);
  85. }
  86. static ssize_t ssw_mode_show(struct kobject *kobj, char *buffer)
  87. {
  88. int remain = PAGE_SIZE;
  89. int len;
  90. char *ptr = buffer;
  91. len = scnprintf(ptr, remain, "0x%x\n", get_current_ssw_mode());
  92. ptr += len;
  93. remain -= len;
  94. SSW_DBG("ssw_mode_show\n");
  95. return PAGE_SIZE - remain;
  96. }
  97. static ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer,
  98. size_t size)
  99. {
  100. unsigned int mode;
  101. int res = kstrtoint(buffer, 0, &mode);
  102. unsigned int type;
  103. if (res != 1) {
  104. SSW_DBG("%s: expect 1 numbers\n", __func__);
  105. } else {
  106. SSW_DBG("ssw_mode_store %x\n", mode);
  107. /*Switch sim mode */
  108. type = (mode & 0xFFFF0000) >> 16;
  109. mode = mode & 0x0000FFFF;
  110. if (type == 0) { /*Internal */
  111. SSW_DBG("Internal sim switch: %d-->%d\n", sim_mode_curr,
  112. mode);
  113. if ((sim_mode_curr != mode)
  114. && (SSW_SUCCESS == set_sim_gpio(mode)))
  115. sim_mode_curr = mode;
  116. }
  117. }
  118. return size;
  119. }
  120. /*---------------------------------------------------------------------------*/
  121. /*************************************************************************/
  122. /*sim switch hardware operation */
  123. /*************************************************************************/
  124. static int set_sim_gpio(unsigned int mode)
  125. {
  126. SSW_DBG("set_sim_gpio: %d\n", mode);
  127. switch (mode) {
  128. case SINGLE_TALK_MDSYS:
  129. if (NULL != hot_plug_mode1)
  130. pinctrl_select_state(ssw_pinctrl, hot_plug_mode1);
  131. else
  132. SSW_DBG("hot_plug_mode1 not exist.\n");
  133. /*SIM1=> MD1 SIM1IF */
  134. /*SIM2=> MD1 SIM2IF */
  135. pinctrl_select_state(ssw_pinctrl, two_sims_bound_to_md1);
  136. break;
  137. case SINGLE_TALK_MDSYS_LITE:
  138. if (NULL != hot_plug_mode2)
  139. pinctrl_select_state(ssw_pinctrl, hot_plug_mode2);
  140. else
  141. SSW_DBG("hot_plug_mode2 not exist.\n");
  142. /*SIM1=> MD1 SIM1IF */
  143. /*SIM2=> MD1 SIM2IF */
  144. pinctrl_select_state(ssw_pinctrl, sim1_md3_sim2_md1);
  145. break;
  146. default:
  147. SSW_DBG("[Error] Invalid Mode(%d)", mode);
  148. return SSW_INVALID_PARA;
  149. }
  150. return SSW_SUCCESS;
  151. }
  152. int switch_sim_mode(int id, char *buf, unsigned int len)
  153. {
  154. unsigned int mode = *((unsigned int *)buf);
  155. unsigned int type = (mode & 0xFFFF0000) >> 16;
  156. SSW_DBG("switch_sim_mode:mode=0x%x, type=%d\n", mode, type);
  157. mode = mode & 0x0000FFFF;
  158. mutex_lock(&sim_switch_mutex);
  159. if (type == 0) { /*Internal */
  160. SSW_DBG("Internal sim switch: %d --> %d\n", sim_mode_curr,
  161. mode);
  162. if ((sim_mode_curr != mode)
  163. && (SSW_SUCCESS == set_sim_gpio(mode)))
  164. sim_mode_curr = mode;
  165. }
  166. mutex_unlock(&sim_switch_mutex);
  167. SSW_DBG("sim switch sim_mode_curr(%d)OK\n", sim_mode_curr);
  168. return 0;
  169. }
  170. /*To decide sim mode according to compile option */
  171. static int get_sim_mode_init(void)
  172. {
  173. unsigned int sim_mode = 0;
  174. #ifdef CONFIG_MTK_SVLTE_SUPPORT
  175. sim_mode = SINGLE_TALK_MDSYS;
  176. #else
  177. #ifdef CONFIG_EVDO_DT_SUPPORT
  178. sim_mode = SINGLE_TALK_MDSYS_LITE;
  179. #else
  180. sim_mode = SINGLE_TALK_MDSYS;
  181. #endif
  182. #endif
  183. return sim_mode;
  184. }
  185. /*sim switch hardware initial */
  186. static int sim_switch_init(void)
  187. {
  188. SSW_DBG("sim_switch_init\n");
  189. sim_mode_curr = get_sim_mode_init();
  190. if (SSW_SUCCESS != set_sim_gpio(sim_mode_curr)) {
  191. SSW_DBG("sim_switch_init fail\n");
  192. return SSW_INVALID_PARA;
  193. }
  194. return 0;
  195. }
  196. static int sim_switch_probe(struct platform_device *dev)
  197. {
  198. ssw_pinctrl = devm_pinctrl_get(&dev->dev);
  199. if (IS_ERR(ssw_pinctrl)) {
  200. SSW_DBG("cannot find ssw pinctrl.\n");
  201. return PTR_ERR(ssw_pinctrl);
  202. }
  203. hot_plug_mode1 = pinctrl_lookup_state(ssw_pinctrl, "hot_plug_mode1");
  204. two_sims_bound_to_md1 =
  205. pinctrl_lookup_state(ssw_pinctrl, "two_sims_bound_to_md1");
  206. hot_plug_mode2 = pinctrl_lookup_state(ssw_pinctrl, "hot_plug_mode2");
  207. sim1_md3_sim2_md1 =
  208. pinctrl_lookup_state(ssw_pinctrl, "sim1_md3_sim2_md1");
  209. SSW_DBG("Enter sim_switch_probe\n");
  210. mutex_init(&sim_switch_mutex);
  211. #if __ENABLE_SSW_SYSFS
  212. ssw_sysfs_init();
  213. #endif
  214. sim_switch_init();
  215. return 0;
  216. }
  217. static int sim_switch_remove(struct platform_device *dev)
  218. {
  219. /*SSW_DBG("sim_switch_remove\n"); */
  220. return 0;
  221. }
  222. static void sim_switch_shutdown(struct platform_device *dev)
  223. {
  224. /*SSW_DBG("sim_switch_shutdown\n"); */
  225. }
  226. static int sim_switch_suspend(struct platform_device *dev, pm_message_t state)
  227. {
  228. /*SSW_DBG("sim_switch_suspend\n"); */
  229. return 0;
  230. }
  231. static int sim_switch_resume(struct platform_device *dev)
  232. {
  233. /*SSW_DBG("sim_switch_resume\n"); */
  234. return 0;
  235. }
  236. #ifdef CONFIG_OF
  237. static const struct of_device_id ssw_of_ids[] = {
  238. {.compatible = "mediatek,sim_switch",},
  239. {}
  240. };
  241. #endif
  242. static struct platform_driver sim_switch_driver = {
  243. .driver = {
  244. .name = "sim-switch",
  245. },
  246. .probe = sim_switch_probe,
  247. .remove = sim_switch_remove,
  248. .shutdown = sim_switch_shutdown,
  249. .suspend = sim_switch_suspend,
  250. .resume = sim_switch_resume,
  251. };
  252. static int __init sim_switch_driver_init(void)
  253. {
  254. int ret = 0;
  255. #ifdef CONFIG_OF
  256. sim_switch_driver.driver.of_match_table = ssw_of_ids;
  257. #endif
  258. SSW_DBG("sim_switch_driver_init\n");
  259. ret = platform_driver_register(&sim_switch_driver);
  260. if (ret) {
  261. SSW_DBG("ssw_driver register fail(%d)\n", ret);
  262. return ret;
  263. }
  264. return ret;
  265. }
  266. static void __exit sim_switch_driver_exit(void)
  267. {
  268. }
  269. module_init(sim_switch_driver_init);
  270. module_exit(sim_switch_driver_exit);
  271. MODULE_DESCRIPTION("MTK SIM Switch Driver");
  272. MODULE_AUTHOR("MTK");
  273. MODULE_LICENSE("GPL");