mt_gpio_init.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <platform/mt_gpio.h>
  32. #ifndef USE_DTB_NO_DWS
  33. #if (!defined(MACH_FPGA) || defined (FPGA_SIMULATION))
  34. #include <cust_power.h>
  35. #include <cust_gpio_boot.h>
  36. #endif
  37. #endif/* end of USE_DTB_NO_DWS */
  38. #include <platform/mt_reg_base.h>
  39. #include <platform/gpio_init.h>
  40. #include <debug.h>
  41. #define GPIO_INIT_DEBUG 1
  42. /*----------------------------------------------------------------------------*/
  43. #define GPIOTAG "[GPIO] "
  44. #define GPIODBG(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  45. #define GPIOERR(fmt, arg...) dprintf(CRITICAL, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  46. #define GPIOVER(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  47. #define GPIO_WR32(addr, data) DRV_WriteReg32(addr,data)
  48. #define GPIO_RD32(addr) DRV_Reg32(addr)
  49. #define ADDR_BIT 0
  50. #define VAL_BIT 1
  51. #define MASK_BIT 2
  52. /*----------------------------------------------------------------------------*/
  53. #if (defined(MACH_FPGA) && !defined (FPGA_SIMULATION))
  54. void mt_gpio_set_default(void)
  55. {
  56. return;
  57. }
  58. void mt_gpio_set_default_dump(void)
  59. {
  60. return;
  61. }
  62. #else
  63. void gpio_dump(void)
  64. {
  65. int i = 0;
  66. GPIOVER("[gpio dct config] ++++++++++++++++++++++++++++\n");
  67. for (i = 0; i < MAX_GPIO_PIN; i++) {
  68. GPIOVER("gpio[%d]\n", i);
  69. GPIOVER("gpio[%d], mode(%x)\n", i, mt_get_gpio_mode(0x80000000 + i));
  70. GPIOVER("gpio[%d], dir(%x)\n", i, mt_get_gpio_dir(0x80000000 + i));
  71. GPIOVER("gpio[%d], pull_en(%x)\n", i, mt_get_gpio_pull_enable(0x80000000 + i));
  72. GPIOVER("gpio[%d], pull_sel(%x)\n", i, mt_get_gpio_pull_select(0x80000000 + i));
  73. GPIOVER("gpio[%d], out(%x)\n", i, mt_get_gpio_out(0x80000000 + i));
  74. GPIOVER("gpio[%d], smt(%x)\n", i, mt_get_gpio_smt(0x80000000 + i));
  75. GPIOVER("gpio[%d], ies(%x)\n", i, mt_get_gpio_ies(0x80000000 + i));
  76. GPIOVER("gpio[%d], in(%x)\n", i, mt_get_gpio_in(0x80000000 + i));
  77. }
  78. GPIOVER("[gpio dct config] ----------------------------\n");
  79. }
  80. void mt_gpio_set_default_dump(void)
  81. {
  82. gpio_dump();
  83. }
  84. #include <platform/boot_mode.h>
  85. #include <debug.h>
  86. #include <stdlib.h>
  87. #include <string.h>
  88. #include <video.h>
  89. #include <dev/uart.h>
  90. #include <arch/arm.h>
  91. #include <arch/arm/mmu.h>
  92. #include <arch/ops.h>
  93. #include <target/board.h>
  94. #include <platform/mt_reg_base.h>
  95. #include <platform/mt_disp_drv.h>
  96. #include <platform/disp_drv.h>
  97. #include <platform/boot_mode.h>
  98. #include <platform/mt_logo.h>
  99. #include <platform/partition.h>
  100. #include <env.h>
  101. #include <platform/mt_gpio.h>
  102. #include <platform/mt_pmic.h>
  103. #include <platform/mt_pmic_wrap_init.h>
  104. #include <platform/mt_i2c.h>
  105. #include <platform/mtk_key.h>
  106. #include <platform/mt_rtc.h>
  107. #include <platform/mt_leds.h>
  108. #include <platform/upmu_common.h>
  109. #include <platform/mtk_wdt.h>
  110. #include <platform/disp_drv_platform.h>
  111. #ifdef USE_DTB_NO_DWS/* for use DTB No DWS */
  112. #include <libfdt.h>
  113. #include <lk_builtin_dtb.h>
  114. extern void msdc_gpio_and_pad_init_by_id(int id);
  115. #define ELEMENTS_PER_GPIO 7
  116. #define GPIO_DT_NODE_NAME "/gpio@10005000"
  117. #define GPIO_DT_NODE_PROP_NAME "gpio_init_default"
  118. int mt_gpio_get_default_chip_from_dtb(void)
  119. {
  120. int off = fdt_path_offset(get_lk_overlayed_dtb(), GPIO_DT_NODE_NAME);
  121. unsigned int *data;
  122. int len = 0, pin, j;
  123. dprintf(INFO, "[GPIO] Found " GPIO_DT_NODE_NAME "at offset %d\n", off);
  124. if (off < 0) {
  125. dprintf(CRITICAL, "[GPIO] Failed to find " GPIO_DT_NODE_NAME " in dtb\n");
  126. return -1;
  127. } else {
  128. data = (unsigned int *)fdt_getprop(get_lk_overlayed_dtb(), off, GPIO_DT_NODE_PROP_NAME, &len);
  129. if (len <= 0 || !data) {
  130. dprintf(CRITICAL, "[GPIO] Fail to found property " GPIO_DT_NODE_PROP_NAME "\n");
  131. return -2;
  132. }
  133. dprintf(INFO, "[GPIO] Found perperty at 0x%08x, len %d\n", (unsigned int)data, len);
  134. }
  135. if ((len > 0) && ((len % ELEMENTS_PER_GPIO) == 0)) {
  136. len /= (ELEMENTS_PER_GPIO * 4); //Per element use 4 bytes */
  137. for (j = 0; j < len; j++) {
  138. pin = fdt32_to_cpu(*data);
  139. if (pin >= MT_GPIO_BASE_MAX) {
  140. data += 7;
  141. continue;
  142. }
  143. data++;/* maybe mode=-1 */
  144. gpio_array[pin].mode = (char) fdt32_to_cpu(*data);
  145. data++;
  146. gpio_array[pin].dir = (unsigned char) fdt32_to_cpu(*data);
  147. data++;
  148. gpio_array[pin].dataout = (unsigned char) fdt32_to_cpu(*data);
  149. data++;
  150. gpio_array[pin].pullen = (unsigned char) fdt32_to_cpu(*data);
  151. data++;
  152. gpio_array[pin].pull = (unsigned char) fdt32_to_cpu(*data);
  153. data++;
  154. gpio_array[pin].smt = (unsigned char) fdt32_to_cpu(*data);
  155. data++;
  156. #if 0
  157. dprintf(INFO, "[bxx]no dws GPIO: %d %d %d %d %d %d %d\n",
  158. pin,
  159. gpio_array[pin].mode,
  160. gpio_array[pin].dir,
  161. gpio_array[pin].dataout,
  162. gpio_array[pin].pullen,
  163. gpio_array[pin].pull,
  164. gpio_array[pin].smt
  165. );
  166. #endif
  167. }
  168. }
  169. return 0;
  170. }
  171. #endif
  172. void mt_gpio_set_default_chip(void)
  173. {
  174. unsigned pin = 0;
  175. #ifdef FPGA_SIMULATION
  176. GPIOVER("gpio debug base =%x\n", GPIO_RD32(GPIO_BASE));
  177. memset(GPIO_BASE, 0, 4096);
  178. #endif
  179. #ifdef USE_DTB_NO_DWS
  180. if (mt_gpio_get_default_chip_from_dtb() < 0) {
  181. dprintf(CRITICAL, "[GPIO] gpio_get_default_chip_from_dtb Failed!\n");
  182. return;
  183. }
  184. #endif
  185. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++) {
  186. #ifdef FPGA_SIMULATION
  187. GPIOVER("GPIO %d dump\n", pin);
  188. #endif
  189. #ifdef USE_DTB_NO_DWS
  190. #if 0
  191. if (gpio_array[pin].mode < 0)
  192. continue;/* init no cover gpios */
  193. else
  194. #endif
  195. if (pin > 121 && pin <134)
  196. continue;/* skip msdc pins init GPIO122~133 */
  197. #endif
  198. /* set GPIOx_MODE */
  199. mt_set_gpio_mode(0x80000000 + pin, gpio_array[pin].mode);
  200. /* set GPIOx_DIR */
  201. mt_set_gpio_dir(0x80000000 + pin, gpio_array[pin].dir);
  202. /* set GPIOx_PULLEN */
  203. mt_set_gpio_pull_enable(0x80000000 + pin, gpio_array[pin].pullen);
  204. /* set GPIOx_PULL */
  205. if (mt_get_gpio_pull_enable(0x80000000 + pin) == GPIO_PULL_ENABLE) {
  206. mt_set_gpio_pull_select(0x80000000 + pin, gpio_array[pin].pull);
  207. }
  208. /* set GPIOx_DATAOUT */
  209. mt_set_gpio_out(0x80000000 + pin, gpio_array[pin].dataout);
  210. /* set GPIOx_SMT */
  211. mt_set_gpio_smt(0x80000000 + pin, gpio_array[pin].smt);
  212. #ifndef USE_DTB_NO_DWS
  213. /* set GPIOx_IES */
  214. mt_set_gpio_ies(0x80000000 + pin, gpio_array[pin].ies);
  215. #if 0
  216. dprintf(INFO, "[bxx]dws-GPIO: %d %d %d %d %d %d %d\n",
  217. pin,
  218. gpio_array[pin].mode,
  219. gpio_array[pin].dir,
  220. gpio_array[pin].dataout,
  221. gpio_array[pin].pullen,
  222. gpio_array[pin].pull,
  223. gpio_array[pin].smt
  224. );
  225. #endif
  226. #endif
  227. }
  228. /* workaround for ap spi1's gpio mode */
  229. /* mt_set_gpio_mode(0x80000000 + 84, GPIO_MODE_01);
  230. mt_set_gpio_mode(0x80000000 + 85, GPIO_MODE_01);
  231. mt_set_gpio_mode(0x80000000 + 86, GPIO_MODE_01);
  232. mt_set_gpio_mode(0x80000000 + 87, GPIO_MODE_01);
  233. */
  234. #ifdef SELF_TEST
  235. mt_gpio_self_test();
  236. #endif
  237. }
  238. void mt_gpio_set_default(void)
  239. {
  240. mt_gpio_set_default_chip();
  241. return;
  242. }
  243. #ifdef SELF_TEST
  244. int smt_test(void)
  245. {
  246. int i, val;
  247. s32 out;
  248. int res;
  249. GPIOVER("smt_test test+++++\n");
  250. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  251. /*prepare test */
  252. res = mt_set_gpio_mode(i | 0x80000000, 0);
  253. if (res)
  254. return -1;
  255. /*test */
  256. for (val = 0; val < GPIO_SMT_MAX; val++) {
  257. GPIOVER("test gpio[%d],smt[%d]\n", i, val);
  258. if (-1 == mt_set_gpio_smt(i | 0x80000000, val)) {
  259. GPIOERR(" set smt unsupport\n");
  260. continue;
  261. }
  262. if ((res = mt_set_gpio_smt(i | 0x80000000, val)) != RSUCCESS) {
  263. GPIOERR(" set smt[%d] fail: %d\n", val, res);
  264. return -1;
  265. }
  266. if (val != mt_get_gpio_smt(i | 0x80000000)) {
  267. GPIOERR(" get smt[%d] fail: real get %d\n", val, mt_get_gpio_smt(i | 0x80000000));
  268. return -1;
  269. }
  270. if (mt_get_gpio_smt(i | 0x80000000) > 1) {
  271. GPIOERR(" get smt[%d] value fail: real get %d\n", val, mt_get_gpio_smt(i | 0x80000000));
  272. return -1;
  273. }
  274. }
  275. }
  276. GPIOVER("smt_test test----- PASS!\n");
  277. return 0;
  278. }
  279. int output_test(void)
  280. {
  281. int i, val;
  282. s32 out;
  283. int res;
  284. GPIOVER("output test+++++\n");
  285. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  286. /*prepare test */
  287. res = mt_set_gpio_mode(i | 0x80000000, 0);
  288. if (res)
  289. return -1;
  290. res = mt_set_gpio_dir(i | 0x80000000, GPIO_DIR_OUT);
  291. if (res)
  292. return -1;
  293. /*test */
  294. for (val = 0; val < GPIO_OUT_MAX; val++) {
  295. GPIOVER("test gpio[%d],output[%d]\n", i, val);
  296. if ((res = mt_set_gpio_out(i | 0x80000000, val)) != RSUCCESS) {
  297. GPIOERR(" set out[%d] fail: %d\n", val, res);
  298. return -1;
  299. }
  300. if (val != mt_get_gpio_out(i | 0x80000000)) {
  301. GPIOERR(" get out[%d] fail: real get %d\n", val, mt_get_gpio_out(i | 0x80000000));
  302. return -1;
  303. }
  304. if (mt_get_gpio_out(i | 0x80000000) > 1) {
  305. GPIOERR(" get out[%d] value fail: real get %d\n", val, mt_get_gpio_out(i | 0x80000000));
  306. return -1;
  307. }
  308. }
  309. }
  310. GPIOVER("output test----- PASS!\n");
  311. return 0;
  312. }
  313. int direction_test(void)
  314. {
  315. int i, val;
  316. s32 out;
  317. int res;
  318. GPIOVER("direction_test test+++++\n");
  319. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  320. /*prepare test */
  321. res = mt_set_gpio_mode(i | 0x80000000, 0);
  322. if (res)
  323. return -1;
  324. /*test */
  325. for (val = 0; val < GPIO_DIR_MAX; val++) {
  326. GPIOVER("test gpio[%d],direction[%d]\n", i, val);
  327. if ((res = mt_set_gpio_dir(i | 0x80000000, val)) != RSUCCESS) {
  328. GPIOERR(" set direction[%d] fail: %d\n", val, res);
  329. return -1;
  330. }
  331. if (val != mt_get_gpio_dir(i | 0x80000000)) {
  332. GPIOERR(" get direction[%d] fail1 real get %d\n", val, mt_get_gpio_dir(i | 0x80000000));
  333. return -1;
  334. }
  335. if (mt_get_gpio_dir(i | 0x80000000) > 1) {
  336. GPIOERR(" get direction[%d] value fail2 real get %d\n", val,
  337. mt_get_gpio_dir(i | 0x80000000));
  338. return -1;
  339. }
  340. }
  341. }
  342. GPIOVER("direction_test----- PASS!\n");
  343. return 0;
  344. }
  345. int mode_test(void)
  346. {
  347. int i, val;
  348. s32 out;
  349. int res;
  350. GPIOVER("mode_test test+++++\n");
  351. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  352. /*test */
  353. for (val = 0; val < GPIO_MODE_MAX; val++) {
  354. GPIOVER("test gpio[%d],dir[%d]\n", i, val);
  355. if ((res = mt_set_gpio_mode(i | 0x80000000, val)) != RSUCCESS) {
  356. GPIOERR(" set mode[%d] fail: %d\n", val, res);
  357. return -1;
  358. }
  359. if (val != mt_get_gpio_mode(i | 0x80000000)) {
  360. GPIOERR(" get mode[%d] fail: real get %d\n", val, mt_get_gpio_mode(i | 0x80000000));
  361. return -1;
  362. }
  363. if (mt_get_gpio_mode(i | 0x80000000) > 7) {
  364. GPIOERR(" get mode[%d] value fail: real get %d\n", val,
  365. mt_get_gpio_mode(i | 0x80000000));
  366. return -1;
  367. }
  368. }
  369. }
  370. GPIOVER("mode_test----- PASS!\n");
  371. return 0;
  372. }
  373. int pullen_test(void)
  374. {
  375. int i, val;
  376. s32 out;
  377. int res;
  378. GPIOVER("pullen_test +++++\n");
  379. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  380. /*prepare test */
  381. res = mt_set_gpio_mode(i | 0x80000000, 0);
  382. if (res)
  383. return -1;
  384. /*test */
  385. for (val = 0; val < GPIO_PULL_EN_MAX; val++) {
  386. GPIOVER("test gpio[%d],pullen[%d]\n", i, val);
  387. if (-1 == mt_set_gpio_pull_enable(i | 0x80000000, val)) {
  388. GPIOERR(" set pull_enable unsupport\n");
  389. continue;
  390. }
  391. if (GPIO_NOPULLDOWN == mt_set_gpio_pull_enable(i | 0x80000000, val)) {
  392. GPIOERR(" set pull_down unsupport\n");
  393. continue;
  394. }
  395. if (GPIO_NOPULLUP == mt_set_gpio_pull_enable(i | 0x80000000, val)) {
  396. GPIOERR(" set pull_up unsupport\n");
  397. continue;
  398. }
  399. if ((res = mt_set_gpio_pull_enable(i | 0x80000000, val)) != RSUCCESS) {
  400. GPIOERR(" set pull_enable[%d] fail1 %d\n", val, res);
  401. return -1;
  402. }
  403. if (val != mt_get_gpio_pull_enable(i | 0x80000000)) {
  404. GPIOERR(" get pull_enable[%d] fail2 real get %d\n", val,
  405. mt_get_gpio_pull_enable(i | 0x80000000));
  406. return -1;
  407. }
  408. if (mt_get_gpio_pull_enable(i | 0x80000000) > 1) {
  409. GPIOERR(" get pull_enable[%d] value fail3: real get %d\n", val,
  410. mt_get_gpio_pull_enable(i | 0x80000000));
  411. return -1;
  412. }
  413. }
  414. }
  415. GPIOVER("pullen_test----- PASS!\n");
  416. return 0;
  417. }
  418. int pullselect_test(void)
  419. {
  420. int i, val;
  421. s32 out;
  422. int res;
  423. GPIOVER("pullselect_test +++++\n");
  424. for (i = 0; i < MT_GPIO_EXT_MAX; i++) {
  425. /*prepare test */
  426. res = mt_set_gpio_mode(i | 0x80000000, 0);
  427. if (res)
  428. return -1;
  429. /*test */
  430. for (val = 0; val < GPIO_PULL_MAX; val++) {
  431. GPIOVER("test gpio[%d],pull_select[%d]\n", i, val);
  432. res = mt_set_gpio_pull_select(i | 0x80000000, val);
  433. if (GPIO_PULL_UNSUPPORTED == res || GPIO_NOPULLUP == res || GPIO_NOPULLDOWN == res) {
  434. GPIOERR(" set gpio[%d] pull_select[%d] unsupport\n", i, val);
  435. continue;
  436. }
  437. if ((res = mt_set_gpio_pull_select(i | 0x80000000, val)) != RSUCCESS) {
  438. GPIOERR(" set pull_select[%d] fail1: %d\n", val, res);
  439. return -1;
  440. }
  441. if (val != mt_get_gpio_pull_select(i | 0x80000000)) {
  442. GPIOERR(" get pull_select[%d] fail2: real get %d\n", val,
  443. mt_get_gpio_pull_select(i | 0x80000000));
  444. return -1;
  445. }
  446. if (-1 == mt_get_gpio_pull_select(i | 0x80000000)) {
  447. GPIOERR(" set gpio[%d] pull_select not support\n", i);
  448. } else if (mt_get_gpio_pull_select(i | 0x80000000) > 2) {
  449. GPIOERR(" get pull_select[%d] value fail: real get %d\n", val,
  450. mt_get_gpio_pull_select(i | 0x80000000));
  451. return -1;
  452. }
  453. }
  454. }
  455. GPIOVER("pullselect_test----- PASS!\n");
  456. return 0;
  457. }
  458. void mt_gpio_self_test(void)
  459. {
  460. int err = 0;
  461. GPIOVER("GPIO self_test start\n");
  462. err = mode_test();
  463. if (err) {
  464. GPIOVER("GPIO self_test FAIL\n");
  465. return;
  466. }
  467. err = direction_test();
  468. if (err) {
  469. GPIOVER("GPIO self_test FAIL\n");
  470. return;
  471. }
  472. err = output_test();
  473. if (err) {
  474. GPIOVER("GPIO self_test FAIL\n");
  475. return;
  476. }
  477. err = smt_test();
  478. if (err) {
  479. GPIOVER("GPIO self_test FAIL\n");
  480. return;
  481. }
  482. err = pullen_test();
  483. if (err) {
  484. GPIOVER("GPIO self_test FAIL\n");
  485. return;
  486. }
  487. err = pullselect_test();
  488. if (err) {
  489. GPIOVER("GPIO self_test FAIL\n");
  490. return;
  491. }
  492. GPIOVER("GPIO self_test PASS\n");
  493. }
  494. #endif
  495. #endif