wilc_sdio.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. /* ////////////////////////////////////////////////////////////////////////// */
  2. /* */
  3. /* Copyright (c) Atmel Corporation. All rights reserved. */
  4. /* */
  5. /* Module Name: wilc_sdio.c */
  6. /* */
  7. /* */
  8. /* //////////////////////////////////////////////////////////////////////////// */
  9. #include <linux/string.h>
  10. #include "wilc_wlan_if.h"
  11. #include "wilc_wlan.h"
  12. #define WILC_SDIO_BLOCK_SIZE 512
  13. typedef struct {
  14. void *os_context;
  15. u32 block_size;
  16. int (*sdio_cmd52)(sdio_cmd52_t *);
  17. int (*sdio_cmd53)(sdio_cmd53_t *);
  18. int (*sdio_set_max_speed)(void);
  19. int (*sdio_set_default_speed)(void);
  20. wilc_debug_func dPrint;
  21. int nint;
  22. #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
  23. int has_thrpt_enh3;
  24. } wilc_sdio_t;
  25. static wilc_sdio_t g_sdio;
  26. #ifdef WILC_SDIO_IRQ_GPIO
  27. static int sdio_write_reg(u32 addr, u32 data);
  28. static int sdio_read_reg(u32 addr, u32 *data);
  29. #endif
  30. /********************************************
  31. *
  32. * Function 0
  33. *
  34. ********************************************/
  35. static int sdio_set_func0_csa_address(u32 adr)
  36. {
  37. sdio_cmd52_t cmd;
  38. /**
  39. * Review: BIG ENDIAN
  40. **/
  41. cmd.read_write = 1;
  42. cmd.function = 0;
  43. cmd.raw = 0;
  44. cmd.address = 0x10c;
  45. cmd.data = (u8)adr;
  46. if (!g_sdio.sdio_cmd52(&cmd)) {
  47. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n");
  48. goto _fail_;
  49. }
  50. cmd.address = 0x10d;
  51. cmd.data = (u8)(adr >> 8);
  52. if (!g_sdio.sdio_cmd52(&cmd)) {
  53. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n");
  54. goto _fail_;
  55. }
  56. cmd.address = 0x10e;
  57. cmd.data = (u8)(adr >> 16);
  58. if (!g_sdio.sdio_cmd52(&cmd)) {
  59. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n");
  60. goto _fail_;
  61. }
  62. return 1;
  63. _fail_:
  64. return 0;
  65. }
  66. static int sdio_set_func0_block_size(u32 block_size)
  67. {
  68. sdio_cmd52_t cmd;
  69. cmd.read_write = 1;
  70. cmd.function = 0;
  71. cmd.raw = 0;
  72. cmd.address = 0x10;
  73. cmd.data = (u8)block_size;
  74. if (!g_sdio.sdio_cmd52(&cmd)) {
  75. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n");
  76. goto _fail_;
  77. }
  78. cmd.address = 0x11;
  79. cmd.data = (u8)(block_size >> 8);
  80. if (!g_sdio.sdio_cmd52(&cmd)) {
  81. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n");
  82. goto _fail_;
  83. }
  84. return 1;
  85. _fail_:
  86. return 0;
  87. }
  88. /********************************************
  89. *
  90. * Function 1
  91. *
  92. ********************************************/
  93. static int sdio_set_func1_block_size(u32 block_size)
  94. {
  95. sdio_cmd52_t cmd;
  96. cmd.read_write = 1;
  97. cmd.function = 0;
  98. cmd.raw = 0;
  99. cmd.address = 0x110;
  100. cmd.data = (u8)block_size;
  101. if (!g_sdio.sdio_cmd52(&cmd)) {
  102. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n");
  103. goto _fail_;
  104. }
  105. cmd.address = 0x111;
  106. cmd.data = (u8)(block_size >> 8);
  107. if (!g_sdio.sdio_cmd52(&cmd)) {
  108. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n");
  109. goto _fail_;
  110. }
  111. return 1;
  112. _fail_:
  113. return 0;
  114. }
  115. static int sdio_clear_int(void)
  116. {
  117. #ifndef WILC_SDIO_IRQ_GPIO
  118. /* u32 sts; */
  119. sdio_cmd52_t cmd;
  120. cmd.read_write = 0;
  121. cmd.function = 1;
  122. cmd.raw = 0;
  123. cmd.address = 0x4;
  124. cmd.data = 0;
  125. g_sdio.sdio_cmd52(&cmd);
  126. return cmd.data;
  127. #else
  128. u32 reg;
  129. if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
  130. g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
  131. return 0;
  132. }
  133. reg &= ~0x1;
  134. sdio_write_reg(WILC_HOST_RX_CTRL_0, reg);
  135. return 1;
  136. #endif
  137. }
  138. u32 sdio_xfer_cnt(void)
  139. {
  140. u32 cnt = 0;
  141. sdio_cmd52_t cmd;
  142. cmd.read_write = 0;
  143. cmd.function = 1;
  144. cmd.raw = 0;
  145. cmd.address = 0x1C;
  146. cmd.data = 0;
  147. g_sdio.sdio_cmd52(&cmd);
  148. cnt = cmd.data;
  149. cmd.read_write = 0;
  150. cmd.function = 1;
  151. cmd.raw = 0;
  152. cmd.address = 0x1D;
  153. cmd.data = 0;
  154. g_sdio.sdio_cmd52(&cmd);
  155. cnt |= (cmd.data << 8);
  156. cmd.read_write = 0;
  157. cmd.function = 1;
  158. cmd.raw = 0;
  159. cmd.address = 0x1E;
  160. cmd.data = 0;
  161. g_sdio.sdio_cmd52(&cmd);
  162. cnt |= (cmd.data << 16);
  163. return cnt;
  164. }
  165. /********************************************
  166. *
  167. * Sdio interfaces
  168. *
  169. ********************************************/
  170. int sdio_check_bs(void)
  171. {
  172. sdio_cmd52_t cmd;
  173. /**
  174. * poll until BS is 0
  175. **/
  176. cmd.read_write = 0;
  177. cmd.function = 0;
  178. cmd.raw = 0;
  179. cmd.address = 0xc;
  180. cmd.data = 0;
  181. if (!g_sdio.sdio_cmd52(&cmd)) {
  182. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n");
  183. goto _fail_;
  184. }
  185. return 1;
  186. _fail_:
  187. return 0;
  188. }
  189. static int sdio_write_reg(u32 addr, u32 data)
  190. {
  191. #ifdef BIG_ENDIAN
  192. data = BYTE_SWAP(data);
  193. #endif
  194. if ((addr >= 0xf0) && (addr <= 0xff)) {
  195. sdio_cmd52_t cmd;
  196. cmd.read_write = 1;
  197. cmd.function = 0;
  198. cmd.raw = 0;
  199. cmd.address = addr;
  200. cmd.data = data;
  201. if (!g_sdio.sdio_cmd52(&cmd)) {
  202. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
  203. goto _fail_;
  204. }
  205. } else {
  206. sdio_cmd53_t cmd;
  207. /**
  208. * set the AHB address
  209. **/
  210. if (!sdio_set_func0_csa_address(addr))
  211. goto _fail_;
  212. cmd.read_write = 1;
  213. cmd.function = 0;
  214. cmd.address = 0x10f;
  215. cmd.block_mode = 0;
  216. cmd.increment = 1;
  217. cmd.count = 4;
  218. cmd.buffer = (u8 *)&data;
  219. cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
  220. if (!g_sdio.sdio_cmd53(&cmd)) {
  221. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr);
  222. goto _fail_;
  223. }
  224. }
  225. return 1;
  226. _fail_:
  227. return 0;
  228. }
  229. static int sdio_write(u32 addr, u8 *buf, u32 size)
  230. {
  231. u32 block_size = g_sdio.block_size;
  232. sdio_cmd53_t cmd;
  233. int nblk, nleft;
  234. cmd.read_write = 1;
  235. if (addr > 0) {
  236. /**
  237. * has to be word aligned...
  238. **/
  239. if (size & 0x3) {
  240. size += 4;
  241. size &= ~0x3;
  242. }
  243. /**
  244. * func 0 access
  245. **/
  246. cmd.function = 0;
  247. cmd.address = 0x10f;
  248. } else {
  249. /**
  250. * has to be word aligned...
  251. **/
  252. if (size & 0x3) {
  253. size += 4;
  254. size &= ~0x3;
  255. }
  256. /**
  257. * func 1 access
  258. **/
  259. cmd.function = 1;
  260. cmd.address = 0;
  261. }
  262. nblk = size / block_size;
  263. nleft = size % block_size;
  264. if (nblk > 0) {
  265. cmd.block_mode = 1;
  266. cmd.increment = 1;
  267. cmd.count = nblk;
  268. cmd.buffer = buf;
  269. cmd.block_size = block_size;
  270. if (addr > 0) {
  271. if (!sdio_set_func0_csa_address(addr))
  272. goto _fail_;
  273. }
  274. if (!g_sdio.sdio_cmd53(&cmd)) {
  275. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr);
  276. goto _fail_;
  277. }
  278. if (addr > 0)
  279. addr += nblk * block_size;
  280. buf += nblk * block_size;
  281. }
  282. if (nleft > 0) {
  283. cmd.block_mode = 0;
  284. cmd.increment = 1;
  285. cmd.count = nleft;
  286. cmd.buffer = buf;
  287. cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
  288. if (addr > 0) {
  289. if (!sdio_set_func0_csa_address(addr))
  290. goto _fail_;
  291. }
  292. if (!g_sdio.sdio_cmd53(&cmd)) {
  293. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr);
  294. goto _fail_;
  295. }
  296. }
  297. return 1;
  298. _fail_:
  299. return 0;
  300. }
  301. static int sdio_read_reg(u32 addr, u32 *data)
  302. {
  303. if ((addr >= 0xf0) && (addr <= 0xff)) {
  304. sdio_cmd52_t cmd;
  305. cmd.read_write = 0;
  306. cmd.function = 0;
  307. cmd.raw = 0;
  308. cmd.address = addr;
  309. if (!g_sdio.sdio_cmd52(&cmd)) {
  310. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
  311. goto _fail_;
  312. }
  313. *data = cmd.data;
  314. } else {
  315. sdio_cmd53_t cmd;
  316. if (!sdio_set_func0_csa_address(addr))
  317. goto _fail_;
  318. cmd.read_write = 0;
  319. cmd.function = 0;
  320. cmd.address = 0x10f;
  321. cmd.block_mode = 0;
  322. cmd.increment = 1;
  323. cmd.count = 4;
  324. cmd.buffer = (u8 *)data;
  325. cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
  326. if (!g_sdio.sdio_cmd53(&cmd)) {
  327. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr);
  328. goto _fail_;
  329. }
  330. }
  331. #ifdef BIG_ENDIAN
  332. *data = BYTE_SWAP(*data);
  333. #endif
  334. return 1;
  335. _fail_:
  336. return 0;
  337. }
  338. static int sdio_read(u32 addr, u8 *buf, u32 size)
  339. {
  340. u32 block_size = g_sdio.block_size;
  341. sdio_cmd53_t cmd;
  342. int nblk, nleft;
  343. cmd.read_write = 0;
  344. if (addr > 0) {
  345. /**
  346. * has to be word aligned...
  347. **/
  348. if (size & 0x3) {
  349. size += 4;
  350. size &= ~0x3;
  351. }
  352. /**
  353. * func 0 access
  354. **/
  355. cmd.function = 0;
  356. cmd.address = 0x10f;
  357. } else {
  358. /**
  359. * has to be word aligned...
  360. **/
  361. if (size & 0x3) {
  362. size += 4;
  363. size &= ~0x3;
  364. }
  365. /**
  366. * func 1 access
  367. **/
  368. cmd.function = 1;
  369. cmd.address = 0;
  370. }
  371. nblk = size / block_size;
  372. nleft = size % block_size;
  373. if (nblk > 0) {
  374. cmd.block_mode = 1;
  375. cmd.increment = 1;
  376. cmd.count = nblk;
  377. cmd.buffer = buf;
  378. cmd.block_size = block_size;
  379. if (addr > 0) {
  380. if (!sdio_set_func0_csa_address(addr))
  381. goto _fail_;
  382. }
  383. if (!g_sdio.sdio_cmd53(&cmd)) {
  384. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr);
  385. goto _fail_;
  386. }
  387. if (addr > 0)
  388. addr += nblk * block_size;
  389. buf += nblk * block_size;
  390. } /* if (nblk > 0) */
  391. if (nleft > 0) {
  392. cmd.block_mode = 0;
  393. cmd.increment = 1;
  394. cmd.count = nleft;
  395. cmd.buffer = buf;
  396. cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
  397. if (addr > 0) {
  398. if (!sdio_set_func0_csa_address(addr))
  399. goto _fail_;
  400. }
  401. if (!g_sdio.sdio_cmd53(&cmd)) {
  402. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr);
  403. goto _fail_;
  404. }
  405. }
  406. return 1;
  407. _fail_:
  408. return 0;
  409. }
  410. /********************************************
  411. *
  412. * Bus interfaces
  413. *
  414. ********************************************/
  415. static int sdio_deinit(void *pv)
  416. {
  417. return 1;
  418. }
  419. static int sdio_sync(void)
  420. {
  421. u32 reg;
  422. /**
  423. * Disable power sequencer
  424. **/
  425. if (!sdio_read_reg(WILC_MISC, &reg)) {
  426. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
  427. return 0;
  428. }
  429. reg &= ~BIT(8);
  430. if (!sdio_write_reg(WILC_MISC, reg)) {
  431. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
  432. return 0;
  433. }
  434. #ifdef WILC_SDIO_IRQ_GPIO
  435. {
  436. u32 reg;
  437. int ret;
  438. /**
  439. * interrupt pin mux select
  440. **/
  441. ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
  442. if (!ret) {
  443. g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
  444. return 0;
  445. }
  446. reg |= BIT(8);
  447. ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
  448. if (!ret) {
  449. g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
  450. return 0;
  451. }
  452. /**
  453. * interrupt enable
  454. **/
  455. ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
  456. if (!ret) {
  457. g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
  458. return 0;
  459. }
  460. reg |= BIT(16);
  461. ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
  462. if (!ret) {
  463. g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
  464. return 0;
  465. }
  466. }
  467. #endif
  468. return 1;
  469. }
  470. static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func)
  471. {
  472. sdio_cmd52_t cmd;
  473. int loop;
  474. u32 chipid;
  475. memset(&g_sdio, 0, sizeof(wilc_sdio_t));
  476. g_sdio.dPrint = func;
  477. g_sdio.os_context = inp->os_context.os_private;
  478. if (inp->io_func.io_init) {
  479. if (!inp->io_func.io_init(g_sdio.os_context)) {
  480. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n");
  481. return 0;
  482. }
  483. } else {
  484. return 0;
  485. }
  486. g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52;
  487. g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53;
  488. g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed;
  489. g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed;
  490. /**
  491. * function 0 csa enable
  492. **/
  493. cmd.read_write = 1;
  494. cmd.function = 0;
  495. cmd.raw = 1;
  496. cmd.address = 0x100;
  497. cmd.data = 0x80;
  498. if (!g_sdio.sdio_cmd52(&cmd)) {
  499. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n");
  500. goto _fail_;
  501. }
  502. /**
  503. * function 0 block size
  504. **/
  505. if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) {
  506. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n");
  507. goto _fail_;
  508. }
  509. g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
  510. /**
  511. * enable func1 IO
  512. **/
  513. cmd.read_write = 1;
  514. cmd.function = 0;
  515. cmd.raw = 1;
  516. cmd.address = 0x2;
  517. cmd.data = 0x2;
  518. if (!g_sdio.sdio_cmd52(&cmd)) {
  519. g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n");
  520. goto _fail_;
  521. }
  522. /**
  523. * make sure func 1 is up
  524. **/
  525. cmd.read_write = 0;
  526. cmd.function = 0;
  527. cmd.raw = 0;
  528. cmd.address = 0x3;
  529. loop = 3;
  530. do {
  531. cmd.data = 0;
  532. if (!g_sdio.sdio_cmd52(&cmd)) {
  533. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n");
  534. goto _fail_;
  535. }
  536. if (cmd.data == 0x2)
  537. break;
  538. } while (loop--);
  539. if (loop <= 0) {
  540. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n");
  541. goto _fail_;
  542. }
  543. /**
  544. * func 1 is ready, set func 1 block size
  545. **/
  546. if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) {
  547. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n");
  548. goto _fail_;
  549. }
  550. /**
  551. * func 1 interrupt enable
  552. **/
  553. cmd.read_write = 1;
  554. cmd.function = 0;
  555. cmd.raw = 1;
  556. cmd.address = 0x4;
  557. cmd.data = 0x3;
  558. if (!g_sdio.sdio_cmd52(&cmd)) {
  559. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n");
  560. goto _fail_;
  561. }
  562. /**
  563. * make sure can read back chip id correctly
  564. **/
  565. if (!sdio_read_reg(0x1000, &chipid)) {
  566. g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n");
  567. goto _fail_;
  568. }
  569. g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid);
  570. if ((chipid & 0xfff) > 0x2a0)
  571. g_sdio.has_thrpt_enh3 = 1;
  572. else
  573. g_sdio.has_thrpt_enh3 = 0;
  574. g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
  575. return 1;
  576. _fail_:
  577. return 0;
  578. }
  579. static void sdio_set_max_speed(void)
  580. {
  581. g_sdio.sdio_set_max_speed();
  582. }
  583. static void sdio_set_default_speed(void)
  584. {
  585. g_sdio.sdio_set_default_speed();
  586. }
  587. static int sdio_read_size(u32 *size)
  588. {
  589. u32 tmp;
  590. sdio_cmd52_t cmd;
  591. /**
  592. * Read DMA count in words
  593. **/
  594. cmd.read_write = 0;
  595. cmd.function = 0;
  596. cmd.raw = 0;
  597. cmd.address = 0xf2;
  598. cmd.data = 0;
  599. g_sdio.sdio_cmd52(&cmd);
  600. tmp = cmd.data;
  601. /* cmd.read_write = 0; */
  602. /* cmd.function = 0; */
  603. /* cmd.raw = 0; */
  604. cmd.address = 0xf3;
  605. cmd.data = 0;
  606. g_sdio.sdio_cmd52(&cmd);
  607. tmp |= (cmd.data << 8);
  608. *size = tmp;
  609. return 1;
  610. }
  611. static int sdio_read_int(u32 *int_status)
  612. {
  613. u32 tmp;
  614. sdio_cmd52_t cmd;
  615. sdio_read_size(&tmp);
  616. /**
  617. * Read IRQ flags
  618. **/
  619. #ifndef WILC_SDIO_IRQ_GPIO
  620. cmd.function = 1;
  621. cmd.address = 0x04;
  622. cmd.data = 0;
  623. g_sdio.sdio_cmd52(&cmd);
  624. if (cmd.data & BIT(0))
  625. tmp |= INT_0;
  626. if (cmd.data & BIT(2))
  627. tmp |= INT_1;
  628. if (cmd.data & BIT(3))
  629. tmp |= INT_2;
  630. if (cmd.data & BIT(4))
  631. tmp |= INT_3;
  632. if (cmd.data & BIT(5))
  633. tmp |= INT_4;
  634. if (cmd.data & BIT(6))
  635. tmp |= INT_5;
  636. {
  637. int i;
  638. for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
  639. if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
  640. g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data);
  641. break;
  642. }
  643. }
  644. }
  645. #else
  646. {
  647. u32 irq_flags;
  648. cmd.read_write = 0;
  649. cmd.function = 0;
  650. cmd.raw = 0;
  651. cmd.address = 0xf7;
  652. cmd.data = 0;
  653. g_sdio.sdio_cmd52(&cmd);
  654. irq_flags = cmd.data & 0x1f;
  655. tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
  656. }
  657. #endif
  658. *int_status = tmp;
  659. return 1;
  660. }
  661. static int sdio_clear_int_ext(u32 val)
  662. {
  663. int ret;
  664. if (g_sdio.has_thrpt_enh3) {
  665. u32 reg;
  666. #ifdef WILC_SDIO_IRQ_GPIO
  667. {
  668. u32 flags;
  669. flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
  670. reg = flags;
  671. }
  672. #else
  673. reg = 0;
  674. #endif
  675. /* select VMM table 0 */
  676. if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
  677. reg |= BIT(5);
  678. /* select VMM table 1 */
  679. if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
  680. reg |= BIT(6);
  681. /* enable VMM */
  682. if ((val & EN_VMM) == EN_VMM)
  683. reg |= BIT(7);
  684. if (reg) {
  685. sdio_cmd52_t cmd;
  686. cmd.read_write = 1;
  687. cmd.function = 0;
  688. cmd.raw = 0;
  689. cmd.address = 0xf8;
  690. cmd.data = reg;
  691. ret = g_sdio.sdio_cmd52(&cmd);
  692. if (!ret) {
  693. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
  694. goto _fail_;
  695. }
  696. }
  697. } else {
  698. #ifdef WILC_SDIO_IRQ_GPIO
  699. {
  700. /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
  701. /* Cannot clear multiple interrupts. Must clear each interrupt individually */
  702. u32 flags;
  703. flags = val & (BIT(MAX_NUM_INT) - 1);
  704. if (flags) {
  705. int i;
  706. ret = 1;
  707. for (i = 0; i < g_sdio.nint; i++) {
  708. if (flags & 1) {
  709. sdio_cmd52_t cmd;
  710. cmd.read_write = 1;
  711. cmd.function = 0;
  712. cmd.raw = 0;
  713. cmd.address = 0xf8;
  714. cmd.data = BIT(i);
  715. ret = g_sdio.sdio_cmd52(&cmd);
  716. if (!ret) {
  717. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
  718. goto _fail_;
  719. }
  720. }
  721. if (!ret)
  722. break;
  723. flags >>= 1;
  724. }
  725. if (!ret)
  726. goto _fail_;
  727. for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
  728. if (flags & 1)
  729. g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i);
  730. flags >>= 1;
  731. }
  732. }
  733. }
  734. #endif /* WILC_SDIO_IRQ_GPIO */
  735. {
  736. u32 vmm_ctl;
  737. vmm_ctl = 0;
  738. /* select VMM table 0 */
  739. if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
  740. vmm_ctl |= BIT(0);
  741. /* select VMM table 1 */
  742. if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
  743. vmm_ctl |= BIT(1);
  744. /* enable VMM */
  745. if ((val & EN_VMM) == EN_VMM)
  746. vmm_ctl |= BIT(2);
  747. if (vmm_ctl) {
  748. sdio_cmd52_t cmd;
  749. cmd.read_write = 1;
  750. cmd.function = 0;
  751. cmd.raw = 0;
  752. cmd.address = 0xf6;
  753. cmd.data = vmm_ctl;
  754. ret = g_sdio.sdio_cmd52(&cmd);
  755. if (!ret) {
  756. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__);
  757. goto _fail_;
  758. }
  759. }
  760. }
  761. }
  762. return 1;
  763. _fail_:
  764. return 0;
  765. }
  766. static int sdio_sync_ext(int nint /* how mant interrupts to enable. */)
  767. {
  768. u32 reg;
  769. if (nint > MAX_NUM_INT) {
  770. g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint);
  771. return 0;
  772. }
  773. if (nint > MAX_NUN_INT_THRPT_ENH2) {
  774. g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
  775. return 0;
  776. }
  777. g_sdio.nint = nint;
  778. /**
  779. * Disable power sequencer
  780. **/
  781. if (!sdio_read_reg(WILC_MISC, &reg)) {
  782. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
  783. return 0;
  784. }
  785. reg &= ~BIT(8);
  786. if (!sdio_write_reg(WILC_MISC, reg)) {
  787. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
  788. return 0;
  789. }
  790. #ifdef WILC_SDIO_IRQ_GPIO
  791. {
  792. u32 reg;
  793. int ret, i;
  794. /**
  795. * interrupt pin mux select
  796. **/
  797. ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
  798. if (!ret) {
  799. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
  800. return 0;
  801. }
  802. reg |= BIT(8);
  803. ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
  804. if (!ret) {
  805. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
  806. return 0;
  807. }
  808. /**
  809. * interrupt enable
  810. **/
  811. ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
  812. if (!ret) {
  813. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
  814. return 0;
  815. }
  816. for (i = 0; (i < 5) && (nint > 0); i++, nint--)
  817. reg |= BIT((27 + i));
  818. ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
  819. if (!ret) {
  820. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
  821. return 0;
  822. }
  823. if (nint) {
  824. ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
  825. if (!ret) {
  826. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
  827. return 0;
  828. }
  829. for (i = 0; (i < 3) && (nint > 0); i++, nint--)
  830. reg |= BIT(i);
  831. ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
  832. if (!ret) {
  833. g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
  834. return 0;
  835. }
  836. }
  837. }
  838. #endif /* WILC_SDIO_IRQ_GPIO */
  839. return 1;
  840. }
  841. /********************************************
  842. *
  843. * Global sdio HIF function table
  844. *
  845. ********************************************/
  846. wilc_hif_func_t hif_sdio = {
  847. sdio_init,
  848. sdio_deinit,
  849. sdio_read_reg,
  850. sdio_write_reg,
  851. sdio_read,
  852. sdio_write,
  853. sdio_sync,
  854. sdio_clear_int,
  855. sdio_read_int,
  856. sdio_clear_int_ext,
  857. sdio_read_size,
  858. sdio_write,
  859. sdio_read,
  860. sdio_sync_ext,
  861. sdio_set_max_speed,
  862. sdio_set_default_speed,
  863. };