mt_spi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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) 2021. 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_spi.h>
  32. #include <malloc.h>
  33. #include <libfdt.h>
  34. static struct mtk_spi_bus *spi_bus[BUS_COUNT] = { NULL };
  35. static int spi_bus_num = -1;
  36. static const struct mtk_spi_bus_config spi_default_config = {
  37. .spi_mode = 0,
  38. .tick_delay = 0,
  39. };
  40. static void mtk_spi_dump_register(int bus_num)
  41. {
  42. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  43. dprintf(SPEW, "spi_cfg0_reg:0x%x\n", DRV_Reg32(&regs->spi_cfg0_reg));
  44. dprintf(SPEW, "spi_cfg1_reg:0x%x\n", DRV_Reg32(&regs->spi_cfg1_reg));
  45. dprintf(SPEW, "spi_tx_src_reg:0x%x\n",
  46. DRV_Reg32(&regs->spi_tx_src_reg));
  47. dprintf(SPEW, "spi_rx_dst_reg:0x%x\n",
  48. DRV_Reg32(&regs->spi_rx_dst_reg));
  49. dprintf(SPEW, "spi_cmd_reg:0x%x\n", DRV_Reg32(&regs->spi_cmd_reg));
  50. dprintf(SPEW, "spi_sta1_reg:0x%x\n", DRV_Reg32(&regs->spi_status1_reg));
  51. }
  52. static void mtk_spi_reset(int bus_num)
  53. {
  54. int reg_val;
  55. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  56. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  57. reg_val |= 1 << SPI_CMD_RST_SHIFT;
  58. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  59. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  60. reg_val &= ~(1 << SPI_CMD_RST_SHIFT);
  61. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  62. spi_bus[bus_num]->state = MTK_SPI_IDLE;
  63. }
  64. static void mtk_spi_set_cs(int bus_num, bool enable)
  65. {
  66. u32 reg_val;
  67. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  68. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  69. if (!enable) {
  70. reg_val |= 1 << SPI_CMD_PAUSE_EN_SHIFT;
  71. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  72. spi_bus[bus_num]->state = MTK_SPI_PAUSE_IDLE;
  73. } else {
  74. reg_val &= ~(1 << SPI_CMD_PAUSE_EN_SHIFT);
  75. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  76. mtk_spi_reset(bus_num);
  77. spi_bus[bus_num]->state = MTK_SPI_IDLE;
  78. }
  79. }
  80. static void mtk_spi_enable_transfer(int bus_num)
  81. {
  82. int reg_val;
  83. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  84. if (spi_bus[bus_num]->state == MTK_SPI_IDLE) {
  85. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  86. reg_val |= 1 << SPI_CMD_ACT_SHIFT;
  87. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  88. } else if (spi_bus[bus_num]->state == MTK_SPI_PAUSE_IDLE) {
  89. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  90. reg_val |= 1 << SPI_CMD_RESUME_SHIFT;
  91. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  92. }
  93. }
  94. static void mtk_spi_packet(int bus_num, int size)
  95. {
  96. int reg_val, packet_len, packet_loop;
  97. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  98. packet_len = size < MTK_PACKET_SIZE ? size : MTK_PACKET_SIZE;
  99. packet_loop = MTK_SPI_ROUNDUP_DIV(size, packet_len);
  100. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  101. reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
  102. reg_val |= ((packet_len - 1) << SPI_CFG1_PACKET_LENGTH_SHIFT) |
  103. ((packet_loop - 1) << SPI_CFG1_PACKET_LOOP_SHIFT);
  104. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  105. }
  106. static int mtk_spi_polling(int bus_num)
  107. {
  108. int i;
  109. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  110. /*
  111. *spi sw should wait for status1 register to idle before polling
  112. * status0 register for rx/tx finish.
  113. */
  114. i = 0;
  115. while ((DRV_Reg32(&regs->spi_status1_reg) &
  116. MTK_SPI_BUSY_STATUS) == 0) {
  117. i++;
  118. udelay(1);
  119. if (i > MTK_TXRX_TIMEOUT_US) {
  120. dprintf(CRITICAL, "Timeout for spi status1 reg.\n");
  121. goto error;
  122. }
  123. }
  124. i = 0;
  125. while ((DRV_Reg32(&regs->spi_status0_reg) &
  126. MTK_SPI_PAUSE_FINISH_INT_STATUS) == 0) {
  127. i++;
  128. udelay(1);
  129. if (i > MTK_TXRX_TIMEOUT_US) {
  130. dprintf(CRITICAL, "Timeout for spi status0 reg.\n");
  131. goto error;
  132. }
  133. }
  134. return 0;
  135. error:
  136. return -1;
  137. }
  138. static void spi_prepare_transfer(int bus_num, struct spi_transfer *transfer)
  139. {
  140. uint32_t div, sck_ticks, cs_ticks, reg_val;
  141. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  142. u32 speed_hz = transfer->speed_hz;
  143. if (speed_hz < (SPI_HZ / 2))
  144. div = MTK_SPI_ROUNDUP_DIV(SPI_HZ, speed_hz);
  145. else
  146. div = 1;
  147. sck_ticks = MTK_SPI_ROUNDUP_DIV(div, 2);
  148. cs_ticks = sck_ticks * 2;
  149. /* set the timing */
  150. mt_reg_sync_writel(((cs_ticks - 1) << SPI_CFG0_CS_HOLD_OFFSET) |
  151. ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_OFFSET),
  152. &regs->spi_cfg0_reg);
  153. mt_reg_sync_writel(((sck_ticks - 1) << SPI_CFG2_SCK_HIGH_OFFSET) |
  154. ((sck_ticks - 1) << SPI_CFG2_SCK_LOW_OFFSET),
  155. &regs->spi_cfg2_reg);
  156. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  157. reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
  158. reg_val |= (cs_ticks - 1) << SPI_CFG1_CS_IDLE_SHIFT;
  159. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  160. /* tick delay */
  161. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  162. reg_val |= (transfer->tick_delay << SPI_CFG1_GET_TICK_DLY_SHIFT);
  163. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  164. }
  165. static int mtk_spi_fifo_transfer(int bus_num, unsigned char *rx_buf,
  166. unsigned char *tx_buf, int size)
  167. {
  168. int i, reg_val = 0, word_count, ret, remaind;
  169. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  170. if (!size || size > MTK_FIFO_DEPTH)
  171. return -1;
  172. mtk_spi_packet(bus_num, size);
  173. remaind = size & 0x03;
  174. if (rx_buf && !tx_buf) {
  175. word_count = size >> 2;
  176. if (remaind)
  177. word_count++;
  178. for (i = 0; i < word_count; i++)
  179. mt_reg_sync_writel(MTK_ARBITRARY_VALUE,
  180. &regs->spi_tx_data_reg);
  181. }
  182. if (tx_buf) {
  183. reg_val = 0;
  184. for (i = 0; i < size - remaind; i++) {
  185. reg_val |= *(tx_buf + i) << ((i & 0x03) << 3);
  186. if ((i & 0x03) == 3) {
  187. mt_reg_sync_writel(reg_val,
  188. &regs->spi_tx_data_reg);
  189. reg_val = 0;
  190. }
  191. }
  192. if (remaind) {
  193. reg_val = 0;
  194. for (i = 0; i < remaind; i++) {
  195. reg_val |= *(tx_buf + size - remaind + i)
  196. << ((i & 0x03) << 3);
  197. }
  198. mt_reg_sync_writel(reg_val, &regs->spi_tx_data_reg);
  199. }
  200. }
  201. mtk_spi_enable_transfer(bus_num);
  202. ret = mtk_spi_polling(bus_num);
  203. if (!ret && rx_buf) {
  204. for (i = 0; i < size; i++) {
  205. if ((i & 0x03) == 0)
  206. reg_val = DRV_Reg32(&regs->spi_rx_data_reg);
  207. *(rx_buf + i) = (reg_val >> ((i & 0x03) << 3)) & 0xff;
  208. }
  209. }
  210. return ret;
  211. }
  212. static int mtk_spi_dma_transfer(int bus_num, unsigned char *rx_buf,
  213. unsigned char *tx_buf, int size)
  214. {
  215. int i, reg_val;
  216. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  217. if (!rx_buf && tx_buf) {
  218. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  219. reg_val |= 1 << SPI_CMD_TX_DMA_SHIFT;
  220. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  221. } else {
  222. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  223. reg_val |= (1 << SPI_CMD_RX_DMA_SHIFT) |
  224. (1 << SPI_CMD_TX_DMA_SHIFT);
  225. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  226. }
  227. if (tx_buf) {
  228. arch_clean_cache_range((addr_t)tx_buf, size);
  229. mt_reg_sync_writel(tx_buf, &regs->spi_tx_src_reg);
  230. }
  231. if (rx_buf) {
  232. arch_clean_cache_range((addr_t)rx_buf, size);
  233. mt_reg_sync_writel(rx_buf, &regs->spi_rx_dst_reg);
  234. }
  235. mtk_spi_packet(bus_num, size);
  236. mtk_spi_enable_transfer(bus_num);
  237. if (mtk_spi_polling(bus_num))
  238. goto error;
  239. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  240. reg_val &= ~(1 << SPI_CMD_RX_DMA_SHIFT | 1 << SPI_CMD_TX_DMA_SHIFT);
  241. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  242. if (rx_buf)
  243. arch_clean_invalidate_cache_range((addr_t)rx_buf, size);
  244. return 0;
  245. error:
  246. return -1;
  247. }
  248. int spi_sync(int bus_num, struct spi_transfer *transfer)
  249. {
  250. int ret, min_size;
  251. u8 *tx_buf = (u8 *)transfer->tx_buf;
  252. u8 *rx_buf = (u8 *)transfer->rx_buf;
  253. u32 size = transfer->len;
  254. spi_prepare_transfer(bus_num, transfer);
  255. while (size) {
  256. min_size = size < MTK_PACKET_SIZE ? size : MTK_PACKET_SIZE;
  257. if (size > MTK_FIFO_DEPTH)
  258. ret = mtk_spi_dma_transfer(bus_num, rx_buf, tx_buf,
  259. min_size);
  260. else
  261. ret = mtk_spi_fifo_transfer(bus_num, rx_buf, tx_buf,
  262. min_size);
  263. if (ret) {
  264. mtk_spi_reset(bus_num);
  265. return ret;
  266. }
  267. size -= min_size;
  268. if (rx_buf)
  269. rx_buf += min_size;
  270. if (tx_buf)
  271. tx_buf += min_size;
  272. }
  273. if (transfer->cs_change)
  274. mtk_spi_set_cs(bus_num, 1);
  275. else
  276. mtk_spi_set_cs(bus_num, 0);
  277. return ret;
  278. }
  279. static void spi_loopback_test(int bus_num)
  280. {
  281. u32 index, status, err_count = 0;
  282. struct spi_transfer transfer;
  283. u32 length = 400;
  284. dprintf(CRITICAL, "spi_loopback_test entry\n");
  285. transfer.tx_buf = (void *)malloc(length);
  286. transfer.rx_buf = (void *)malloc(length);
  287. transfer.speed_hz = 10000;
  288. transfer.cs_change = 1;
  289. transfer.len = 30;
  290. for (index = 0; index < transfer.len; index++) {
  291. ((u8 *)transfer.tx_buf)[index] = index % 255;
  292. ((u8 *)transfer.rx_buf)[index] = 0;
  293. }
  294. status = spi_sync(bus_num, &transfer);
  295. if (status)
  296. dprintf(CRITICAL, "spi transfer err: %d\n", status);
  297. while (transfer.len--) {
  298. if (((u8 *)transfer.tx_buf)[transfer.len] !=
  299. ((u8 *)transfer.rx_buf)[transfer.len]) {
  300. dprintf(CRITICAL, "spi pio data compare err: tx: %d rx: %d\n",
  301. ((u8 *)transfer.tx_buf)[transfer.len],
  302. ((u8 *)transfer.rx_buf)[transfer.len]);
  303. err_count++;
  304. }
  305. }
  306. dprintf(CRITICAL, "----SPI PIO MODE test done, err count is %d----\n",
  307. err_count);
  308. err_count = 0;
  309. transfer.len = length;
  310. for (index = 0; index < transfer.len; index++) {
  311. ((u8 *)transfer.tx_buf)[index] = index % 255;
  312. ((u8 *)transfer.rx_buf)[index] = 0;
  313. }
  314. status = spi_sync(bus_num, &transfer);
  315. if (status)
  316. dprintf(CRITICAL, "spi transfer err: %d\n", status);
  317. while (transfer.len--) {
  318. if (((u8 *)transfer.tx_buf)[transfer.len] !=
  319. ((u8 *)transfer.rx_buf)[transfer.len]) {
  320. dprintf(CRITICAL, "spi dma data compare err: tx: %d rx: %d\n",
  321. ((u8 *)transfer.tx_buf)[transfer.len],
  322. ((u8 *)transfer.rx_buf)[transfer.len]);
  323. err_count++;
  324. }
  325. }
  326. dprintf(CRITICAL, "----SPI DMA MODE test done, err count is %d----\n",
  327. err_count);
  328. free((void *)transfer.tx_buf);
  329. free((void *)transfer.rx_buf);
  330. dprintf(CRITICAL, "spi_loopback_test done\n");
  331. }
  332. static void spi_fdt_getprop_u32_array(int nodeoffset,
  333. const char *name, unsigned int *out_value)
  334. {
  335. unsigned int i;
  336. unsigned int *data = NULL;
  337. int len = 0;
  338. void *lk_drv_fdt = get_lk_overlayed_dtb();
  339. if (lk_drv_fdt == NULL)
  340. panic("lk driver fdt is NULL!\n");
  341. data = (unsigned int *)fdt_getprop(lk_drv_fdt, nodeoffset, name, &len);
  342. if (len > 0) {
  343. len = len / sizeof(unsigned int);
  344. for (i = 0; i < len; i++)
  345. *(out_value+i) = fdt32_to_cpu(*(data+i));
  346. } else
  347. *out_value = 0;
  348. }
  349. void mtk_spi_init(int bus_num, struct mtk_spi_bus_config *spi_config)
  350. {
  351. uint32_t reg_val;
  352. uint16_t cpha, cpol;
  353. struct mtk_spi_bus_config *spi_bus_config = spi_config;
  354. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  355. dprintf(SPEW, "mtk_spi_init entry\n");
  356. if (spi_bus_config == NULL)
  357. spi_bus_config = &spi_default_config;
  358. cpha = spi_bus_config->spi_mode & SPI_CPHA ? 1:0;
  359. cpol = spi_bus_config->spi_mode & SPI_CPOL ? 1:0;
  360. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  361. /* set spi mode */
  362. if (cpha)
  363. reg_val |= SPI_CMD_CPHA_EN;
  364. else
  365. reg_val &= ~SPI_CMD_CPHA_EN;
  366. if (cpol)
  367. reg_val |= SPI_CMD_CPOL_EN;
  368. else
  369. reg_val &= ~SPI_CMD_CPOL_EN;
  370. /* set the mlsbx and mlsbtx */
  371. reg_val &= ~SPI_CMD_TXMSBF_EN;
  372. reg_val &= ~SPI_CMD_RXMSBF_EN;
  373. /* set the tx/rx endian */
  374. reg_val &= ~SPI_CMD_TX_ENDIAN_EN;
  375. reg_val &= ~SPI_CMD_RX_ENDIAN_EN;
  376. /* clear pause mode */
  377. reg_val &= ~SPI_CMD_PAUSE_EN;
  378. /* set finish interrupt always disable */
  379. reg_val &= ~SPI_CMD_FINISH_IE_EN;
  380. /* set pause interrupt always disable */
  381. reg_val &= ~SPI_CMD_PAUSE_IE_EN;
  382. /* disable dma mode */
  383. reg_val &= ~(SPI_CMD_TX_DMA_EN | SPI_CMD_RX_DMA_EN);
  384. /* set deassert mode */
  385. reg_val &= ~SPI_CMD_DEASSERT_EN;
  386. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  387. /* pad select */
  388. reg_val = spi_bus[bus_num]->pad_select;
  389. mt_reg_sync_writel(reg_val, &regs->spi_pad_sel_reg);
  390. /* tick delay */
  391. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  392. reg_val |= (spi_bus_config->tick_delay << SPI_CFG1_GET_TICK_DLY_SHIFT);
  393. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  394. /* cs pull high && reset spi */
  395. mtk_spi_set_cs(bus_num, 1);
  396. #ifdef SPI_EARLY_PORTING
  397. reg_val = 7;
  398. mt_reg_sync_writel(reg_val, &regs->spi_pad_sel_reg);
  399. spi_loopback_test(bus_num);
  400. reg_val = spi_bus[bus_num]->pad_select;
  401. mt_reg_sync_writel(reg_val, &regs->spi_pad_sel_reg);
  402. #endif
  403. mtk_spi_reset(bus_num);
  404. }
  405. int init_spi_bus_from_dt(const char *compatible,
  406. struct mtk_spi_bus_config *config)
  407. {
  408. uint32_t node, parent_node = 0;
  409. uint32_t temp_data[4];
  410. uint32_t pad_select = 0;
  411. struct mtk_spi_bus *bus = NULL;
  412. void *lk_drv_fdt = get_lk_overlayed_dtb();
  413. if (lk_drv_fdt == NULL)
  414. panic("lk driver fdt is NULL!\n");
  415. node = fdt_node_offset_by_compatible(lk_drv_fdt, -1, compatible);
  416. if (node > 0) {
  417. parent_node = fdt_parent_offset(lk_drv_fdt, node);
  418. if (parent_node > 0) {
  419. bus = malloc(sizeof(struct mtk_spi_bus));
  420. if (bus) {
  421. spi_bus_num++;
  422. spi_bus[spi_bus_num] = bus;
  423. }
  424. spi_fdt_getprop_u32_array(parent_node,
  425. "reg", temp_data);
  426. spi_fdt_getprop_u32_array(parent_node,
  427. "mediatek,pad-select", &pad_select);
  428. spi_bus[spi_bus_num]->reg_addr = temp_data[1];
  429. spi_bus[spi_bus_num]->pad_select = pad_select;
  430. spi_bus[spi_bus_num]->spi_bus_fdt_offset = parent_node;
  431. dprintf(SPEW, "reg addr : %x, pad_select : %d\n",
  432. spi_bus[spi_bus_num]->reg_addr,
  433. spi_bus[spi_bus_num]->pad_select);
  434. } else {
  435. dprintf(SPEW, "get spi slave parent node failed!\n");
  436. return -1;
  437. }
  438. } else {
  439. dprintf(SPEW, "get spi slave node failed!\n");
  440. return -1;
  441. }
  442. mtk_spi_init(spi_bus_num, config);
  443. return spi_bus_num;
  444. }