sim_switch.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include <ssw.h>
  2. #include <mach/mtk_ccci_helper.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. #define DUAL_TALK (0x3)
  9. #define DUAL_TALK_SWAP (0x4)
  10. /*----------------Error Code-----------------*/
  11. #define SSW_SUCCESS (0)
  12. #define SSW_INVALID_PARA (-1)
  13. /*--------------Global varible---------------*/
  14. unsigned int sim_mode_curr = SINGLE_TALK_MDSYS;
  15. unsigned int get_sim_switch_type(void)
  16. {
  17. SSW_DBG("[ccci/ssw]SSW_GENERIC\n");
  18. return SSW_INTERN;
  19. }
  20. struct mutex sim_switch_mutex;
  21. static inline void sim_switch_writel(void *addr, unsigned offset, u32 data)
  22. {
  23. *((volatile unsigned int *)(addr + offset)) = data;
  24. }
  25. static inline u32 sim_switch_readl(const void *addr, unsigned offset)
  26. {
  27. u32 rc = 0;
  28. rc = *((volatile unsigned int *)(addr + offset));
  29. return rc;
  30. }
  31. static int set_sim_gpio(unsigned int mode);
  32. static int get_current_ssw_mode(void);
  33. /*---------------------------------------------------------------------------*/
  34. /*define sysfs entry for configuring debug level and sysrq*/
  35. static ssize_t ssw_attr_show(struct kobject *kobj, struct attribute *attr,
  36. char *buffer)
  37. {
  38. struct ssw_sys_entry *entry =
  39. container_of(attr, struct ssw_sys_entry, attr);
  40. return entry->show(kobj, buffer);
  41. }
  42. static ssize_t ssw_attr_store(struct kobject *kobj, struct attribute *attr,
  43. const char *buffer, size_t size)
  44. {
  45. struct ssw_sys_entry *entry =
  46. container_of(attr, struct ssw_sys_entry, attr);
  47. return entry->store(kobj, buffer, size);
  48. }
  49. static ssize_t ssw_mode_show(struct kobject *kobj, char *buffer)
  50. {
  51. int remain = PAGE_SIZE;
  52. int len;
  53. char *ptr = buffer;
  54. len = scnprintf(ptr, remain, "0x%x\n", get_current_ssw_mode());
  55. ptr += len;
  56. remain -= len;
  57. SSW_DBG("ssw_mode_show\n");
  58. return PAGE_SIZE - remain;
  59. }
  60. ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer, size_t size)
  61. {
  62. unsigned int mode;
  63. int res = kstrtoint(buffer, 0, &mode);
  64. unsigned int type;
  65. if (res != 1) {
  66. SSW_DBG("%s: expect 1 numbers\n", __func__);
  67. } else {
  68. SSW_DBG("ssw_mode_store %x\n", mode);
  69. /*Switch sim mode */
  70. if ((sim_mode_curr != mode)
  71. && (SSW_SUCCESS == set_sim_gpio(mode))) {
  72. sim_mode_curr = mode;
  73. }
  74. }
  75. return size;
  76. }
  77. const struct sysfs_ops ssw_sysfs_ops = {
  78. .show = ssw_attr_show,
  79. .store = ssw_attr_store,
  80. };
  81. struct ssw_sys_entry {
  82. struct attribute attr;
  83. ssize_t (*show)(struct kobject *kobj, char *page);
  84. ssize_t (*store)(struct kobject *kobj, const char *page, size_t size);
  85. };
  86. static struct ssw_sys_entry mode_entry = {
  87. {.name = "mode", .mode = S_IRUGO | S_IWUSR}, /*remove .owner = NULL, */
  88. ssw_mode_show,
  89. ssw_mode_store,
  90. };
  91. struct attribute *ssw_attributes[] = {
  92. &mode_entry.attr,
  93. NULL,
  94. };
  95. struct kobj_type ssw_ktype = {
  96. .sysfs_ops = &ssw_sysfs_ops,
  97. .default_attrs = ssw_attributes,
  98. };
  99. static struct ssw_sysobj_t {
  100. struct kobject kobj;
  101. } ssw_sysobj;
  102. int ssw_sysfs_init(void)
  103. {
  104. struct ssw_sysobj_t *obj = &ssw_sysobj;
  105. memset(&obj->kobj, 0x00, sizeof(obj->kobj));
  106. obj->kobj.parent = kernel_kobj;
  107. if (kobject_init_and_add(&obj->kobj, &ssw_ktype, NULL, "mtk_ssw")) {
  108. kobject_put(&obj->kobj);
  109. return -ENOMEM;
  110. }
  111. kobject_uevent(&obj->kobj, KOBJ_ADD);
  112. return 0;
  113. }
  114. /*---------------------------------------------------------------------------*/
  115. int get_current_ssw_mode(void)
  116. {
  117. return sim_mode_curr;
  118. }
  119. static int set_sim_gpio(unsigned int mode)
  120. {
  121. SSW_DBG("set_sim_gpio %d\n", mode);
  122. switch (mode) {
  123. case SINGLE_TALK_MDSYS:
  124. #if defined(GPIO_SIM1_SCLK) && defined(GPIO_SIM1_SIO) && defined(GPIO_SIM2_SCLK) && defined(GPIO_SIM2_SIO)
  125. mt_set_gpio_mode(GPIO_SIM1_SCLK, 1); /*SIM1_SCLK */
  126. mt_set_gpio_mode(GPIO_SIM1_SIO, 1); /*SIM1_SIO */
  127. mt_set_gpio_mode(GPIO_SIM2_SCLK, 1); /*SIM2_SCLK */
  128. mt_set_gpio_mode(GPIO_SIM2_SIO, 1); /*SIM2_SIO */
  129. /*mt_set_gpio_mode(GPIO_SIM1_SRST, 4); SIM1_SRST, 6582 not use reset pin */
  130. /*mt_set_gpio_mode(GPIO_SIM2_SRST, 4); SIM2_SRST, 6582 not use reset pin */
  131. #endif
  132. break;
  133. default:
  134. SSW_DBG("Mode(%d) not supported!!!", mode);
  135. return SSW_INVALID_PARA;
  136. }
  137. #if 0
  138. SSW_DBG
  139. ("Current sim mode(%d), GPIO0_MODE(%d, %d), GPIO1_MODE(%d, %d),
  140. GPIO2_MODE(%d, %d), GPIO3_MODE(%d, %d),
  141. GPIO89_MODE(%d, %d), GPIO90_MODE(%d, %d)\n",
  142. mode, mt_get_gpio_mode(GPIO0), mt_get_gpio_dir(GPIO0),
  143. mt_get_gpio_mode(GPIO1), mt_get_gpio_dir(GPIO1),
  144. mt_get_gpio_mode(GPIO2), mt_get_gpio_dir(GPIO2),
  145. mt_get_gpio_mode(GPIO3), mt_get_gpio_dir(GPIO3),
  146. mt_get_gpio_mode(GPIO89), mt_get_gpio_dir(GPIO89),
  147. mt_get_gpio_mode(GPIO90), mt_get_gpio_dir(GPIO90));
  148. #else
  149. #if defined(GPIO_SIM1_SCLK) && defined(GPIO_SIM1_SIO) && defined(GPIO_SIM2_SCLK) && defined(GPIO_SIM2_SIO)
  150. SSW_DBG
  151. ("Current sim mode(%d), GPIO_SIM1_SCLK_MODE(%d, %d),
  152. GPIO_SIM1_SIO_MODE(%d, %d), GPIO_SIM2_SCLK_MODE(%d, %d),
  153. GPIO_SIM2_SIO_MODE(%d, %d)\n",
  154. mode, mt_get_gpio_mode(GPIO_SIM1_SCLK),
  155. mt_get_gpio_dir(GPIO_SIM1_SCLK), mt_get_gpio_mode(GPIO_SIM1_SIO),
  156. mt_get_gpio_dir(GPIO_SIM1_SIO), mt_get_gpio_mode(GPIO_SIM2_SCLK),
  157. mt_get_gpio_dir(GPIO_SIM2_SCLK), mt_get_gpio_mode(GPIO_SIM2_SIO),
  158. mt_get_gpio_dir(GPIO_SIM2_SIO));
  159. #endif
  160. #endif
  161. return SSW_SUCCESS;
  162. }
  163. int switch_sim_mode(int id, char *buf, unsigned int len)
  164. {
  165. unsigned int mode = *((unsigned int *)buf);
  166. SSW_DBG("sim switch: %d(%d)\n", mode, sim_mode_curr);
  167. mutex_lock(&sim_switch_mutex);
  168. if ((sim_mode_curr != mode) && (SSW_SUCCESS == set_sim_gpio(mode)))
  169. sim_mode_curr = mode;
  170. mutex_unlock(&sim_switch_mutex);
  171. SSW_DBG("sim switch(%d) OK\n", sim_mode_curr);
  172. return 0;
  173. }
  174. /*To decide sim mode according to compile option*/
  175. static int get_sim_mode_init(void)
  176. {
  177. unsigned int sim_mode = 0;
  178. unsigned int md1_enable, md2_enable = 0;
  179. md1_enable = get_modem_is_enabled(MD_SYS1);
  180. md2_enable = get_modem_is_enabled(MD_SYS2);
  181. if (md1_enable) {
  182. sim_mode = SINGLE_TALK_MDSYS;
  183. if (md2_enable)
  184. sim_mode = DUAL_TALK;
  185. } else if (md2_enable)
  186. sim_mode = SINGLE_TALK_MDSYS_LITE;
  187. return sim_mode;
  188. }
  189. /*sim switch hardware initial*/
  190. static int sim_switch_init(void)
  191. {
  192. SSW_DBG("sim_switch_init\n");
  193. /*better to set pull_en and pull_sel first, then mode */
  194. /*if GPIO in sim mode, no need to set direction, because hw has done this when setting mode */
  195. /*
  196. mt_set_gpio_dir(GPIO_SIM1_SCLK, GPIO_DIR_OUT); /*GPIO0->SIM2_CLK, out */
  197. mt_set_gpio_dir(GPIO_SIM1_SIO, GPIO_DIR_IN); /*GPIO1->SIM2_SIO, in */
  198. mt_set_gpio_dir(GPIO_SIM2_SCLK, GPIO_DIR_OUT); /*GPIO2->SIM1_CLK, out */
  199. mt_set_gpio_dir(GPIO_SIM2_SIO, GPIO_DIR_IN); /*GPIO3->SIM1_SIO, in */
  200. */
  201. /*mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); GPIO89->SIM1_SRST, out, 6572 not use reset pin */
  202. /*mt_set_gpio_dir(GPIO90, GPIO_DIR_OUT); GPIO90->SIM2_SRST, out, 6572 not use reset pin */
  203. sim_mode_curr = get_sim_mode_init();
  204. if (SSW_SUCCESS != set_sim_gpio(sim_mode_curr)) {
  205. SSW_DBG("sim_switch_init fail\n");
  206. return SSW_INVALID_PARA;
  207. }
  208. return 0;
  209. }
  210. static int sim_switch_probe(struct platform_device *dev)
  211. {
  212. SSW_DBG("Enter sim_switch_probe\n");
  213. /*sim_switch_init(); */
  214. /*move this to sim_switch_driver_init(). Because this function not exceute on device tree branch. */
  215. /*mutex_init(&sim_switch_mutex); */
  216. /*register_ccci_kern_func(ID_SSW_SWITCH_MODE, switch_sim_mode); */
  217. return 0;
  218. }
  219. static int sim_switch_remove(struct platform_device *dev)
  220. {
  221. /*SSW_DBG("sim_switch_remove\n"); */
  222. return 0;
  223. }
  224. static void sim_switch_shutdown(struct platform_device *dev)
  225. {
  226. /*SSW_DBG("sim_switch_shutdown\n"); */
  227. }
  228. static int sim_switch_suspend(struct platform_device *dev, pm_message_t state)
  229. {
  230. /*SSW_DBG("sim_switch_suspend\n"); */
  231. return 0;
  232. }
  233. static int sim_switch_resume(struct platform_device *dev)
  234. {
  235. /*SSW_DBG("sim_switch_resume\n"); */
  236. return 0;
  237. }
  238. static struct platform_driver sim_switch_driver = {
  239. .driver = {
  240. .name = "sim-switch",
  241. },
  242. .probe = sim_switch_probe,
  243. .remove = sim_switch_remove,
  244. .shutdown = sim_switch_shutdown,
  245. .suspend = sim_switch_suspend,
  246. .resume = sim_switch_resume,
  247. };
  248. static int __init sim_switch_driver_init(void)
  249. {
  250. int ret = 0;
  251. SSW_DBG("sim_switch_driver_init\n");
  252. ret = platform_driver_register(&sim_switch_driver);
  253. if (ret) {
  254. SSW_DBG("ssw_driver register fail(%d)\n", ret);
  255. return ret;
  256. }
  257. mutex_init(&sim_switch_mutex);
  258. #if __ENABLE_SSW_SYSFS
  259. ssw_sysfs_init();
  260. #endif
  261. sim_switch_init();
  262. return ret;
  263. }
  264. static void __exit sim_switch_driver_exit(void)
  265. {
  266. }
  267. module_init(sim_switch_driver_init);
  268. module_exit(sim_switch_driver_exit);
  269. MODULE_DESCRIPTION("MTK SIM Switch Driver");
  270. MODULE_AUTHOR("Anny <Anny.Hu@mediatek.com>");
  271. MODULE_LICENSE("GPL");