]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - drivers/staging/wilc1000/wilc_spi.c
Merge tag 'tegra-for-4.3-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-eoan-kernel.git] / drivers / staging / wilc1000 / wilc_spi.c
1 /* ////////////////////////////////////////////////////////////////////////// */
2 /* */
3 /* Copyright (c) Atmel Corporation. All rights reserved. */
4 /* */
5 /* Module Name: wilc_spi.c */
6 /* */
7 /* */
8 /* //////////////////////////////////////////////////////////////////////////// */
9
10 #include "wilc_wlan_if.h"
11 #include "wilc_wlan.h"
12
13 extern unsigned int int_clrd;
14
15 /*
16 * #include <linux/kernel.h>
17 * #include <linux/string.h>
18 */
19 typedef struct {
20 void *os_context;
21 int (*spi_tx)(uint8_t *, uint32_t);
22 int (*spi_rx)(uint8_t *, uint32_t);
23 int (*spi_trx)(uint8_t *, uint8_t *, uint32_t);
24 int (*spi_max_speed)(void);
25 wilc_debug_func dPrint;
26 int crc_off;
27 int nint;
28 int has_thrpt_enh;
29 } wilc_spi_t;
30
31 static wilc_spi_t g_spi;
32
33 static int spi_read(uint32_t, uint8_t *, uint32_t);
34 static int spi_write(uint32_t, uint8_t *, uint32_t);
35
36 /********************************************
37 *
38 * Crc7
39 *
40 ********************************************/
41
42 static const uint8_t crc7_syndrome_table[256] = {
43 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
44 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
45 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
46 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
47 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
48 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
49 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
50 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
51 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
52 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
53 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
54 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
55 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
56 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
57 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
58 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
59 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
60 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
61 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
62 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
63 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
64 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
65 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
66 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
67 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
68 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
69 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
70 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
71 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
72 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
73 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
74 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
75 };
76
77 static uint8_t crc7_byte(uint8_t crc, uint8_t data)
78 {
79 return crc7_syndrome_table[(crc << 1) ^ data];
80 }
81
82 static uint8_t crc7(uint8_t crc, const uint8_t *buffer, uint32_t len)
83 {
84 while (len--)
85 crc = crc7_byte(crc, *buffer++);
86 return crc;
87 }
88
89 /********************************************
90 *
91 * Spi protocol Function
92 *
93 ********************************************/
94
95 #define CMD_DMA_WRITE 0xc1
96 #define CMD_DMA_READ 0xc2
97 #define CMD_INTERNAL_WRITE 0xc3
98 #define CMD_INTERNAL_READ 0xc4
99 #define CMD_TERMINATE 0xc5
100 #define CMD_REPEAT 0xc6
101 #define CMD_DMA_EXT_WRITE 0xc7
102 #define CMD_DMA_EXT_READ 0xc8
103 #define CMD_SINGLE_WRITE 0xc9
104 #define CMD_SINGLE_READ 0xca
105 #define CMD_RESET 0xcf
106
107 #define N_OK 1
108 #define N_FAIL 0
109 #define N_RESET -1
110 #define N_RETRY -2
111
112 #define DATA_PKT_SZ_256 256
113 #define DATA_PKT_SZ_512 512
114 #define DATA_PKT_SZ_1K 1024
115 #define DATA_PKT_SZ_4K (4 * 1024)
116 #define DATA_PKT_SZ_8K (8 * 1024)
117 #define DATA_PKT_SZ DATA_PKT_SZ_8K
118
119 static int spi_cmd(uint8_t cmd, uint32_t adr, uint32_t data, uint32_t sz, uint8_t clockless)
120 {
121 uint8_t bc[9];
122 int len = 5;
123 int result = N_OK;
124
125 bc[0] = cmd;
126 switch (cmd) {
127 case CMD_SINGLE_READ: /* single word (4 bytes) read */
128 bc[1] = (uint8_t)(adr >> 16);
129 bc[2] = (uint8_t)(adr >> 8);
130 bc[3] = (uint8_t)adr;
131 len = 5;
132 break;
133
134 case CMD_INTERNAL_READ: /* internal register read */
135 bc[1] = (uint8_t)(adr >> 8);
136 if (clockless)
137 bc[1] |= (1 << 7);
138 bc[2] = (uint8_t)adr;
139 bc[3] = 0x00;
140 len = 5;
141 break;
142
143 case CMD_TERMINATE: /* termination */
144 bc[1] = 0x00;
145 bc[2] = 0x00;
146 bc[3] = 0x00;
147 len = 5;
148 break;
149
150 case CMD_REPEAT: /* repeat */
151 bc[1] = 0x00;
152 bc[2] = 0x00;
153 bc[3] = 0x00;
154 len = 5;
155 break;
156
157 case CMD_RESET: /* reset */
158 bc[1] = 0xff;
159 bc[2] = 0xff;
160 bc[3] = 0xff;
161 len = 5;
162 break;
163
164 case CMD_DMA_WRITE: /* dma write */
165 case CMD_DMA_READ: /* dma read */
166 bc[1] = (uint8_t)(adr >> 16);
167 bc[2] = (uint8_t)(adr >> 8);
168 bc[3] = (uint8_t)adr;
169 bc[4] = (uint8_t)(sz >> 8);
170 bc[5] = (uint8_t)(sz);
171 len = 7;
172 break;
173
174 case CMD_DMA_EXT_WRITE: /* dma extended write */
175 case CMD_DMA_EXT_READ: /* dma extended read */
176 bc[1] = (uint8_t)(adr >> 16);
177 bc[2] = (uint8_t)(adr >> 8);
178 bc[3] = (uint8_t)adr;
179 bc[4] = (uint8_t)(sz >> 16);
180 bc[5] = (uint8_t)(sz >> 8);
181 bc[6] = (uint8_t)(sz);
182 len = 8;
183 break;
184
185 case CMD_INTERNAL_WRITE: /* internal register write */
186 bc[1] = (uint8_t)(adr >> 8);
187 if (clockless)
188 bc[1] |= (1 << 7);
189 bc[2] = (uint8_t)(adr);
190 bc[3] = (uint8_t)(data >> 24);
191 bc[4] = (uint8_t)(data >> 16);
192 bc[5] = (uint8_t)(data >> 8);
193 bc[6] = (uint8_t)(data);
194 len = 8;
195 break;
196
197 case CMD_SINGLE_WRITE: /* single word write */
198 bc[1] = (uint8_t)(adr >> 16);
199 bc[2] = (uint8_t)(adr >> 8);
200 bc[3] = (uint8_t)(adr);
201 bc[4] = (uint8_t)(data >> 24);
202 bc[5] = (uint8_t)(data >> 16);
203 bc[6] = (uint8_t)(data >> 8);
204 bc[7] = (uint8_t)(data);
205 len = 9;
206 break;
207
208 default:
209 result = N_FAIL;
210 break;
211 }
212
213 if (result) {
214 if (!g_spi.crc_off)
215 bc[len - 1] = (crc7(0x7f, (const uint8_t *)&bc[0], len - 1)) << 1;
216 else
217 len -= 1;
218
219 if (!g_spi.spi_tx(bc, len)) {
220 PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
221 result = N_FAIL;
222 }
223 }
224
225 return result;
226 }
227
228 static int spi_cmd_rsp(uint8_t cmd)
229 {
230 uint8_t rsp;
231 int result = N_OK;
232
233 /**
234 * Command/Control response
235 **/
236 if ((cmd == CMD_RESET) ||
237 (cmd == CMD_TERMINATE) ||
238 (cmd == CMD_REPEAT)) {
239 if (!g_spi.spi_rx(&rsp, 1)) {
240 result = N_FAIL;
241 goto _fail_;
242 }
243 }
244
245 if (!g_spi.spi_rx(&rsp, 1)) {
246 PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n");
247 result = N_FAIL;
248 goto _fail_;
249 }
250
251 if (rsp != cmd) {
252 PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
253 result = N_FAIL;
254 goto _fail_;
255 }
256
257 /**
258 * State response
259 **/
260 if (!g_spi.spi_rx(&rsp, 1)) {
261 PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n");
262 result = N_FAIL;
263 goto _fail_;
264 }
265
266 if (rsp != 0x00) {
267 PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp);
268 result = N_FAIL;
269 }
270
271 _fail_:
272
273 return result;
274 }
275
276 static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
277 {
278 uint8_t wb[32], rb[32];
279 uint8_t wix, rix;
280 uint32_t len2;
281 uint8_t rsp;
282 int len = 0;
283 int result = N_OK;
284
285 wb[0] = cmd;
286 switch (cmd) {
287 case CMD_SINGLE_READ: /* single word (4 bytes) read */
288 wb[1] = (uint8_t)(adr >> 16);
289 wb[2] = (uint8_t)(adr >> 8);
290 wb[3] = (uint8_t)adr;
291 len = 5;
292 break;
293
294 case CMD_INTERNAL_READ: /* internal register read */
295 wb[1] = (uint8_t)(adr >> 8);
296 if (clockless == 1)
297 wb[1] |= (1 << 7);
298 wb[2] = (uint8_t)adr;
299 wb[3] = 0x00;
300 len = 5;
301 break;
302
303 case CMD_TERMINATE: /* termination */
304 wb[1] = 0x00;
305 wb[2] = 0x00;
306 wb[3] = 0x00;
307 len = 5;
308 break;
309
310 case CMD_REPEAT: /* repeat */
311 wb[1] = 0x00;
312 wb[2] = 0x00;
313 wb[3] = 0x00;
314 len = 5;
315 break;
316
317 case CMD_RESET: /* reset */
318 wb[1] = 0xff;
319 wb[2] = 0xff;
320 wb[3] = 0xff;
321 len = 5;
322 break;
323
324 case CMD_DMA_WRITE: /* dma write */
325 case CMD_DMA_READ: /* dma read */
326 wb[1] = (uint8_t)(adr >> 16);
327 wb[2] = (uint8_t)(adr >> 8);
328 wb[3] = (uint8_t)adr;
329 wb[4] = (uint8_t)(sz >> 8);
330 wb[5] = (uint8_t)(sz);
331 len = 7;
332 break;
333
334 case CMD_DMA_EXT_WRITE: /* dma extended write */
335 case CMD_DMA_EXT_READ: /* dma extended read */
336 wb[1] = (uint8_t)(adr >> 16);
337 wb[2] = (uint8_t)(adr >> 8);
338 wb[3] = (uint8_t)adr;
339 wb[4] = (uint8_t)(sz >> 16);
340 wb[5] = (uint8_t)(sz >> 8);
341 wb[6] = (uint8_t)(sz);
342 len = 8;
343 break;
344
345 case CMD_INTERNAL_WRITE: /* internal register write */
346 wb[1] = (uint8_t)(adr >> 8);
347 if (clockless == 1)
348 wb[1] |= (1 << 7);
349 wb[2] = (uint8_t)(adr);
350 wb[3] = b[3];
351 wb[4] = b[2];
352 wb[5] = b[1];
353 wb[6] = b[0];
354 len = 8;
355 break;
356
357 case CMD_SINGLE_WRITE: /* single word write */
358 wb[1] = (uint8_t)(adr >> 16);
359 wb[2] = (uint8_t)(adr >> 8);
360 wb[3] = (uint8_t)(adr);
361 wb[4] = b[3];
362 wb[5] = b[2];
363 wb[6] = b[1];
364 wb[7] = b[0];
365 len = 9;
366 break;
367
368 default:
369 result = N_FAIL;
370 break;
371 }
372
373 if (result != N_OK) {
374 return result;
375 }
376
377 if (!g_spi.crc_off) {
378 wb[len - 1] = (crc7(0x7f, (const uint8_t *)&wb[0], len - 1)) << 1;
379 } else {
380 len -= 1;
381 }
382
383 #define NUM_SKIP_BYTES (1)
384 #define NUM_RSP_BYTES (2)
385 #define NUM_DATA_HDR_BYTES (1)
386 #define NUM_DATA_BYTES (4)
387 #define NUM_CRC_BYTES (2)
388 #define NUM_DUMMY_BYTES (3)
389 if ((cmd == CMD_RESET) ||
390 (cmd == CMD_TERMINATE) ||
391 (cmd == CMD_REPEAT)) {
392 len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
393 } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
394 if (!g_spi.crc_off) {
395 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
396 + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
397 } else {
398 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
399 + NUM_DUMMY_BYTES);
400 }
401 } else {
402 len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
403 }
404 #undef NUM_DUMMY_BYTES
405
406 if (len2 > (sizeof(wb) / sizeof(wb[0]))) {
407 PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%zu)\n",
408 len2, (sizeof(wb) / sizeof(wb[0])));
409 result = N_FAIL;
410 return result;
411 }
412 /* zero spi write buffers. */
413 for (wix = len; wix < len2; wix++) {
414 wb[wix] = 0;
415 }
416 rix = len;
417
418 if (!g_spi.spi_trx(wb, rb, len2)) {
419 PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
420 result = N_FAIL;
421 return result;
422 }
423
424 /**
425 * Command/Control response
426 **/
427 if ((cmd == CMD_RESET) ||
428 (cmd == CMD_TERMINATE) ||
429 (cmd == CMD_REPEAT)) {
430 rix++; /* skip 1 byte */
431 }
432
433 /* do { */
434 rsp = rb[rix++];
435 /* if(rsp == cmd) break; */
436 /* } while(&rptr[1] <= &rb[len2]); */
437
438 if (rsp != cmd) {
439 PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)"
440 ", resp (%02x)\n", cmd, rsp);
441 result = N_FAIL;
442 return result;
443 }
444
445 /**
446 * State response
447 **/
448 rsp = rb[rix++];
449 if (rsp != 0x00) {
450 PRINT_ER("[wilc spi]: Failed cmd state response "
451 "state (%02x)\n", rsp);
452 result = N_FAIL;
453 return result;
454 }
455
456 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
457 || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
458 int retry;
459 /* uint16_t crc1, crc2; */
460 uint8_t crc[2];
461 /**
462 * Data Respnose header
463 **/
464 retry = 100;
465 do {
466 /* ensure there is room in buffer later to read data and crc */
467 if (rix < len2) {
468 rsp = rb[rix++];
469 } else {
470 retry = 0;
471 break;
472 }
473 if (((rsp >> 4) & 0xf) == 0xf)
474 break;
475 } while (retry--);
476
477 if (retry <= 0) {
478 PRINT_ER("[wilc spi]: Error, data read "
479 "response (%02x)\n", rsp);
480 result = N_RESET;
481 return result;
482 }
483
484 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
485 /**
486 * Read bytes
487 **/
488 if ((rix + 3) < len2) {
489 b[0] = rb[rix++];
490 b[1] = rb[rix++];
491 b[2] = rb[rix++];
492 b[3] = rb[rix++];
493 } else {
494 PRINT_ER("[wilc spi]: buffer overrun when reading data.\n");
495 result = N_FAIL;
496 return result;
497 }
498
499 if (!g_spi.crc_off) {
500 /**
501 * Read Crc
502 **/
503 if ((rix + 1) < len2) {
504 crc[0] = rb[rix++];
505 crc[1] = rb[rix++];
506 } else {
507 PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n");
508 result = N_FAIL;
509 return result;
510 }
511 }
512 } else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
513 int ix;
514
515 /* some data may be read in response to dummy bytes. */
516 for (ix = 0; (rix < len2) && (ix < sz); ) {
517 b[ix++] = rb[rix++];
518 }
519
520 sz -= ix;
521
522 if (sz > 0) {
523 int nbytes;
524
525 if (sz <= (DATA_PKT_SZ - ix)) {
526 nbytes = sz;
527 } else {
528 nbytes = DATA_PKT_SZ - ix;
529 }
530
531 /**
532 * Read bytes
533 **/
534 if (!g_spi.spi_rx(&b[ix], nbytes)) {
535 PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
536 result = N_FAIL;
537 goto _error_;
538 }
539
540 /**
541 * Read Crc
542 **/
543 if (!g_spi.crc_off) {
544 if (!g_spi.spi_rx(crc, 2)) {
545 PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
546 result = N_FAIL;
547 goto _error_;
548 }
549 }
550
551
552 ix += nbytes;
553 sz -= nbytes;
554 }
555
556 /* if any data in left unread, then read the rest using normal DMA code.*/
557 while (sz > 0) {
558 int nbytes;
559
560 if (sz <= DATA_PKT_SZ) {
561 nbytes = sz;
562 } else {
563 nbytes = DATA_PKT_SZ;
564 }
565
566 /**
567 * read data response only on the next DMA cycles not
568 * the first DMA since data response header is already
569 * handled above for the first DMA.
570 **/
571 /**
572 * Data Respnose header
573 **/
574 retry = 10;
575 do {
576 if (!g_spi.spi_rx(&rsp, 1)) {
577 PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
578 result = N_FAIL;
579 break;
580 }
581 if (((rsp >> 4) & 0xf) == 0xf)
582 break;
583 } while (retry--);
584
585 if (result == N_FAIL)
586 break;
587
588
589 /**
590 * Read bytes
591 **/
592 if (!g_spi.spi_rx(&b[ix], nbytes)) {
593 PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
594 result = N_FAIL;
595 break;
596 }
597
598 /**
599 * Read Crc
600 **/
601 if (!g_spi.crc_off) {
602 if (!g_spi.spi_rx(crc, 2)) {
603 PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
604 result = N_FAIL;
605 break;
606 }
607 }
608
609 ix += nbytes;
610 sz -= nbytes;
611 }
612 }
613 }
614 _error_:
615 return result;
616 }
617
618 static int spi_data_read(uint8_t *b, uint32_t sz)
619 {
620 int retry, ix, nbytes;
621 int result = N_OK;
622 uint8_t crc[2];
623 uint8_t rsp;
624
625 /**
626 * Data
627 **/
628 ix = 0;
629 do {
630 if (sz <= DATA_PKT_SZ)
631 nbytes = sz;
632 else
633 nbytes = DATA_PKT_SZ;
634
635 /**
636 * Data Respnose header
637 **/
638 retry = 10;
639 do {
640 if (!g_spi.spi_rx(&rsp, 1)) {
641 PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
642 result = N_FAIL;
643 break;
644 }
645 if (((rsp >> 4) & 0xf) == 0xf)
646 break;
647 } while (retry--);
648
649 if (result == N_FAIL)
650 break;
651
652 if (retry <= 0) {
653 PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp);
654 result = N_FAIL;
655 break;
656 }
657
658 /**
659 * Read bytes
660 **/
661 if (!g_spi.spi_rx(&b[ix], nbytes)) {
662 PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
663 result = N_FAIL;
664 break;
665 }
666
667 /**
668 * Read Crc
669 **/
670 if (!g_spi.crc_off) {
671 if (!g_spi.spi_rx(crc, 2)) {
672 PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
673 result = N_FAIL;
674 break;
675 }
676 }
677
678 ix += nbytes;
679 sz -= nbytes;
680
681 } while (sz);
682
683 return result;
684 }
685
686 static int spi_data_write(uint8_t *b, uint32_t sz)
687 {
688 int ix, nbytes;
689 int result = 1;
690 uint8_t cmd, order, crc[2] = {0};
691 /* uint8_t rsp; */
692
693 /**
694 * Data
695 **/
696 ix = 0;
697 do {
698 if (sz <= DATA_PKT_SZ)
699 nbytes = sz;
700 else
701 nbytes = DATA_PKT_SZ;
702
703 /**
704 * Write command
705 **/
706 cmd = 0xf0;
707 if (ix == 0) {
708 if (sz <= DATA_PKT_SZ)
709
710 order = 0x3;
711 else
712 order = 0x1;
713 } else {
714 if (sz <= DATA_PKT_SZ)
715 order = 0x3;
716 else
717 order = 0x2;
718 }
719 cmd |= order;
720 if (!g_spi.spi_tx(&cmd, 1)) {
721 PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n");
722 result = N_FAIL;
723 break;
724 }
725
726 /**
727 * Write data
728 **/
729 if (!g_spi.spi_tx(&b[ix], nbytes)) {
730 PRINT_ER("[wilc spi]: Failed data block write, bus error...\n");
731 result = N_FAIL;
732 break;
733 }
734
735 /**
736 * Write Crc
737 **/
738 if (!g_spi.crc_off) {
739 if (!g_spi.spi_tx(crc, 2)) {
740 PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n");
741 result = N_FAIL;
742 break;
743 }
744 }
745
746 /**
747 * No need to wait for response
748 **/
749 ix += nbytes;
750 sz -= nbytes;
751 } while (sz);
752
753
754 return result;
755 }
756
757 /********************************************
758 *
759 * Spi Internal Read/Write Function
760 *
761 ********************************************/
762
763 static int spi_internal_write(uint32_t adr, uint32_t dat)
764 {
765 int result;
766
767 #if defined USE_OLD_SPI_SW
768 /**
769 * Command
770 **/
771 result = spi_cmd(CMD_INTERNAL_WRITE, adr, dat, 4, 0);
772 if (result != N_OK) {
773 PRINT_ER("[wilc spi]: Failed internal write cmd...\n");
774 return 0;
775 }
776
777 result = spi_cmd_rsp(CMD_INTERNAL_WRITE, 0);
778 if (result != N_OK) {
779 PRINT_ER("[wilc spi]: Failed internal write cmd response...\n");
780 }
781 #else
782
783 #ifdef BIG_ENDIAN
784 dat = BYTE_SWAP(dat);
785 #endif
786 result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (uint8_t *)&dat, 4, 0);
787 if (result != N_OK) {
788 PRINT_ER("[wilc spi]: Failed internal write cmd...\n");
789 }
790
791 #endif
792 return result;
793 }
794
795 static int spi_internal_read(uint32_t adr, uint32_t *data)
796 {
797 int result;
798
799 #if defined USE_OLD_SPI_SW
800 result = spi_cmd(CMD_INTERNAL_READ, adr, 0, 4, 0);
801 if (result != N_OK) {
802 PRINT_ER("[wilc spi]: Failed internal read cmd...\n");
803 return 0;
804 }
805
806 result = spi_cmd_rsp(CMD_INTERNAL_READ, 0);
807 if (result != N_OK) {
808 PRINT_ER("[wilc spi]: Failed internal read cmd response...\n");
809 return 0;
810 }
811
812 /**
813 * Data
814 **/
815 result = spi_data_read((uint8_t *)data, 4);
816 if (result != N_OK) {
817 PRINT_ER("[wilc spi]: Failed internal read data...\n");
818 return 0;
819 }
820 #else
821 result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (uint8_t *)data, 4, 0);
822 if (result != N_OK) {
823 PRINT_ER("[wilc spi]: Failed internal read cmd...\n");
824 return 0;
825 }
826 #endif
827
828
829 #ifdef BIG_ENDIAN
830 *data = BYTE_SWAP(*data);
831 #endif
832
833 return 1;
834 }
835
836 /********************************************
837 *
838 * Spi interfaces
839 *
840 ********************************************/
841
842 static int spi_write_reg(uint32_t addr, uint32_t data)
843 {
844 int result = N_OK;
845 uint8_t cmd = CMD_SINGLE_WRITE;
846 uint8_t clockless = 0;
847
848
849 #if defined USE_OLD_SPI_SW
850 {
851 result = spi_cmd(cmd, addr, data, 4, 0);
852 if (result != N_OK) {
853 PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr);
854 return 0;
855 }
856
857 result = spi_cmd_rsp(cmd, 0);
858 if (result != N_OK) {
859 PRINT_ER("[wilc spi]: Failed cmd response, write reg (%08x)...\n", addr);
860 return 0;
861 }
862
863 return 1;
864 }
865 #else
866 #ifdef BIG_ENDIAN
867 data = BYTE_SWAP(data);
868 #endif
869 if (addr < 0x30) {
870 /* Clockless register*/
871 cmd = CMD_INTERNAL_WRITE;
872 clockless = 1;
873 }
874
875 result = spi_cmd_complete(cmd, addr, (uint8_t *)&data, 4, clockless);
876 if (result != N_OK) {
877 PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr);
878 }
879
880 return result;
881 #endif
882
883 }
884
885 static int spi_write(uint32_t addr, uint8_t *buf, uint32_t size)
886 {
887 int result;
888 uint8_t cmd = CMD_DMA_EXT_WRITE;
889
890 /**
891 * has to be greated than 4
892 **/
893 if (size <= 4)
894 return 0;
895
896 #if defined USE_OLD_SPI_SW
897 /**
898 * Command
899 **/
900 result = spi_cmd(cmd, addr, 0, size, 0);
901 if (result != N_OK) {
902 PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr);
903 return 0;
904 }
905
906 result = spi_cmd_rsp(cmd, 0);
907 if (result != N_OK) {
908 PRINT_ER("[wilc spi ]: Failed cmd response, write block (%08x)...\n", addr);
909 return 0;
910 }
911 #else
912 result = spi_cmd_complete(cmd, addr, NULL, size, 0);
913 if (result != N_OK) {
914 PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr);
915 return 0;
916 }
917 #endif
918
919 /**
920 * Data
921 **/
922 result = spi_data_write(buf, size);
923 if (result != N_OK) {
924 PRINT_ER("[wilc spi]: Failed block data write...\n");
925 }
926
927 return 1;
928 }
929
930 static int spi_read_reg(uint32_t addr, uint32_t *data)
931 {
932 int result = N_OK;
933 uint8_t cmd = CMD_SINGLE_READ;
934 uint8_t clockless = 0;
935
936 #if defined USE_OLD_SPI_SW
937 result = spi_cmd(cmd, addr, 0, 4, 0);
938 if (result != N_OK) {
939 PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr);
940 return 0;
941 }
942 result = spi_cmd_rsp(cmd, 0);
943 if (result != N_OK) {
944 PRINT_ER("[wilc spi]: Failed cmd response, read reg (%08x)...\n", addr);
945 return 0;
946 }
947
948 result = spi_data_read((uint8_t *)data, 4);
949 if (result != N_OK) {
950 PRINT_ER("[wilc spi]: Failed data read...\n");
951 return 0;
952 }
953 #else
954 if (addr < 0x30) {
955 /* PRINT_ER("***** read addr %d\n\n", addr); */
956 /* Clockless register*/
957 cmd = CMD_INTERNAL_READ;
958 clockless = 1;
959 }
960
961 result = spi_cmd_complete(cmd, addr, (uint8_t *)data, 4, clockless);
962 if (result != N_OK) {
963 PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr);
964 return 0;
965 }
966 #endif
967
968
969 #ifdef BIG_ENDIAN
970 *data = BYTE_SWAP(*data);
971 #endif
972
973 return 1;
974 }
975
976 static int spi_read(uint32_t addr, uint8_t *buf, uint32_t size)
977 {
978 uint8_t cmd = CMD_DMA_EXT_READ;
979 int result;
980
981 if (size <= 4)
982 return 0;
983
984 #if defined USE_OLD_SPI_SW
985 /**
986 * Command
987 **/
988 result = spi_cmd(cmd, addr, 0, size, 0);
989 if (result != N_OK) {
990 PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr);
991 return 0;
992 }
993
994 result = spi_cmd_rsp(cmd, 0);
995 if (result != N_OK) {
996 PRINT_ER("[wilc spi]: Failed cmd response, read block (%08x)...\n", addr);
997 return 0;
998 }
999
1000 /**
1001 * Data
1002 **/
1003 result = spi_data_read(buf, size);
1004 if (result != N_OK) {
1005 PRINT_ER("[wilc spi]: Failed block data read...\n");
1006 return 0;
1007 }
1008 #else
1009 result = spi_cmd_complete(cmd, addr, buf, size, 0);
1010 if (result != N_OK) {
1011 PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr);
1012 return 0;
1013 }
1014 #endif
1015
1016
1017 return 1;
1018 }
1019
1020 /********************************************
1021 *
1022 * Bus interfaces
1023 *
1024 ********************************************/
1025
1026 static int spi_clear_int(void)
1027 {
1028 uint32_t reg;
1029 if (!spi_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
1030 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
1031 return 0;
1032 }
1033 reg &= ~0x1;
1034 spi_write_reg(WILC_HOST_RX_CTRL_0, reg);
1035 int_clrd++;
1036 return 1;
1037 }
1038
1039 static int spi_deinit(void *pv)
1040 {
1041 /**
1042 * TODO:
1043 **/
1044 return 1;
1045 }
1046
1047 static int spi_sync(void)
1048 {
1049 uint32_t reg;
1050 int ret;
1051
1052 /**
1053 * interrupt pin mux select
1054 **/
1055 ret = spi_read_reg(WILC_PIN_MUX_0, &reg);
1056 if (!ret) {
1057 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
1058 return 0;
1059 }
1060 reg |= (1 << 8);
1061 ret = spi_write_reg(WILC_PIN_MUX_0, reg);
1062 if (!ret) {
1063 PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
1064 return 0;
1065 }
1066
1067 /**
1068 * interrupt enable
1069 **/
1070 ret = spi_read_reg(WILC_INTR_ENABLE, &reg);
1071 if (!ret) {
1072 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
1073 return 0;
1074 }
1075 reg |= (1 << 16);
1076 ret = spi_write_reg(WILC_INTR_ENABLE, reg);
1077 if (!ret) {
1078 PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
1079 return 0;
1080 }
1081
1082 return 1;
1083 }
1084
1085 static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func)
1086 {
1087 uint32_t reg;
1088 uint32_t chipid;
1089
1090 static int isinit;
1091
1092 if (isinit) {
1093
1094 if (!spi_read_reg(0x1000, &chipid)) {
1095 PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
1096 return 0;
1097 }
1098 return 1;
1099 }
1100
1101 memset(&g_spi, 0, sizeof(wilc_spi_t));
1102
1103 g_spi.dPrint = func;
1104 g_spi.os_context = inp->os_context.os_private;
1105 if (inp->io_func.io_init) {
1106 if (!inp->io_func.io_init(g_spi.os_context)) {
1107 PRINT_ER("[wilc spi]: Failed io init bus...\n");
1108 return 0;
1109 }
1110 } else {
1111 return 0;
1112 }
1113 g_spi.spi_tx = inp->io_func.u.spi.spi_tx;
1114 g_spi.spi_rx = inp->io_func.u.spi.spi_rx;
1115 g_spi.spi_trx = inp->io_func.u.spi.spi_trx;
1116 g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed;
1117
1118 /**
1119 * configure protocol
1120 **/
1121 g_spi.crc_off = 0;
1122
1123 /* TODO: We can remove the CRC trials if there is a definite way to reset */
1124 /* the SPI to it's initial value. */
1125 if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, &reg)) {
1126 /* Read failed. Try with CRC off. This might happen when module
1127 * is removed but chip isn't reset*/
1128 g_spi.crc_off = 1;
1129 PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
1130 if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, &reg)) {
1131 /* Reaad failed with both CRC on and off, something went bad */
1132 PRINT_ER("[wilc spi]: Failed internal read protocol...\n");
1133 return 0;
1134 }
1135 }
1136 if (g_spi.crc_off == 0) {
1137 reg &= ~0xc; /* disable crc checking */
1138 reg &= ~0x70;
1139 reg |= (0x5 << 4);
1140 if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) {
1141 PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__);
1142 return 0;
1143 }
1144 g_spi.crc_off = 1;
1145 }
1146
1147
1148 /**
1149 * make sure can read back chip id correctly
1150 **/
1151 if (!spi_read_reg(0x1000, &chipid)) {
1152 PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
1153 return 0;
1154 }
1155 /* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */
1156
1157 g_spi.has_thrpt_enh = 1;
1158
1159 isinit = 1;
1160
1161 return 1;
1162 }
1163
1164 static void spi_max_bus_speed(void)
1165 {
1166 g_spi.spi_max_speed();
1167 }
1168
1169 static void spi_default_bus_speed(void)
1170 {
1171 }
1172
1173 static int spi_read_size(uint32_t *size)
1174 {
1175 int ret;
1176 if (g_spi.has_thrpt_enh) {
1177 ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size);
1178 *size = *size & IRQ_DMA_WD_CNT_MASK;
1179 } else {
1180 uint32_t tmp;
1181 uint32_t byte_cnt;
1182
1183 ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
1184 if (!ret) {
1185 PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
1186 goto _fail_;
1187 }
1188 tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
1189 *size = tmp;
1190 }
1191
1192
1193
1194 _fail_:
1195 return ret;
1196 }
1197
1198
1199
1200 static int spi_read_int(uint32_t *int_status)
1201 {
1202 int ret;
1203 if (g_spi.has_thrpt_enh) {
1204 ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status);
1205 } else {
1206 uint32_t tmp;
1207 uint32_t byte_cnt;
1208
1209 ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
1210 if (!ret) {
1211 PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
1212 goto _fail_;
1213 }
1214 tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
1215
1216 {
1217 int happended, j;
1218
1219 j = 0;
1220 do {
1221 uint32_t irq_flags;
1222
1223 happended = 0;
1224
1225 spi_read_reg(0x1a90, &irq_flags);
1226 tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
1227
1228 if (g_spi.nint > 5) {
1229 spi_read_reg(0x1a94, &irq_flags);
1230 tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5));
1231 }
1232
1233 {
1234 uint32_t unkmown_mask;
1235
1236 unkmown_mask = ~((1ul << g_spi.nint) - 1);
1237
1238 if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
1239 PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
1240 happended = 1;
1241 }
1242 }
1243 j++;
1244 } while (happended);
1245 }
1246
1247 *int_status = tmp;
1248
1249 }
1250
1251 _fail_:
1252 return ret;
1253 }
1254
1255 static int spi_clear_int_ext(uint32_t val)
1256 {
1257 int ret;
1258
1259 if (g_spi.has_thrpt_enh) {
1260 ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val);
1261 } else {
1262 uint32_t flags;
1263 flags = val & ((1 << MAX_NUM_INT) - 1);
1264 if (flags) {
1265 int i;
1266
1267 ret = 1;
1268 for (i = 0; i < g_spi.nint; i++) {
1269 /* No matter what you write 1 or 0, it will clear interrupt. */
1270 if (flags & 1)
1271 ret = spi_write_reg(0x10c8 + i * 4, 1);
1272 if (!ret)
1273 break;
1274 flags >>= 1;
1275 }
1276 if (!ret) {
1277 PRINT_ER("[wilc spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4);
1278 goto _fail_;
1279 }
1280 for (i = g_spi.nint; i < MAX_NUM_INT; i++) {
1281 if (flags & 1)
1282 PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i);
1283 flags >>= 1;
1284 }
1285 }
1286
1287 {
1288 uint32_t tbl_ctl;
1289
1290 tbl_ctl = 0;
1291 /* select VMM table 0 */
1292 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
1293 tbl_ctl |= (1 << 0);
1294 /* select VMM table 1 */
1295 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
1296 tbl_ctl |= (1 << 1);
1297
1298 ret = spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl);
1299 if (!ret) {
1300 PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n");
1301 goto _fail_;
1302 }
1303
1304 if ((val & EN_VMM) == EN_VMM) {
1305 /**
1306 * enable vmm transfer.
1307 **/
1308 ret = spi_write_reg(WILC_VMM_CORE_CTL, 1);
1309 if (!ret) {
1310 PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n");
1311 goto _fail_;
1312 }
1313 }
1314 }
1315 }
1316 _fail_:
1317 return ret;
1318 }
1319
1320 static int spi_sync_ext(int nint /* how mant interrupts to enable. */)
1321 {
1322 uint32_t reg;
1323 int ret, i;
1324
1325 if (nint > MAX_NUM_INT) {
1326 PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint);
1327 return 0;
1328 }
1329
1330 g_spi.nint = nint;
1331
1332 /**
1333 * interrupt pin mux select
1334 **/
1335 ret = spi_read_reg(WILC_PIN_MUX_0, &reg);
1336 if (!ret) {
1337 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
1338 return 0;
1339 }
1340 reg |= (1 << 8);
1341 ret = spi_write_reg(WILC_PIN_MUX_0, reg);
1342 if (!ret) {
1343 PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
1344 return 0;
1345 }
1346
1347 /**
1348 * interrupt enable
1349 **/
1350 ret = spi_read_reg(WILC_INTR_ENABLE, &reg);
1351 if (!ret) {
1352 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
1353 return 0;
1354 }
1355
1356 for (i = 0; (i < 5) && (nint > 0); i++, nint--) {
1357 reg |= (1 << (27 + i));
1358 }
1359 ret = spi_write_reg(WILC_INTR_ENABLE, reg);
1360 if (!ret) {
1361 PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
1362 return 0;
1363 }
1364 if (nint) {
1365 ret = spi_read_reg(WILC_INTR2_ENABLE, &reg);
1366 if (!ret) {
1367 PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
1368 return 0;
1369 }
1370
1371 for (i = 0; (i < 3) && (nint > 0); i++, nint--) {
1372 reg |= (1 << i);
1373 }
1374
1375 ret = spi_read_reg(WILC_INTR2_ENABLE, &reg);
1376 if (!ret) {
1377 PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
1378 return 0;
1379 }
1380 }
1381
1382 return 1;
1383 }
1384 /********************************************
1385 *
1386 * Global spi HIF function table
1387 *
1388 ********************************************/
1389 wilc_hif_func_t hif_spi = {
1390 spi_init,
1391 spi_deinit,
1392 spi_read_reg,
1393 spi_write_reg,
1394 spi_read,
1395 spi_write,
1396 spi_sync,
1397 spi_clear_int,
1398 spi_read_int,
1399 spi_clear_int_ext,
1400 spi_read_size,
1401 spi_write,
1402 spi_read,
1403 spi_sync_ext,
1404 spi_max_bus_speed,
1405 spi_default_bus_speed,
1406 };