sim_switch.c 9.4 KB

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