mt_usb.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /*
  2. * MUSB OTG controller driver for Blackfin Processors
  3. *
  4. * Copyright 2006-2008 Analog Devices Inc.
  5. *
  6. * Enter bugs at http://blackfin.uclinux.org/
  7. *
  8. * Licensed under the GPL-2 or later.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/workqueue.h>
  13. #include <linux/usb/gadget.h>
  14. /*#include "mach/emi_mpu.h"*/
  15. #include "mu3d_hal_osal.h"
  16. #include "musb_core.h"
  17. #ifdef CONFIG_MTK_UART_USB_SWITCH
  18. #include "mtk-phy-asic.h"
  19. /*#include <mach/mt_typedefs.h>*/
  20. #endif
  21. #if defined(FOR_BRING_UP) || !defined(CONFIG_MTK_SMART_BATTERY)
  22. static inline void BATTERY_SetUSBState(int usb_state)
  23. {
  24. };
  25. #ifndef CONFIG_MTK_FPGA
  26. static inline CHARGER_TYPE mt_get_charger_type(void)
  27. {
  28. return STANDARD_HOST;
  29. };
  30. #endif
  31. static inline bool upmu_is_chr_det(void)
  32. {
  33. return true;
  34. };
  35. static inline u32 upmu_get_rgs_chrdet(void)
  36. {
  37. return 1;
  38. };
  39. #endif
  40. unsigned int cable_mode = CABLE_MODE_NORMAL;
  41. #ifdef CONFIG_MTK_UART_USB_SWITCH
  42. u32 port_mode = PORT_MODE_USB;
  43. u32 sw_tx = 0;
  44. u32 sw_rx = 0;
  45. u32 sw_uart_path = 0;
  46. #endif
  47. /* ================================ */
  48. /* connect and disconnect functions */
  49. /* ================================ */
  50. bool mt_usb_is_device(void)
  51. {
  52. #if !defined(CONFIG_MTK_FPGA) && defined(CONFIG_USB_XHCI_MTK)
  53. bool tmp = mtk_is_host_mode();
  54. os_printk(K_INFO, "%s mode\n", tmp ? "HOST" : "DEV");
  55. return !tmp;
  56. #else
  57. return true;
  58. #endif
  59. }
  60. enum status { INIT, ON, OFF };
  61. #ifdef CONFIG_USBIF_COMPLIANCE
  62. static enum status connection_work_dev_status = INIT;
  63. void init_connection_work(void)
  64. {
  65. connection_work_dev_status = INIT;
  66. }
  67. #endif
  68. #ifndef CONFIG_USBIF_COMPLIANCE
  69. struct timespec connect_timestamp = { 0, 0 };
  70. void set_connect_timestamp(void)
  71. {
  72. connect_timestamp = CURRENT_TIME;
  73. pr_debug("set timestamp = %llu\n", timespec_to_ns(&connect_timestamp));
  74. }
  75. void clr_connect_timestamp(void)
  76. {
  77. connect_timestamp.tv_sec = 0;
  78. connect_timestamp.tv_nsec = 0;
  79. pr_debug("clr timestamp = %llu\n", timespec_to_ns(&connect_timestamp));
  80. }
  81. struct timespec get_connect_timestamp(void)
  82. {
  83. pr_debug("get timestamp = %llu\n", timespec_to_ns(&connect_timestamp));
  84. return connect_timestamp;
  85. }
  86. #endif
  87. void connection_work(struct work_struct *data)
  88. {
  89. struct musb *musb = container_of(to_delayed_work(data), struct musb, connection_work);
  90. #ifndef CONFIG_USBIF_COMPLIANCE
  91. static enum status connection_work_dev_status = INIT;
  92. #endif
  93. #ifdef CONFIG_MTK_UART_USB_SWITCH
  94. if (!usb_phy_check_in_uart_mode()) {
  95. #endif
  96. bool is_usb_cable = usb_cable_connected();
  97. bool cmode_effect_on = false;
  98. #ifndef CONFIG_MTK_FPGA
  99. CHARGER_TYPE chg_type = mt_get_charger_type();
  100. if (fake_CDP && chg_type == STANDARD_HOST) {
  101. os_printk(K_INFO, "%s, fake to type 2\n", __func__);
  102. chg_type = CHARGING_HOST;
  103. }
  104. os_printk(K_NOTICE, "%s type=%d\n", __func__, chg_type);
  105. if ((musb->usb_mode == CABLE_MODE_HOST_ONLY && chg_type == STANDARD_HOST)
  106. || musb->usb_mode == CABLE_MODE_CHRG_ONLY)
  107. cmode_effect_on = true;
  108. #ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING
  109. if (get_boot_mode() == KERNEL_POWER_OFF_CHARGING_BOOT
  110. || get_boot_mode() == LOW_POWER_OFF_CHARGING_BOOT) {
  111. if (chg_type == STANDARD_HOST)
  112. cmode_effect_on = true;
  113. }
  114. #endif
  115. os_printk(K_INFO, "%s type=%d, cmode_effect_on=%d, usb_mode:%d\n",
  116. __func__, chg_type, cmode_effect_on, musb->usb_mode);
  117. if (!mt_usb_is_device()) {
  118. connection_work_dev_status = OFF;
  119. usb_fake_powerdown(musb->is_clk_on);
  120. musb->is_clk_on = 0;
  121. os_printk(K_INFO, "%s, Host mode. directly return\n", __func__);
  122. return;
  123. }
  124. #endif
  125. os_printk(K_INFO, "%s musb %s, cable %s\n", __func__,
  126. ((connection_work_dev_status ==
  127. 0) ? "INIT" : ((connection_work_dev_status == 1) ? "ON" : "OFF")),
  128. (is_usb_cable ? "IN" : "OUT"));
  129. if ((is_usb_cable == true) && (connection_work_dev_status != ON)
  130. && (!cmode_effect_on)) {
  131. connection_work_dev_status = ON;
  132. #ifndef CONFIG_USBIF_COMPLIANCE
  133. set_connect_timestamp();
  134. #endif
  135. if (!wake_lock_active(&musb->usb_wakelock))
  136. wake_lock(&musb->usb_wakelock);
  137. /* FIXME: Should use usb_udc_start() & usb_gadget_connect(), like usb_udc_softconn_store().
  138. * But have no time to think how to handle. However i think it is the correct way.*/
  139. musb_start(musb);
  140. os_printk(K_INFO, "%s ----Connect----\n", __func__);
  141. } else if (((is_usb_cable == false) && (connection_work_dev_status != OFF))
  142. || (cmode_effect_on)) {
  143. connection_work_dev_status = OFF;
  144. #ifndef CONFIG_USBIF_COMPLIANCE
  145. clr_connect_timestamp();
  146. #endif
  147. /*FIXME: we should use usb_gadget_disconnect() & usb_udc_stop(). like usb_udc_softconn_store().
  148. * But have no time to think how to handle. However i think it is the correct way.*/
  149. musb_stop(musb);
  150. if (wake_lock_active(&musb->usb_wakelock))
  151. wake_unlock(&musb->usb_wakelock);
  152. os_printk(K_INFO, "%s ----Disconnect----\n", __func__);
  153. } else {
  154. /* This if-elseif is to set wakelock when booting with USB cable.
  155. * Because battery driver does _NOT_ notify at this codition.*/
  156. /* if( (is_usb_cable == true) && !wake_lock_active(&musb->usb_wakelock)) { */
  157. /* os_printk(K_INFO, "%s Boot wakelock\n", __func__); */
  158. /* wake_lock(&musb->usb_wakelock); */
  159. /* } else if( (is_usb_cable == false) && wake_lock_active(&musb->usb_wakelock)) { */
  160. /* os_printk(K_INFO, "%s Boot unwakelock\n", __func__); */
  161. /* wake_unlock(&musb->usb_wakelock); */
  162. /* } */
  163. os_printk(K_INFO, "%s directly return\n", __func__);
  164. }
  165. #ifdef CONFIG_MTK_UART_USB_SWITCH
  166. } else {
  167. #if 0
  168. usb_fake_powerdown(musb->is_clk_on);
  169. musb->is_clk_on = 0;
  170. #else
  171. os_printk(K_INFO, "%s, in UART MODE!!!\n", __func__);
  172. #endif
  173. }
  174. #endif
  175. }
  176. bool mt_usb_is_ready(void)
  177. {
  178. os_printk(K_INFO, "USB is ready or not\n");
  179. #ifdef NEVER
  180. if (!mtk_musb || !mtk_musb->is_ready)
  181. return false;
  182. else
  183. return true;
  184. #endif /* NEVER */
  185. return true;
  186. }
  187. void mt_usb_connect(void)
  188. {
  189. os_printk(K_INFO, "%s+\n", __func__);
  190. if (_mu3d_musb) {
  191. struct delayed_work *work;
  192. work = &_mu3d_musb->connection_work;
  193. schedule_delayed_work_on(0, work, 0);
  194. } else {
  195. os_printk(K_INFO, "%s musb_musb not ready\n", __func__);
  196. }
  197. os_printk(K_INFO, "%s-\n", __func__);
  198. }
  199. EXPORT_SYMBOL_GPL(mt_usb_connect);
  200. void mt_usb_disconnect(void)
  201. {
  202. os_printk(K_INFO, "%s+\n", __func__);
  203. if (_mu3d_musb) {
  204. struct delayed_work *work;
  205. work = &_mu3d_musb->connection_work;
  206. schedule_delayed_work_on(0, work, 0);
  207. } else {
  208. os_printk(K_INFO, "%s musb_musb not ready\n", __func__);
  209. }
  210. os_printk(K_INFO, "%s-\n", __func__);
  211. }
  212. EXPORT_SYMBOL_GPL(mt_usb_disconnect);
  213. bool usb_cable_connected(void)
  214. {
  215. #ifndef CONFIG_MTK_FPGA
  216. CHARGER_TYPE chg_type = CHARGER_UNKNOWN;
  217. #ifdef CONFIG_POWER_EXT
  218. chg_type = mt_get_charger_type();
  219. os_printk(K_INFO, "%s ext-chrdet=%d type=%d\n", __func__, upmu_get_rgs_chrdet(), chg_type);
  220. if (upmu_get_rgs_chrdet() && (chg_type == STANDARD_HOST))
  221. return true;
  222. #else
  223. if (upmu_is_chr_det()) {
  224. chg_type = mt_get_charger_type();
  225. os_printk(K_INFO, "%s type=%d\n", __func__, chg_type);
  226. if (chg_type == STANDARD_HOST || chg_type == CHARGING_HOST)
  227. return true;
  228. }
  229. #endif
  230. os_printk(K_INFO, "%s no USB Host detect!\n", __func__);
  231. return false;
  232. #else
  233. os_printk(K_INFO, "%s [FPGA] always true\n", __func__);
  234. return true;
  235. #endif
  236. }
  237. EXPORT_SYMBOL_GPL(usb_cable_connected);
  238. #ifdef CONFIG_USB_C_SWITCH
  239. int typec_switch_usb_connect(void *data)
  240. {
  241. struct musb *musb = data;
  242. os_printk(K_INFO, "%s+\n", __func__);
  243. if (musb && musb->gadget_driver) {
  244. struct delayed_work *work;
  245. work = &musb->connection_work;
  246. schedule_delayed_work_on(0, work, 0);
  247. } else {
  248. os_printk(K_INFO, "%s musb_musb not ready\n", __func__);
  249. }
  250. os_printk(K_INFO, "%s-\n", __func__);
  251. return 0;
  252. }
  253. int typec_switch_usb_disconnect(void *data)
  254. {
  255. struct musb *musb = data;
  256. os_printk(K_INFO, "%s+\n", __func__);
  257. if (musb && musb->gadget_driver) {
  258. struct delayed_work *work;
  259. work = &musb->connection_work;
  260. schedule_delayed_work_on(0, work, 0);
  261. } else {
  262. os_printk(K_INFO, "%s musb_musb not ready\n", __func__);
  263. }
  264. os_printk(K_INFO, "%s-\n", __func__);
  265. return 0;
  266. }
  267. #endif
  268. #ifdef NEVER
  269. void musb_platform_reset(struct musb *musb)
  270. {
  271. u16 swrst = 0;
  272. void __iomem *mbase = musb->mregs;
  273. swrst = musb_readw(mbase, MUSB_SWRST);
  274. swrst |= (MUSB_SWRST_DISUSBRESET | MUSB_SWRST_SWRST);
  275. musb_writew(mbase, MUSB_SWRST, swrst);
  276. }
  277. #endif /* NEVER */
  278. void usb_check_connect(void)
  279. {
  280. os_printk(K_INFO, "usb_check_connect\n");
  281. #ifndef CONFIG_MTK_FPGA
  282. if (usb_cable_connected())
  283. mt_usb_connect();
  284. #endif
  285. }
  286. void musb_sync_with_bat(struct musb *musb, int usb_state)
  287. {
  288. os_printk(K_DEBUG, "musb_sync_with_bat\n");
  289. #ifndef CONFIG_MTK_FPGA
  290. #if defined(CONFIG_MTK_SMART_BATTERY)
  291. BATTERY_SetUSBState(usb_state);
  292. #ifndef FOR_BRING_UP
  293. wake_up_bat();
  294. #endif
  295. #endif
  296. #endif
  297. }
  298. EXPORT_SYMBOL_GPL(musb_sync_with_bat);
  299. #ifdef CONFIG_USB_MTK_DUALMODE
  300. bool musb_check_ipo_state(void)
  301. {
  302. bool ipo_off;
  303. down(&_mu3d_musb->musb_lock);
  304. ipo_off = _mu3d_musb->in_ipo_off;
  305. os_printk(K_INFO, "IPO State is %s\n", (ipo_off ? "true" : "false"));
  306. up(&_mu3d_musb->musb_lock);
  307. return ipo_off;
  308. }
  309. #endif
  310. /*--FOR INSTANT POWER ON USAGE--------------------------------------------------*/
  311. static inline struct musb *dev_to_musb(struct device *dev)
  312. {
  313. return dev_get_drvdata(dev);
  314. }
  315. const char *const usb_mode_str[CABLE_MODE_MAX] = { "CHRG_ONLY", "NORMAL", "HOST_ONLY" };
  316. ssize_t musb_cmode_show(struct device *dev, struct device_attribute *attr, char *buf)
  317. {
  318. if (!dev) {
  319. os_printk(K_ERR, "dev is null!!\n");
  320. return 0;
  321. }
  322. return sprintf(buf, "%d\n", cable_mode);
  323. }
  324. ssize_t musb_cmode_store(struct device *dev, struct device_attribute *attr,
  325. const char *buf, size_t count)
  326. {
  327. unsigned int cmode;
  328. struct musb *musb = dev_to_musb(dev);
  329. if (!dev) {
  330. os_printk(K_ERR, "dev is null!!\n");
  331. return count;
  332. } else if (1 == sscanf(buf, "%ud", &cmode)) {
  333. os_printk(K_INFO, "%s %s --> %s\n", __func__, usb_mode_str[cable_mode],
  334. usb_mode_str[cmode]);
  335. if (cmode >= CABLE_MODE_MAX)
  336. cmode = CABLE_MODE_NORMAL;
  337. if (cable_mode != cmode) {
  338. if (_mu3d_musb) {
  339. if (down_interruptible(&_mu3d_musb->musb_lock))
  340. os_printk(K_INFO, "%s: busy, Couldn't get musb_lock\n", __func__);
  341. }
  342. if (cmode == CABLE_MODE_CHRG_ONLY) { /* IPO shutdown, disable USB */
  343. if (_mu3d_musb)
  344. _mu3d_musb->in_ipo_off = true;
  345. } else { /* IPO bootup, enable USB */
  346. if (_mu3d_musb)
  347. _mu3d_musb->in_ipo_off = false;
  348. }
  349. if (cmode == CABLE_MODE_CHRG_ONLY) { /* IPO shutdown, disable USB */
  350. if (musb) {
  351. musb->usb_mode = CABLE_MODE_CHRG_ONLY;
  352. mt_usb_disconnect();
  353. }
  354. } else if (cmode == CABLE_MODE_HOST_ONLY) {
  355. if (musb) {
  356. musb->usb_mode = CABLE_MODE_HOST_ONLY;
  357. mt_usb_disconnect();
  358. }
  359. } else { /* IPO bootup, enable USB */
  360. if (musb) {
  361. musb->usb_mode = CABLE_MODE_NORMAL;
  362. #ifndef CONFIG_USB_C_SWITCH
  363. mt_usb_connect();
  364. #else
  365. typec_switch_usb_connect(musb);
  366. #endif
  367. }
  368. }
  369. cable_mode = cmode;
  370. #ifdef CONFIG_USB_MTK_DUALMODE
  371. if (cmode == CABLE_MODE_CHRG_ONLY) {
  372. #ifdef CONFIG_USB_C_SWITCH
  373. ;
  374. #else
  375. /* mask ID pin interrupt even if A-cable is not plugged in */
  376. switch_int_to_host_and_mask();
  377. if (mtk_is_host_mode() == true)
  378. mtk_unload_xhci_on_ipo();
  379. #endif
  380. } else {
  381. #ifdef CONFIG_USB_C_SWITCH
  382. ;
  383. #else
  384. switch_int_to_host(); /* resotre ID pin interrupt */
  385. #endif
  386. }
  387. #endif
  388. if (_mu3d_musb)
  389. up(&_mu3d_musb->musb_lock);
  390. }
  391. }
  392. return count;
  393. }
  394. #ifdef CONFIG_MTK_UART_USB_SWITCH
  395. ssize_t musb_portmode_show(struct device *dev, struct device_attribute *attr, char *buf)
  396. {
  397. if (!dev) {
  398. pr_debug("dev is null!!\n");
  399. return 0;
  400. }
  401. if (usb_phy_check_in_uart_mode())
  402. port_mode = PORT_MODE_UART;
  403. else
  404. port_mode = PORT_MODE_USB;
  405. if (port_mode == PORT_MODE_USB)
  406. pr_debug("\nUSB Port mode -> USB\n");
  407. else if (port_mode == PORT_MODE_UART)
  408. pr_debug("\nUSB Port mode -> UART\n");
  409. uart_usb_switch_dump_register();
  410. return scnprintf(buf, PAGE_SIZE, "%d\n", port_mode);
  411. }
  412. ssize_t musb_portmode_store(struct device *dev, struct device_attribute *attr,
  413. const char *buf, size_t count)
  414. {
  415. unsigned int portmode;
  416. if (!dev) {
  417. pr_debug("dev is null!!\n");
  418. return count;
  419. } else if (1 == sscanf(buf, "%ud", &portmode)) {
  420. pr_debug("\nUSB Port mode: current => %d (port_mode), change to => %d (portmode)\n",
  421. port_mode, portmode);
  422. if (portmode >= PORT_MODE_MAX)
  423. portmode = PORT_MODE_USB;
  424. if (port_mode != portmode) {
  425. if (portmode == PORT_MODE_USB) { /* Changing to USB Mode */
  426. pr_debug("USB Port mode -> USB\n");
  427. usb_phy_switch_to_usb();
  428. } else if (portmode == PORT_MODE_UART) { /* Changing to UART Mode */
  429. pr_debug("USB Port mode -> UART\n");
  430. usb_phy_switch_to_uart();
  431. }
  432. uart_usb_switch_dump_register();
  433. port_mode = portmode;
  434. }
  435. }
  436. return count;
  437. }
  438. ssize_t musb_tx_show(struct device *dev, struct device_attribute *attr, char *buf)
  439. {
  440. u8 var;
  441. u8 var2;
  442. if (!dev) {
  443. pr_debug("dev is null!!\n");
  444. return 0;
  445. }
  446. var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2));
  447. var2 = (var >> 3) & ~0xFE;
  448. pr_debug("[MUSB]addr: 0x6E (TX), value: %x - %x\n", var, var2);
  449. sw_tx = var;
  450. return scnprintf(buf, PAGE_SIZE, "%x\n", var2);
  451. }
  452. ssize_t musb_tx_store(struct device *dev, struct device_attribute *attr,
  453. const char *buf, size_t count)
  454. {
  455. unsigned int val;
  456. u8 var;
  457. u8 var2;
  458. if (!dev) {
  459. pr_debug("dev is null!!\n");
  460. return count;
  461. } else if (1 == sscanf(buf, "%ud", &val)) {
  462. pr_debug("\n Write TX : %d\n", val);
  463. #ifdef CONFIG_MTK_FPGA
  464. var = USB_PHY_Read_Register8(U3D_U2PHYDTM1 + 0x2);
  465. #else
  466. var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2));
  467. #endif
  468. if (val == 0)
  469. var2 = var & ~(1 << 3);
  470. else
  471. var2 = var | (1 << 3);
  472. #ifdef CONFIG_MTK_FPGA
  473. USB_PHY_Write_Register8(var2, U3D_U2PHYDTM1 + 0x2);
  474. var = USB_PHY_Read_Register8(U3D_U2PHYDTM1 + 0x2);
  475. #else
  476. /* U3PhyWriteField32(U3D_USBPHYDTM1+0x2,
  477. E60802_RG_USB20_BC11_SW_EN_OFST, E60802_RG_USB20_BC11_SW_EN, 0); */
  478. /* Jeremy TODO 0320 */
  479. var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2));
  480. #endif
  481. var2 = (var >> 3) & ~0xFE;
  482. pr_debug
  483. ("[MUSB]addr: U3D_U2PHYDTM1 (0x6E) TX [AFTER WRITE], value after: %x - %x\n",
  484. var, var2);
  485. sw_tx = var;
  486. }
  487. return count;
  488. }
  489. ssize_t musb_rx_show(struct device *dev, struct device_attribute *attr, char *buf)
  490. {
  491. u8 var;
  492. u8 var2;
  493. if (!dev) {
  494. pr_debug("dev is null!!\n");
  495. return 0;
  496. }
  497. #ifdef CONFIG_MTK_FPGA
  498. var = USB_PHY_Read_Register8(U3D_U2PHYDMON1 + 0x3);
  499. #else
  500. var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDMON1 + 0x3));
  501. #endif
  502. var2 = (var >> 7) & ~0xFE;
  503. pr_debug("[MUSB]addr: U3D_U2PHYDMON1 (0x77) (RX), value: %x - %x\n", var, var2);
  504. sw_rx = var;
  505. return scnprintf(buf, PAGE_SIZE, "%x\n", var2);
  506. }
  507. ssize_t musb_uart_path_show(struct device *dev, struct device_attribute *attr, char *buf)
  508. {
  509. u8 var = 0;
  510. if (!dev) {
  511. pr_debug("dev is null!!\n");
  512. return 0;
  513. }
  514. var = DRV_Reg8(ap_uart0_base + 0xB0);
  515. pr_debug("[MUSB]addr: (UART0) 0xB0, value: %x\n\n", DRV_Reg8(ap_uart0_base + 0xB0));
  516. sw_uart_path = var;
  517. return scnprintf(buf, PAGE_SIZE, "%x\n", var);
  518. }
  519. #endif
  520. #ifdef NEVER
  521. #ifdef CONFIG_MTK_FPGA
  522. static struct i2c_client *usb_i2c_client;
  523. static const struct i2c_device_id usb_i2c_id[] = { {"mtk-usb", 0}, {} };
  524. static struct i2c_board_info usb_i2c_dev __initdata = { I2C_BOARD_INFO("mtk-usb", 0x60) };
  525. void USB_PHY_Write_Register8(UINT8 var, UINT8 addr)
  526. {
  527. char buffer[2];
  528. buffer[0] = addr;
  529. buffer[1] = var;
  530. i2c_master_send(usb_i2c_client, &buffer, 2);
  531. }
  532. UINT8 USB_PHY_Read_Register8(UINT8 addr)
  533. {
  534. UINT8 var;
  535. i2c_master_send(usb_i2c_client, &addr, 1);
  536. i2c_master_recv(usb_i2c_client, &var, 1);
  537. return var;
  538. }
  539. static int usb_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  540. {
  541. pr_debug("[MUSB]usb_i2c_probe, start\n");
  542. usb_i2c_client = client;
  543. /* disable usb mac suspend */
  544. DRV_WriteReg8(USB_SIF_BASE + 0x86a, 0x00);
  545. /* usb phy initial sequence */
  546. USB_PHY_Write_Register8(0x00, 0xFF);
  547. USB_PHY_Write_Register8(0x04, 0x61);
  548. USB_PHY_Write_Register8(0x00, 0x68);
  549. USB_PHY_Write_Register8(0x00, 0x6a);
  550. USB_PHY_Write_Register8(0x6e, 0x00);
  551. USB_PHY_Write_Register8(0x0c, 0x1b);
  552. USB_PHY_Write_Register8(0x44, 0x08);
  553. USB_PHY_Write_Register8(0x55, 0x11);
  554. USB_PHY_Write_Register8(0x68, 0x1a);
  555. pr_debug("[MUSB]addr: 0xFF, value: %x\n", USB_PHY_Read_Register8(0xFF));
  556. pr_debug("[MUSB]addr: 0x61, value: %x\n", USB_PHY_Read_Register8(0x61));
  557. pr_debug("[MUSB]addr: 0x68, value: %x\n", USB_PHY_Read_Register8(0x68));
  558. pr_debug("[MUSB]addr: 0x6a, value: %x\n", USB_PHY_Read_Register8(0x6a));
  559. pr_debug("[MUSB]addr: 0x00, value: %x\n", USB_PHY_Read_Register8(0x00));
  560. pr_debug("[MUSB]addr: 0x1b, value: %x\n", USB_PHY_Read_Register8(0x1b));
  561. pr_debug("[MUSB]addr: 0x08, value: %x\n", USB_PHY_Read_Register8(0x08));
  562. pr_debug("[MUSB]addr: 0x11, value: %x\n", USB_PHY_Read_Register8(0x11));
  563. pr_debug("[MUSB]addr: 0x1a, value: %x\n", USB_PHY_Read_Register8(0x1a));
  564. pr_debug("[MUSB]usb_i2c_probe, end\n");
  565. return 0;
  566. }
  567. static int usb_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
  568. {
  569. strcpy(info->type, "mtk-usb");
  570. return 0;
  571. }
  572. static int usb_i2c_remove(struct i2c_client *client)
  573. {
  574. return 0;
  575. }
  576. struct i2c_driver usb_i2c_driver = {
  577. .probe = usb_i2c_probe,
  578. .remove = usb_i2c_remove,
  579. .detect = usb_i2c_detect,
  580. .driver = {
  581. .name = "mtk-usb",
  582. },
  583. .id_table = usb_i2c_id,
  584. };
  585. int add_usb_i2c_driver(void)
  586. {
  587. int ret = 0;
  588. i2c_register_board_info(0, &usb_i2c_dev, 1);
  589. if (i2c_add_driver(&usb_i2c_driver) != 0) {
  590. pr_debug("[MUSB]usb_i2c_driver initialization failed!!\n");
  591. ret = -1;
  592. } else
  593. pr_debug("[MUSB]usb_i2c_driver initialization succeed!!\n");
  594. return ret;
  595. }
  596. #endif /* End of CONFIG_MTK_FPGA */
  597. #endif /* NEVER */