combo_fxla2203_driver.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #include "cust_ssw.h"
  2. #include <ssw.h>
  3. #include <mach/mtk_ccci_helper.h>
  4. #include "cust_gpio_usage.h"
  5. #ifdef MTK_PCA9575A_SUPPORT
  6. #include "cust_pca9575.h"
  7. #endif
  8. /*--------------Feature option---------------*/
  9. #define __ENABLE_SSW_SYSFS 1
  10. /*--------------SIM mode list----------------*/
  11. #define SINGLE_TALK_MDSYS (0x1)
  12. #define SINGLE_TALK_MDSYS_LITE (0x2)
  13. #define DUAL_TALK (0x3)
  14. #define DUAL_TALK_SWAP (0x4)
  15. static unsigned int ext_ssw_mode_curr = SSW_DUAL_TALK;
  16. static unsigned int ch_swap;
  17. static unsigned int en;
  18. static unsigned int sim_mode_curr = SINGLE_TALK_MDSYS;
  19. struct mutex sim_switch_mutex;
  20. static int sim_switch_init(void);
  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. static int get_ext_current_ssw_mode(void);
  34. unsigned int get_sim_switch_type(void)
  35. {
  36. SSW_DBG("[ccci/ssw]COMBO_FXLA2203\n");
  37. return SSW_EXT_FXLA2203;
  38. }
  39. /*---------------------------------------------------------------------------*/
  40. /*define sysfs entry for configuring debug level and sysrq*/
  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 =
  61. scnprintf(ptr, remain, "I:0x%x E:0x%x\n", get_current_ssw_mode(),
  62. get_ext_current_ssw_mode());
  63. ptr += len;
  64. remain -= len;
  65. SSW_DBG("ssw_mode_show\n");
  66. return PAGE_SIZE - remain;
  67. }
  68. #ifdef MTK_PCA9575A_SUPPORT
  69. ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer, size_t size)
  70. {
  71. unsigned int mode;
  72. int res = kstrtoint(buffer, 0, &mode);
  73. unsigned int type;
  74. if (res != 1) {
  75. SSW_DBG("%s: expect 1 numbers\n", __func__);
  76. } else {
  77. SSW_DBG("ssw_mode_store %x\n", mode);
  78. /*Switch sim mode */
  79. type = (mode & 0xFFFF0000) >> 16;
  80. mode = mode & 0x0000FFFF;
  81. if (type == 0) { /*Internal */
  82. SSW_DBG("Internal sim switch: %d-->%d\n", sim_mode_curr,
  83. mode);
  84. if ((sim_mode_curr != mode)
  85. && (SSW_SUCCESS == set_sim_gpio(mode))) {
  86. sim_mode_curr = mode;
  87. }
  88. } else {
  89. SSW_DBG("External sim switch: %d-->%d\n",
  90. ext_ssw_mode_curr, mode);
  91. if (mode == SSW_DUAL_TALK) {
  92. /*mt_set_gpio_out(ch_swap, SSW_DUAL_TALK); */
  93. pca9575_set_gpio_output(ch_swap, SSW_DUAL_TALK);
  94. } else if (mode == SSW_SING_TALK) {
  95. pca9575_set_gpio_output(ch_swap, SSW_SING_TALK);
  96. /*mt_set_gpio_out(ch_swap, SSW_SING_TALK); */
  97. }
  98. ext_ssw_mode_curr = mode;
  99. /*mt_set_gpio_out(en, GPIO_OUT_ONE); */
  100. pca9575_set_gpio_output(en, GPIO_OUT_ONE);
  101. }
  102. }
  103. return size;
  104. }
  105. #else
  106. ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer, size_t size)
  107. {
  108. unsigned int mode;
  109. int res = kstrtoint(buffer, 0, &mode);
  110. unsigned int type;
  111. if (res != 1) {
  112. SSW_DBG("%s: expect 1 numbers\n", __func__);
  113. } else {
  114. SSW_DBG("ssw_mode_store %x\n", mode);
  115. type = (mode & 0xFFFF0000) >> 16;
  116. mode = mode & 0x0000FFFF;
  117. if (type == 0) { /*Internal */
  118. SSW_DBG("Internal sim switch: %d-->%d\n", sim_mode_curr,
  119. mode);
  120. if ((sim_mode_curr != mode)
  121. && (SSW_SUCCESS == set_sim_gpio(mode))) {
  122. sim_mode_curr = mode;
  123. }
  124. } else {
  125. SSW_DBG("External sim switch: %d-->%d\n",
  126. ext_ssw_mode_curr, mode);
  127. if (mode == SSW_DUAL_TALK)
  128. mt_set_gpio_out(ch_swap, SSW_DUAL_TALK);
  129. else if (mode == SSW_SING_TALK)
  130. mt_set_gpio_out(ch_swap, SSW_SING_TALK);
  131. ext_ssw_mode_curr = mode;
  132. mt_set_gpio_out(en, GPIO_OUT_ONE);
  133. }
  134. }
  135. return size;
  136. }
  137. #endif
  138. const struct sysfs_ops ssw_sysfs_ops = {
  139. .show = ssw_attr_show,
  140. .store = ssw_attr_store,
  141. };
  142. struct ssw_sys_entry {
  143. struct attribute attr;
  144. ssize_t (*show)(struct kobject *kobj, char *page);
  145. ssize_t (*store)(struct kobject *kobj, const char *page, size_t size);
  146. };
  147. static struct ssw_sys_entry mode_entry = {
  148. {.name = "mode", .mode = S_IRUGO | S_IWUSR}, /*remove .owner = NULL, */
  149. ssw_mode_show,
  150. ssw_mode_store,
  151. };
  152. struct attribute *ssw_attributes[] = {
  153. &mode_entry.attr,
  154. NULL,
  155. };
  156. struct kobj_type ssw_ktype = {
  157. .sysfs_ops = &ssw_sysfs_ops,
  158. .default_attrs = ssw_attributes,
  159. };
  160. static struct ssw_sysobj_t {
  161. struct kobject kobj;
  162. } ssw_sysobj;
  163. int ssw_sysfs_init(void)
  164. {
  165. struct ssw_sysobj_t *obj = &ssw_sysobj;
  166. memset(&obj->kobj, 0x00, sizeof(obj->kobj));
  167. obj->kobj.parent = kernel_kobj;
  168. if (kobject_init_and_add(&obj->kobj, &ssw_ktype, NULL, "mtk_ssw")) {
  169. kobject_put(&obj->kobj);
  170. return -ENOMEM;
  171. }
  172. kobject_uevent(&obj->kobj, KOBJ_ADD);
  173. return 0;
  174. }
  175. /*---------------------------------------------------------------------------*/
  176. /*************************************************************************/
  177. /*external sim switch hardware operation */
  178. /**/
  179. /*************************************************************************/
  180. /*Exteranl sim switch hardware initial*/
  181. #ifdef MTK_PCA9575A_SUPPORT
  182. static int extern_ssw_init(void)
  183. {
  184. unsigned int mode = SSW_DUAL_TALK;
  185. unsigned int ch_mode, en_mode;
  186. SSW_DBG("extern_ssw_init: %d\n", mode);
  187. /*ch_swap = GPIO_SSW_CH_SWAP_PIN; */
  188. /*en = GPIO_SSW_EN_PIN; */
  189. en = GPIO_SSW_ENABLE; /*GPIO_P0_1; */
  190. ch_swap = GPIO_SSW_CH_SW; /*GPIO_P0_2; */
  191. ch_mode = GPIO_SSW_CH_SWAP_PIN_M_GPIO;
  192. en_mode = GPIO_SSW_EN_PIN_M_GPIO;
  193. /*initial Ch_Swap pin: 1, host1->sim slot1, host2->sim slot2; 0, host1->sim slot2, host2->sim slot1 */
  194. /*mt_set_gpio_mode(ch_swap, ch_mode); */
  195. /*mt_set_gpio_dir(ch_swap, GPIO_DIR_OUT); */
  196. pca9575_set_gpio_dir(ch_swap, 0); /*set as output */
  197. /*initial EN pin: 1, enable sim slot; 0, disable sim slot */
  198. /*mt_set_gpio_mode(en, en_mode); */
  199. /*mt_set_gpio_dir(en, GPIO_DIR_OUT); */
  200. pca9575_set_gpio_dir(en, 0); /*set as output */
  201. ext_ssw_mode_curr = mode;
  202. if (mode == SSW_DUAL_TALK) {
  203. /*mt_set_gpio_out(ch_swap, SSW_DUAL_TALK); */
  204. pca9575_set_gpio_output(ch_swap, SSW_DUAL_TALK);
  205. } else if (mode == SSW_SING_TALK) {
  206. /*mt_set_gpio_out(ch_swap, SSW_SING_TALK); */
  207. pca9575_set_gpio_output(ch_swap, SSW_SING_TALK);
  208. }
  209. mdelay(50); /*delay 50ms */
  210. /*mt_set_gpio_out(en, GPIO_OUT_ONE); */
  211. pca9575_set_gpio_output(en, GPIO_OUT_ONE);
  212. SSW_DBG("extern_ssw_init: ch_swap=(%x %d %d), en=(%x %d %d)\n",
  213. ch_swap, ch_mode, pca9575_get_gpio_output(ch_swap),
  214. en, en_mode, pca9575_get_gpio_output(en));
  215. return 0;
  216. }
  217. #else
  218. static int extern_ssw_init(void)
  219. {
  220. unsigned int mode = SSW_DUAL_TALK;
  221. unsigned int ch_mode, en_mode;
  222. SSW_DBG("extern_ssw_init: %d\n", mode);
  223. ch_swap = GPIO_SSW_CH_SWAP_PIN;
  224. en = GPIO_SSW_EN_PIN;
  225. ch_mode = GPIO_SSW_CH_SWAP_PIN_M_GPIO;
  226. en_mode = GPIO_SSW_EN_PIN_M_GPIO;
  227. mt_set_gpio_mode(ch_swap, ch_mode);
  228. mt_set_gpio_dir(ch_swap, GPIO_DIR_OUT);
  229. mt_set_gpio_mode(en, en_mode);
  230. mt_set_gpio_dir(en, GPIO_DIR_OUT);
  231. ext_ssw_mode_curr = mode;
  232. if (mode == SSW_DUAL_TALK)
  233. mt_set_gpio_out(ch_swap, SSW_DUAL_TALK);
  234. else if (mode == SSW_SING_TALK)
  235. mt_set_gpio_out(ch_swap, SSW_SING_TALK);
  236. mt_set_gpio_out(en, GPIO_OUT_ONE);
  237. SSW_DBG("extern_ssw_init: ch_swap=(%x %d %d), en=(%x %d %d)\n",
  238. ch_swap, ch_mode, mt_get_gpio_out(ch_swap),
  239. en, en_mode, mt_get_gpio_out(en));
  240. return 0;
  241. }
  242. #endif
  243. static int set_sim_gpio(unsigned int mode)
  244. {
  245. SSW_DBG("set_sim_gpio %d\n", mode);
  246. switch (mode) {
  247. case SINGLE_TALK_MDSYS:
  248. mt_set_gpio_mode(GPIO_SIM1_SCLK, 1); /*SIM1_SCLK */
  249. mt_set_gpio_mode(GPIO_SIM1_SIO, 1); /*SIM1_SIO */
  250. mt_set_gpio_mode(GPIO_SIM2_SCLK, 1); /*SIM2_SCLK */
  251. mt_set_gpio_mode(GPIO_SIM2_SIO, 1); /*SIM2_SIO */
  252. /*mt_set_gpio_mode(GPIO_SIM1_SRST, 4); SIM1_SRST, 6582 not use reset pin */
  253. /*mt_set_gpio_mode(GPIO_SIM2_SRST, 4); SIM2_SRST, 6582 not use reset pin */
  254. break;
  255. default:
  256. SSW_DBG("Mode(%d) not supported!!!", mode);
  257. return SSW_INVALID_PARA;
  258. }
  259. #if 0
  260. SSW_DBG
  261. ("Current sim mode(%d), GPIO0_MODE(%d, %d), GPIO1_MODE(%d, %d),
  262. GPIO2_MODE(%d, %d), GPIO3_MODE(%d, %d), GPIO89_MODE(%d, %d),
  263. GPIO90_MODE(%d, %d)\n",
  264. mode, mt_get_gpio_mode(GPIO0), mt_get_gpio_dir(GPIO0),
  265. mt_get_gpio_mode(GPIO1), mt_get_gpio_dir(GPIO1),
  266. mt_get_gpio_mode(GPIO2), mt_get_gpio_dir(GPIO2),
  267. mt_get_gpio_mode(GPIO3), mt_get_gpio_dir(GPIO3),
  268. mt_get_gpio_mode(GPIO89), mt_get_gpio_dir(GPIO89),
  269. mt_get_gpio_mode(GPIO90), mt_get_gpio_dir(GPIO90));
  270. #else
  271. SSW_DBG
  272. ("Current sim mode(%d), GPIO_SIM1_SCLK_MODE(%d, %d),
  273. GPIO_SIM1_SIO_MODE(%d, %d), GPIO_SIM2_SCLK_MODE(%d, %d),
  274. GPIO_SIM2_SIO_MODE(%d, %d)\n",
  275. mode, mt_get_gpio_mode(GPIO_SIM1_SCLK),
  276. mt_get_gpio_dir(GPIO_SIM1_SCLK), mt_get_gpio_mode(GPIO_SIM1_SIO),
  277. mt_get_gpio_dir(GPIO_SIM1_SIO), mt_get_gpio_mode(GPIO_SIM2_SCLK),
  278. mt_get_gpio_dir(GPIO_SIM2_SCLK), mt_get_gpio_mode(GPIO_SIM2_SIO),
  279. mt_get_gpio_dir(GPIO_SIM2_SIO));
  280. #endif
  281. return SSW_SUCCESS;
  282. }
  283. int get_ext_current_ssw_mode(void)
  284. {
  285. return ext_ssw_mode_curr;
  286. }
  287. int get_current_ssw_mode(void)
  288. {
  289. return sim_mode_curr;
  290. }
  291. #ifdef MTK_PCA9575A_SUPPORT
  292. int switch_sim_mode(int id, char *buf, unsigned int len)
  293. {
  294. unsigned int mode = *((unsigned int *)buf);
  295. unsigned int type = (mode & 0xFFFF0000) >> 16;
  296. int direction = 0;
  297. mode = mode & 0x0000FFFF;
  298. mutex_lock(&sim_switch_mutex);
  299. if (type == SSW_RESTORE) {
  300. /*This used for IPO-H to restore sim to default state */
  301. SSW_DBG("sim switch restore\n");
  302. sim_switch_init();
  303. } else if (type == 0) { /*Internal */
  304. SSW_DBG("Internal sim switch: %d --> %d\n", sim_mode_curr,
  305. mode);
  306. if ((sim_mode_curr != mode)
  307. && (SSW_SUCCESS == set_sim_gpio(mode))) {
  308. sim_mode_curr = mode;
  309. }
  310. } else if (type == SSW_EXT_SINGLE_COMMON) { /*External */
  311. if (((mode & 0x00FF) == 0) || ((mode & 0xFF00) == 0)) { /*CDMA */
  312. direction = SSW_DUAL_TALK;
  313. } else {
  314. direction = SSW_SING_TALK;
  315. }
  316. SSW_DBG("External sim switch: %d --> %d\n", ext_ssw_mode_curr,
  317. direction);
  318. if (ext_ssw_mode_curr != direction) {
  319. if (direction == SSW_DUAL_TALK)
  320. /*mt_set_gpio_out(ch_swap, SSW_DUAL_TALK); */
  321. pca9575_set_gpio_output(ch_swap, SSW_DUAL_TALK);
  322. else if (direction == SSW_SING_TALK)
  323. pca9575_set_gpio_output(ch_swap, SSW_SING_TALK);
  324. /*mt_set_gpio_out(ch_swap, SSW_SING_TALK); */
  325. /*SSW_DBG("ch_swap=%d, en=%d\n", mt_get_gpio_out(ch_swap), mt_get_gpio_out(en)); */
  326. SSW_DBG("ch_swap=%d, en=%d\n",
  327. pca9575_get_gpio_output(ch_swap),
  328. pca9575_get_gpio_output(en));
  329. ext_ssw_mode_curr = direction;
  330. }
  331. } else { /*External */
  332. SSW_DBG("External sim switch: %d --> %d\n", ext_ssw_mode_curr,
  333. mode);
  334. if (ext_ssw_mode_curr != mode) {
  335. if (mode == SSW_DUAL_TALK)
  336. /*mt_set_gpio_out(ch_swap, SSW_DUAL_TALK); */
  337. pca9575_set_gpio_output(ch_swap, SSW_DUAL_TALK);
  338. else if (mode == SSW_SING_TALK)
  339. pca9575_set_gpio_output(ch_swap, SSW_SING_TALK);
  340. /*mt_set_gpio_out(ch_swap, SSW_SING_TALK); */
  341. /*SSW_DBG("ch_swap=%d, en=%d\n", mt_get_gpio_out(ch_swap), mt_get_gpio_out(en)); */
  342. SSW_DBG("ch_swap=%d, en=%d\n",
  343. pca9575_get_gpio_output(ch_swap),
  344. pca9575_get_gpio_output(en));
  345. ext_ssw_mode_curr = mode;
  346. }
  347. }
  348. mutex_unlock(&sim_switch_mutex);
  349. SSW_DBG("sim switch(%d) OK\n", sim_mode_curr);
  350. return 0;
  351. }
  352. #else
  353. int switch_sim_mode(int id, char *buf, unsigned int len)
  354. {
  355. unsigned int mode = *((unsigned int *)buf);
  356. unsigned int type = (mode & 0xFFFF0000) >> 16;
  357. int direction = 0;
  358. mode = mode & 0x0000FFFF;
  359. mutex_lock(&sim_switch_mutex);
  360. if (type == 0) { /*Internal */
  361. SSW_DBG("Internal sim switch: %d --> %d\n", sim_mode_curr,
  362. mode);
  363. if ((sim_mode_curr != mode)
  364. && (SSW_SUCCESS == set_sim_gpio(mode))) {
  365. sim_mode_curr = mode;
  366. }
  367. } else if (type == SSW_EXT_SINGLE_COMMON) { /*External */
  368. if (((mode & 0x00FF) == 0) || ((mode & 0xFF00) == 0)) { /*CDMA */
  369. direction = SSW_DUAL_TALK;
  370. } else {
  371. direction = SSW_SING_TALK;
  372. }
  373. SSW_DBG("External sim switch: %d --> %d\n", ext_ssw_mode_curr,
  374. direction);
  375. if (ext_ssw_mode_curr != direction) {
  376. if (direction == SSW_DUAL_TALK)
  377. mt_set_gpio_out(ch_swap, SSW_DUAL_TALK);
  378. else if (direction == SSW_SING_TALK)
  379. mt_set_gpio_out(ch_swap, SSW_SING_TALK);
  380. SSW_DBG("ch_swap=%d, en=%d\n", mt_get_gpio_out(ch_swap),
  381. mt_get_gpio_out(en));
  382. ext_ssw_mode_curr = direction;
  383. }
  384. } else { /*External */
  385. SSW_DBG("External sim switch: %d --> %d\n", ext_ssw_mode_curr,
  386. mode);
  387. if (ext_ssw_mode_curr != mode) {
  388. if (mode == SSW_DUAL_TALK)
  389. mt_set_gpio_out(ch_swap, SSW_DUAL_TALK);
  390. else if (mode == SSW_SING_TALK)
  391. mt_set_gpio_out(ch_swap, SSW_SING_TALK);
  392. SSW_DBG("ch_swap=%d, en=%d\n", mt_get_gpio_out(ch_swap),
  393. mt_get_gpio_out(en));
  394. ext_ssw_mode_curr = mode;
  395. }
  396. }
  397. mutex_unlock(&sim_switch_mutex);
  398. SSW_DBG("sim switch(%d) OK\n", sim_mode_curr);
  399. return 0;
  400. }
  401. #endif
  402. /*To decide sim mode according to compile option*/
  403. static int get_sim_mode_init(void)
  404. {
  405. unsigned int sim_mode = 0;
  406. unsigned int md1_enable, md2_enable = 0;
  407. md1_enable = get_modem_is_enabled(MD_SYS1);
  408. md2_enable = get_modem_is_enabled(MD_SYS2);
  409. if (md1_enable) {
  410. sim_mode = SINGLE_TALK_MDSYS;
  411. if (md2_enable)
  412. sim_mode = DUAL_TALK;
  413. } else if (md2_enable)
  414. sim_mode = SINGLE_TALK_MDSYS_LITE;
  415. return sim_mode;
  416. }
  417. /*sim switch hardware initial*/
  418. int sim_switch_init(void)
  419. {
  420. SSW_DBG("sim_switch_init\n");
  421. /*better to set pull_en and pull_sel first, then mode */
  422. /*if GPIO in sim mode, no need to set direction, because hw has done this when setting mode */
  423. /*
  424. mt_set_gpio_dir(GPIO_SIM1_SCLK, GPIO_DIR_OUT); /*GPIO0->SIM2_CLK, out */
  425. mt_set_gpio_dir(GPIO_SIM1_SIO, GPIO_DIR_IN); /*GPIO1->SIM2_SIO, in */
  426. mt_set_gpio_dir(GPIO_SIM2_SCLK, GPIO_DIR_OUT); /*GPIO2->SIM1_CLK, out */
  427. mt_set_gpio_dir(GPIO_SIM2_SIO, GPIO_DIR_IN); /*GPIO3->SIM1_SIO, in */
  428. */
  429. /*mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); GPIO89->SIM1_SRST, out, 6572 not use reset pin */
  430. /*mt_set_gpio_dir(GPIO90, GPIO_DIR_OUT); GPIO90->SIM2_SRST, out, 6572 not use reset pin */
  431. sim_mode_curr = get_sim_mode_init();
  432. if (SSW_SUCCESS != set_sim_gpio(sim_mode_curr)) {
  433. SSW_DBG("sim_switch_init fail\n");
  434. return SSW_INVALID_PARA;
  435. }
  436. extern_ssw_init();
  437. return 0;
  438. }
  439. static int sim_switch_probe(struct platform_device *dev)
  440. {
  441. SSW_DBG("Enter sim_switch_probe\n");
  442. /*sim_switch_init(); */
  443. /*mutex_init(&sim_switch_mutex); */
  444. register_ccci_kern_func(ID_SSW_SWITCH_MODE, switch_sim_mode);
  445. return 0;
  446. }
  447. static int sim_switch_remove(struct platform_device *dev)
  448. {
  449. /*SSW_DBG("sim_switch_remove\n"); */
  450. return 0;
  451. }
  452. static void sim_switch_shutdown(struct platform_device *dev)
  453. {
  454. /*SSW_DBG("sim_switch_shutdown\n"); */
  455. }
  456. static int sim_switch_suspend(struct platform_device *dev, pm_message_t state)
  457. {
  458. /*SSW_DBG("sim_switch_suspend\n"); */
  459. return 0;
  460. }
  461. static int sim_switch_resume(struct platform_device *dev)
  462. {
  463. /*SSW_DBG("sim_switch_resume\n"); */
  464. return 0;
  465. }
  466. static struct platform_driver sim_switch_driver = {
  467. .driver = {
  468. .name = "sim-switch",
  469. },
  470. .probe = sim_switch_probe,
  471. .remove = sim_switch_remove,
  472. .shutdown = sim_switch_shutdown,
  473. .suspend = sim_switch_suspend,
  474. .resume = sim_switch_resume,
  475. };
  476. static int __init sim_switch_driver_init(void)
  477. {
  478. int ret = 0;
  479. SSW_DBG("sim_switch_driver_init\n");
  480. ret = platform_driver_register(&sim_switch_driver);
  481. if (ret) {
  482. SSW_DBG("ssw_driver register fail(%d)\n", ret);
  483. return ret;
  484. }
  485. mutex_init(&sim_switch_mutex);
  486. #if __ENABLE_SSW_SYSFS
  487. ssw_sysfs_init();
  488. #endif
  489. sim_switch_init();
  490. return ret;
  491. }
  492. static void __exit sim_switch_driver_exit(void)
  493. {
  494. }
  495. /*module_init(sim_switch_driver_init);*/
  496. late_initcall(sim_switch_driver_init);
  497. module_exit(sim_switch_driver_exit);
  498. MODULE_DESCRIPTION("MTK SIM Switch Driver");
  499. MODULE_AUTHOR("Anny <Anny.Hu@mediatek.com>");
  500. MODULE_LICENSE("GPL");