Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / wilc1000 / wilc_spi.c
CommitLineData
c5c77ba1
JK
1/* ////////////////////////////////////////////////////////////////////////// */
2/* */
3/* Copyright (c) Atmel Corporation. All rights reserved. */
4/* */
5/* Module Name: wilc_spi.c */
6/* */
7/* */
8/* //////////////////////////////////////////////////////////////////////////// */
43a76229
GL
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/fs.h>
13#include <linux/slab.h>
14#include <linux/types.h>
15#include <linux/cdev.h>
16#include <linux/uaccess.h>
17#include <linux/device.h>
18#include <linux/spi/spi.h>
19#include <linux/of_gpio.h>
c5c77ba1 20
0c9fc33c 21#include <linux/string.h>
c5c77ba1
JK
22#include "wilc_wlan_if.h"
23#include "wilc_wlan.h"
9c800322 24#include "wilc_wfi_netdevice.h"
c5c77ba1 25
6a707a9e 26struct wilc_spi {
c5c77ba1
JK
27 int crc_off;
28 int nint;
29 int has_thrpt_enh;
6a707a9e 30};
c5c77ba1 31
6a707a9e 32static struct wilc_spi g_spi;
c5c77ba1 33
d4312b6f
GL
34static int wilc_spi_read(struct wilc *wilc, u32, u8 *, u32);
35static int wilc_spi_write(struct wilc *wilc, u32, u8 *, u32);
c5c77ba1
JK
36
37/********************************************
38 *
39 * Crc7
40 *
41 ********************************************/
42
51e825f7 43static const u8 crc7_syndrome_table[256] = {
c5c77ba1
JK
44 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
45 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
46 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
47 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
48 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
49 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
50 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
51 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
52 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
53 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
54 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
55 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
56 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
57 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
58 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
59 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
60 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
61 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
62 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
63 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
64 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
65 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
66 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
67 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
68 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
69 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
70 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
71 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
72 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
73 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
74 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
75 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
76};
77
51e825f7 78static u8 crc7_byte(u8 crc, u8 data)
c5c77ba1
JK
79{
80 return crc7_syndrome_table[(crc << 1) ^ data];
81}
82
fbc2fe16 83static u8 crc7(u8 crc, const u8 *buffer, u32 len)
c5c77ba1
JK
84{
85 while (len--)
86 crc = crc7_byte(crc, *buffer++);
87 return crc;
88}
89
90/********************************************
91 *
92 * Spi protocol Function
93 *
94 ********************************************/
95
96#define CMD_DMA_WRITE 0xc1
97#define CMD_DMA_READ 0xc2
98#define CMD_INTERNAL_WRITE 0xc3
99#define CMD_INTERNAL_READ 0xc4
100#define CMD_TERMINATE 0xc5
101#define CMD_REPEAT 0xc6
102#define CMD_DMA_EXT_WRITE 0xc7
103#define CMD_DMA_EXT_READ 0xc8
104#define CMD_SINGLE_WRITE 0xc9
105#define CMD_SINGLE_READ 0xca
106#define CMD_RESET 0xcf
107
108#define N_OK 1
109#define N_FAIL 0
110#define N_RESET -1
111#define N_RETRY -2
112
113#define DATA_PKT_SZ_256 256
114#define DATA_PKT_SZ_512 512
115#define DATA_PKT_SZ_1K 1024
116#define DATA_PKT_SZ_4K (4 * 1024)
117#define DATA_PKT_SZ_8K (8 * 1024)
118#define DATA_PKT_SZ DATA_PKT_SZ_8K
119
43a76229
GL
120#define USE_SPI_DMA 0
121
43a76229
GL
122static int wilc_bus_probe(struct spi_device *spi)
123{
124 int ret, gpio;
125 struct wilc *wilc;
126
127 gpio = of_get_gpio(spi->dev.of_node, 0);
128 if (gpio < 0)
129 gpio = GPIO_NUM;
130
131 ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, GPIO_NUM, &wilc_hif_spi);
132 if (ret)
133 return ret;
134
135 spi_set_drvdata(spi, wilc);
136 wilc->dev = &spi->dev;
137
138 return 0;
139}
140
141static int wilc_bus_remove(struct spi_device *spi)
142{
143 wilc_netdev_cleanup(spi_get_drvdata(spi));
144 return 0;
145}
146
147static const struct of_device_id wilc1000_of_match[] = {
148 { .compatible = "atmel,wilc_spi", },
149 {}
150};
151MODULE_DEVICE_TABLE(of, wilc1000_of_match);
152
d27afda3 153static struct spi_driver wilc1000_spi_driver = {
43a76229
GL
154 .driver = {
155 .name = MODALIAS,
156 .of_match_table = wilc1000_of_match,
157 },
158 .probe = wilc_bus_probe,
159 .remove = wilc_bus_remove,
160};
161module_spi_driver(wilc1000_spi_driver);
162MODULE_LICENSE("GPL");
163
164static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
165{
166 struct spi_device *spi = to_spi_device(wilc->dev);
167 int ret;
168 struct spi_message msg;
169
170 if (len > 0 && b) {
171 struct spi_transfer tr = {
172 .tx_buf = b,
173 .len = len,
174 .delay_usecs = 0,
175 };
176 char *r_buffer = kzalloc(len, GFP_KERNEL);
177
178 if (!r_buffer)
179 return -ENOMEM;
180
181 tr.rx_buf = r_buffer;
182 dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
183
184 memset(&msg, 0, sizeof(msg));
185 spi_message_init(&msg);
186 msg.spi = spi;
187 msg.is_dma_mapped = USE_SPI_DMA;
188 spi_message_add_tail(&tr, &msg);
189
190 ret = spi_sync(spi, &msg);
191 if (ret < 0)
192 dev_err(&spi->dev, "SPI transaction failed\n");
193
194 kfree(r_buffer);
195 } else {
196 dev_err(&spi->dev,
197 "can't write data with the following length: %d\n",
198 len);
43a76229
GL
199 ret = -EINVAL;
200 }
201
202 return ret;
203}
204
205static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
206{
207 struct spi_device *spi = to_spi_device(wilc->dev);
208 int ret;
209
210 if (rlen > 0) {
211 struct spi_message msg;
212 struct spi_transfer tr = {
213 .rx_buf = rb,
214 .len = rlen,
215 .delay_usecs = 0,
216
217 };
218 char *t_buffer = kzalloc(rlen, GFP_KERNEL);
219
220 if (!t_buffer)
221 return -ENOMEM;
222
223 tr.tx_buf = t_buffer;
224
225 memset(&msg, 0, sizeof(msg));
226 spi_message_init(&msg);
227 msg.spi = spi;
228 msg.is_dma_mapped = USE_SPI_DMA;
229 spi_message_add_tail(&tr, &msg);
230
231 ret = spi_sync(spi, &msg);
232 if (ret < 0)
233 dev_err(&spi->dev, "SPI transaction failed\n");
234 kfree(t_buffer);
235 } else {
236 dev_err(&spi->dev,
237 "can't read data with the following length: %u\n",
238 rlen);
239 ret = -EINVAL;
240 }
241
242 return ret;
243}
244
245static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
246{
247 struct spi_device *spi = to_spi_device(wilc->dev);
248 int ret;
249
250 if (rlen > 0) {
251 struct spi_message msg;
252 struct spi_transfer tr = {
253 .rx_buf = rb,
254 .tx_buf = wb,
255 .len = rlen,
256 .bits_per_word = 8,
257 .delay_usecs = 0,
258
259 };
260
261 memset(&msg, 0, sizeof(msg));
262 spi_message_init(&msg);
263 msg.spi = spi;
264 msg.is_dma_mapped = USE_SPI_DMA;
265
266 spi_message_add_tail(&tr, &msg);
267 ret = spi_sync(spi, &msg);
268 if (ret < 0)
269 dev_err(&spi->dev, "SPI transaction failed\n");
270 } else {
271 dev_err(&spi->dev,
272 "can't read data with the following length: %u\n",
273 rlen);
274 ret = -EINVAL;
275 }
276
277 return ret;
278}
279
49dcd0dd
GL
280static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
281 u8 clockless)
c5c77ba1 282{
ac1da162 283 struct spi_device *spi = to_spi_device(wilc->dev);
51e825f7
CL
284 u8 wb[32], rb[32];
285 u8 wix, rix;
fbc2fe16 286 u32 len2;
51e825f7 287 u8 rsp;
c5c77ba1
JK
288 int len = 0;
289 int result = N_OK;
290
291 wb[0] = cmd;
292 switch (cmd) {
293 case CMD_SINGLE_READ: /* single word (4 bytes) read */
51e825f7
CL
294 wb[1] = (u8)(adr >> 16);
295 wb[2] = (u8)(adr >> 8);
296 wb[3] = (u8)adr;
c5c77ba1
JK
297 len = 5;
298 break;
299
300 case CMD_INTERNAL_READ: /* internal register read */
51e825f7 301 wb[1] = (u8)(adr >> 8);
c5c77ba1 302 if (clockless == 1)
ffda203c 303 wb[1] |= BIT(7);
51e825f7 304 wb[2] = (u8)adr;
c5c77ba1
JK
305 wb[3] = 0x00;
306 len = 5;
307 break;
308
309 case CMD_TERMINATE: /* termination */
310 wb[1] = 0x00;
311 wb[2] = 0x00;
312 wb[3] = 0x00;
313 len = 5;
314 break;
315
316 case CMD_REPEAT: /* repeat */
317 wb[1] = 0x00;
318 wb[2] = 0x00;
319 wb[3] = 0x00;
320 len = 5;
321 break;
322
323 case CMD_RESET: /* reset */
324 wb[1] = 0xff;
325 wb[2] = 0xff;
326 wb[3] = 0xff;
327 len = 5;
328 break;
329
330 case CMD_DMA_WRITE: /* dma write */
331 case CMD_DMA_READ: /* dma read */
51e825f7
CL
332 wb[1] = (u8)(adr >> 16);
333 wb[2] = (u8)(adr >> 8);
334 wb[3] = (u8)adr;
335 wb[4] = (u8)(sz >> 8);
336 wb[5] = (u8)(sz);
c5c77ba1
JK
337 len = 7;
338 break;
339
340 case CMD_DMA_EXT_WRITE: /* dma extended write */
341 case CMD_DMA_EXT_READ: /* dma extended read */
51e825f7
CL
342 wb[1] = (u8)(adr >> 16);
343 wb[2] = (u8)(adr >> 8);
344 wb[3] = (u8)adr;
345 wb[4] = (u8)(sz >> 16);
346 wb[5] = (u8)(sz >> 8);
347 wb[6] = (u8)(sz);
c5c77ba1
JK
348 len = 8;
349 break;
350
351 case CMD_INTERNAL_WRITE: /* internal register write */
51e825f7 352 wb[1] = (u8)(adr >> 8);
c5c77ba1 353 if (clockless == 1)
ffda203c 354 wb[1] |= BIT(7);
51e825f7 355 wb[2] = (u8)(adr);
c5c77ba1
JK
356 wb[3] = b[3];
357 wb[4] = b[2];
358 wb[5] = b[1];
359 wb[6] = b[0];
360 len = 8;
361 break;
362
363 case CMD_SINGLE_WRITE: /* single word write */
51e825f7
CL
364 wb[1] = (u8)(adr >> 16);
365 wb[2] = (u8)(adr >> 8);
366 wb[3] = (u8)(adr);
c5c77ba1
JK
367 wb[4] = b[3];
368 wb[5] = b[2];
369 wb[6] = b[1];
370 wb[7] = b[0];
371 len = 9;
372 break;
373
374 default:
375 result = N_FAIL;
376 break;
377 }
378
e0a30008 379 if (result != N_OK)
c5c77ba1 380 return result;
c5c77ba1 381
78174ada 382 if (!g_spi.crc_off)
51e825f7 383 wb[len - 1] = (crc7(0x7f, (const u8 *)&wb[0], len - 1)) << 1;
78174ada 384 else
c5c77ba1 385 len -= 1;
c5c77ba1
JK
386
387#define NUM_SKIP_BYTES (1)
388#define NUM_RSP_BYTES (2)
389#define NUM_DATA_HDR_BYTES (1)
390#define NUM_DATA_BYTES (4)
391#define NUM_CRC_BYTES (2)
392#define NUM_DUMMY_BYTES (3)
393 if ((cmd == CMD_RESET) ||
394 (cmd == CMD_TERMINATE) ||
395 (cmd == CMD_REPEAT)) {
396 len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
397 } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
398 if (!g_spi.crc_off) {
399 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
400 + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
401 } else {
402 len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
403 + NUM_DUMMY_BYTES);
404 }
405 } else {
406 len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
407 }
408#undef NUM_DUMMY_BYTES
409
5cc59d29 410 if (len2 > ARRAY_SIZE(wb)) {
ac1da162 411 dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n",
5cc59d29 412 len2, ARRAY_SIZE(wb));
c5c77ba1
JK
413 result = N_FAIL;
414 return result;
415 }
416 /* zero spi write buffers. */
e0a30008 417 for (wix = len; wix < len2; wix++)
c5c77ba1 418 wb[wix] = 0;
c5c77ba1
JK
419 rix = len;
420
d4312b6f 421 if (wilc_spi_tx_rx(wilc, wb, rb, len2)) {
ac1da162 422 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
c5c77ba1
JK
423 result = N_FAIL;
424 return result;
425 }
426
c5c77ba1
JK
427 /**
428 * Command/Control response
429 **/
430 if ((cmd == CMD_RESET) ||
431 (cmd == CMD_TERMINATE) ||
432 (cmd == CMD_REPEAT)) {
433 rix++; /* skip 1 byte */
434 }
435
436 /* do { */
437 rsp = rb[rix++];
438 /* if(rsp == cmd) break; */
439 /* } while(&rptr[1] <= &rb[len2]); */
440
441 if (rsp != cmd) {
8779bf84
AJ
442 dev_err(&spi->dev,
443 "Failed cmd response, cmd (%02x), resp (%02x)\n",
444 cmd, rsp);
c5c77ba1
JK
445 result = N_FAIL;
446 return result;
447 }
448
449 /**
450 * State response
451 **/
452 rsp = rb[rix++];
453 if (rsp != 0x00) {
ac1da162
GL
454 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
455 rsp);
c5c77ba1
JK
456 result = N_FAIL;
457 return result;
458 }
459
460 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
461 || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
462 int retry;
ec53adfe 463 /* u16 crc1, crc2; */
51e825f7 464 u8 crc[2];
c5c77ba1
JK
465 /**
466 * Data Respnose header
467 **/
468 retry = 100;
469 do {
470 /* ensure there is room in buffer later to read data and crc */
471 if (rix < len2) {
472 rsp = rb[rix++];
473 } else {
474 retry = 0;
475 break;
476 }
477 if (((rsp >> 4) & 0xf) == 0xf)
478 break;
479 } while (retry--);
480
481 if (retry <= 0) {
ac1da162
GL
482 dev_err(&spi->dev,
483 "Error, data read response (%02x)\n", rsp);
c5c77ba1
JK
484 result = N_RESET;
485 return result;
486 }
487
488 if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
489 /**
490 * Read bytes
491 **/
492 if ((rix + 3) < len2) {
493 b[0] = rb[rix++];
494 b[1] = rb[rix++];
495 b[2] = rb[rix++];
496 b[3] = rb[rix++];
497 } else {
ac1da162
GL
498 dev_err(&spi->dev,
499 "buffer overrun when reading data.\n");
c5c77ba1
JK
500 result = N_FAIL;
501 return result;
502 }
503
504 if (!g_spi.crc_off) {
505 /**
506 * Read Crc
507 **/
508 if ((rix + 1) < len2) {
509 crc[0] = rb[rix++];
510 crc[1] = rb[rix++];
511 } else {
5142a14e 512 dev_err(&spi->dev, "buffer overrun when reading crc.\n");
c5c77ba1
JK
513 result = N_FAIL;
514 return result;
515 }
516 }
517 } else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
518 int ix;
519
520 /* some data may be read in response to dummy bytes. */
e0a30008 521 for (ix = 0; (rix < len2) && (ix < sz); )
c5c77ba1 522 b[ix++] = rb[rix++];
61500fbd 523
c5c77ba1
JK
524 sz -= ix;
525
526 if (sz > 0) {
527 int nbytes;
528
78174ada 529 if (sz <= (DATA_PKT_SZ - ix))
c5c77ba1 530 nbytes = sz;
78174ada 531 else
c5c77ba1 532 nbytes = DATA_PKT_SZ - ix;
c5c77ba1
JK
533
534 /**
535 * Read bytes
536 **/
d4312b6f 537 if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
ac1da162 538 dev_err(&spi->dev, "Failed data block read, bus error...\n");
c5c77ba1
JK
539 result = N_FAIL;
540 goto _error_;
541 }
542
543 /**
544 * Read Crc
545 **/
546 if (!g_spi.crc_off) {
d4312b6f 547 if (wilc_spi_rx(wilc, crc, 2)) {
ac1da162 548 dev_err(&spi->dev, "Failed data block crc read, bus error...\n");
c5c77ba1
JK
549 result = N_FAIL;
550 goto _error_;
551 }
552 }
553
554
555 ix += nbytes;
556 sz -= nbytes;
557 }
558
559 /* if any data in left unread, then read the rest using normal DMA code.*/
560 while (sz > 0) {
561 int nbytes;
562
78174ada 563 if (sz <= DATA_PKT_SZ)
c5c77ba1 564 nbytes = sz;
78174ada 565 else
c5c77ba1 566 nbytes = DATA_PKT_SZ;
c5c77ba1
JK
567
568 /**
569 * read data response only on the next DMA cycles not
570 * the first DMA since data response header is already
571 * handled above for the first DMA.
572 **/
573 /**
574 * Data Respnose header
575 **/
576 retry = 10;
577 do {
d4312b6f 578 if (wilc_spi_rx(wilc, &rsp, 1)) {
ac1da162 579 dev_err(&spi->dev, "Failed data response read, bus error...\n");
c5c77ba1
JK
580 result = N_FAIL;
581 break;
582 }
583 if (((rsp >> 4) & 0xf) == 0xf)
584 break;
585 } while (retry--);
586
587 if (result == N_FAIL)
588 break;
589
590
591 /**
592 * Read bytes
593 **/
d4312b6f 594 if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
ac1da162 595 dev_err(&spi->dev, "Failed data block read, bus error...\n");
c5c77ba1
JK
596 result = N_FAIL;
597 break;
598 }
599
600 /**
601 * Read Crc
602 **/
603 if (!g_spi.crc_off) {
d4312b6f 604 if (wilc_spi_rx(wilc, crc, 2)) {
ac1da162 605 dev_err(&spi->dev, "Failed data block crc read, bus error...\n");
c5c77ba1
JK
606 result = N_FAIL;
607 break;
608 }
609 }
610
611 ix += nbytes;
612 sz -= nbytes;
613 }
614 }
615 }
616_error_:
617 return result;
618}
619
49dcd0dd 620static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
c5c77ba1 621{
ac1da162 622 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1
JK
623 int ix, nbytes;
624 int result = 1;
51e825f7
CL
625 u8 cmd, order, crc[2] = {0};
626 /* u8 rsp; */
c5c77ba1
JK
627
628 /**
629 * Data
630 **/
631 ix = 0;
632 do {
633 if (sz <= DATA_PKT_SZ)
634 nbytes = sz;
635 else
636 nbytes = DATA_PKT_SZ;
637
638 /**
639 * Write command
640 **/
641 cmd = 0xf0;
642 if (ix == 0) {
643 if (sz <= DATA_PKT_SZ)
644
645 order = 0x3;
646 else
647 order = 0x1;
648 } else {
649 if (sz <= DATA_PKT_SZ)
650 order = 0x3;
651 else
652 order = 0x2;
653 }
654 cmd |= order;
d4312b6f 655 if (wilc_spi_tx(wilc, &cmd, 1)) {
ac1da162
GL
656 dev_err(&spi->dev,
657 "Failed data block cmd write, bus error...\n");
c5c77ba1
JK
658 result = N_FAIL;
659 break;
660 }
661
662 /**
663 * Write data
664 **/
d4312b6f 665 if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
ac1da162
GL
666 dev_err(&spi->dev,
667 "Failed data block write, bus error...\n");
c5c77ba1
JK
668 result = N_FAIL;
669 break;
670 }
671
672 /**
673 * Write Crc
674 **/
675 if (!g_spi.crc_off) {
d4312b6f 676 if (wilc_spi_tx(wilc, crc, 2)) {
5142a14e 677 dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
c5c77ba1
JK
678 result = N_FAIL;
679 break;
680 }
681 }
682
683 /**
684 * No need to wait for response
685 **/
c5c77ba1
JK
686 ix += nbytes;
687 sz -= nbytes;
688 } while (sz);
689
690
691 return result;
692}
693
694/********************************************
695 *
696 * Spi Internal Read/Write Function
697 *
698 ********************************************/
699
49dcd0dd 700static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
c5c77ba1 701{
ac1da162 702 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1
JK
703 int result;
704
9e6627ac 705 dat = cpu_to_le32(dat);
49dcd0dd
GL
706 result = spi_cmd_complete(wilc, CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4,
707 0);
e0a30008 708 if (result != N_OK)
ac1da162 709 dev_err(&spi->dev, "Failed internal write cmd...\n");
c5c77ba1 710
c5c77ba1
JK
711 return result;
712}
713
49dcd0dd 714static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
c5c77ba1 715{
ac1da162 716 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1
JK
717 int result;
718
49dcd0dd
GL
719 result = spi_cmd_complete(wilc, CMD_INTERNAL_READ, adr, (u8 *)data, 4,
720 0);
c5c77ba1 721 if (result != N_OK) {
ac1da162 722 dev_err(&spi->dev, "Failed internal read cmd...\n");
c5c77ba1
JK
723 return 0;
724 }
c5c77ba1 725
9e6627ac 726 *data = cpu_to_le32(*data);
c5c77ba1
JK
727
728 return 1;
729}
730
731/********************************************
732 *
733 * Spi interfaces
734 *
735 ********************************************/
736
49dcd0dd 737static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
c5c77ba1 738{
ac1da162 739 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1 740 int result = N_OK;
51e825f7
CL
741 u8 cmd = CMD_SINGLE_WRITE;
742 u8 clockless = 0;
c5c77ba1 743
9e6627ac 744 data = cpu_to_le32(data);
c5c77ba1
JK
745 if (addr < 0x30) {
746 /* Clockless register*/
747 cmd = CMD_INTERNAL_WRITE;
748 clockless = 1;
749 }
750
49dcd0dd 751 result = spi_cmd_complete(wilc, cmd, addr, (u8 *)&data, 4, clockless);
e0a30008 752 if (result != N_OK)
ac1da162 753 dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
c5c77ba1
JK
754
755 return result;
c5c77ba1
JK
756}
757
d4312b6f 758static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
c5c77ba1 759{
ac1da162 760 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1 761 int result;
51e825f7 762 u8 cmd = CMD_DMA_EXT_WRITE;
c5c77ba1
JK
763
764 /**
765 * has to be greated than 4
766 **/
767 if (size <= 4)
768 return 0;
769
49dcd0dd 770 result = spi_cmd_complete(wilc, cmd, addr, NULL, size, 0);
c5c77ba1 771 if (result != N_OK) {
ac1da162
GL
772 dev_err(&spi->dev,
773 "Failed cmd, write block (%08x)...\n", addr);
c5c77ba1
JK
774 return 0;
775 }
c5c77ba1
JK
776
777 /**
778 * Data
779 **/
49dcd0dd 780 result = spi_data_write(wilc, buf, size);
e0a30008 781 if (result != N_OK)
ac1da162 782 dev_err(&spi->dev, "Failed block data write...\n");
c5c77ba1
JK
783
784 return 1;
785}
786
49dcd0dd 787static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
c5c77ba1 788{
ac1da162 789 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1 790 int result = N_OK;
51e825f7
CL
791 u8 cmd = CMD_SINGLE_READ;
792 u8 clockless = 0;
c5c77ba1 793
c5c77ba1 794 if (addr < 0x30) {
ac1da162 795 /* dev_err(&spi->dev, "***** read addr %d\n\n", addr); */
c5c77ba1
JK
796 /* Clockless register*/
797 cmd = CMD_INTERNAL_READ;
798 clockless = 1;
799 }
800
49dcd0dd 801 result = spi_cmd_complete(wilc, cmd, addr, (u8 *)data, 4, clockless);
c5c77ba1 802 if (result != N_OK) {
ac1da162 803 dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
c5c77ba1
JK
804 return 0;
805 }
c5c77ba1 806
9e6627ac 807 *data = cpu_to_le32(*data);
c5c77ba1
JK
808
809 return 1;
810}
811
d4312b6f 812static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
c5c77ba1 813{
ac1da162 814 struct spi_device *spi = to_spi_device(wilc->dev);
51e825f7 815 u8 cmd = CMD_DMA_EXT_READ;
c5c77ba1
JK
816 int result;
817
818 if (size <= 4)
819 return 0;
820
49dcd0dd 821 result = spi_cmd_complete(wilc, cmd, addr, buf, size, 0);
c5c77ba1 822 if (result != N_OK) {
ac1da162 823 dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
c5c77ba1
JK
824 return 0;
825 }
c5c77ba1
JK
826
827 return 1;
828}
829
830/********************************************
831 *
832 * Bus interfaces
833 *
834 ********************************************/
835
49dcd0dd 836static int _wilc_spi_deinit(struct wilc *wilc)
c5c77ba1
JK
837{
838 /**
839 * TODO:
840 **/
841 return 1;
842}
843
5397cbc2 844static int wilc_spi_init(struct wilc *wilc, bool resume)
c5c77ba1 845{
ac1da162 846 struct spi_device *spi = to_spi_device(wilc->dev);
fbc2fe16
CL
847 u32 reg;
848 u32 chipid;
c5c77ba1
JK
849
850 static int isinit;
851
852 if (isinit) {
853
49dcd0dd 854 if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
ac1da162 855 dev_err(&spi->dev, "Fail cmd read chip id...\n");
c5c77ba1
JK
856 return 0;
857 }
858 return 1;
859 }
860
6a707a9e 861 memset(&g_spi, 0, sizeof(struct wilc_spi));
c5c77ba1 862
c5c77ba1
JK
863 /**
864 * configure protocol
865 **/
866 g_spi.crc_off = 0;
867
868 /* TODO: We can remove the CRC trials if there is a definite way to reset */
869 /* the SPI to it's initial value. */
49dcd0dd 870 if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
c5c77ba1
JK
871 /* Read failed. Try with CRC off. This might happen when module
872 * is removed but chip isn't reset*/
873 g_spi.crc_off = 1;
2218b8fc 874 dev_err(&spi->dev, "Failed internal read protocol with CRC on, retrying with CRC off...\n");
49dcd0dd 875 if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
c5c77ba1 876 /* Reaad failed with both CRC on and off, something went bad */
ac1da162
GL
877 dev_err(&spi->dev,
878 "Failed internal read protocol...\n");
c5c77ba1
JK
879 return 0;
880 }
881 }
882 if (g_spi.crc_off == 0) {
883 reg &= ~0xc; /* disable crc checking */
884 reg &= ~0x70;
885 reg |= (0x5 << 4);
49dcd0dd 886 if (!spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg)) {
ac1da162 887 dev_err(&spi->dev, "[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__);
c5c77ba1
JK
888 return 0;
889 }
890 g_spi.crc_off = 1;
891 }
892
893
894 /**
895 * make sure can read back chip id correctly
896 **/
49dcd0dd 897 if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
ac1da162 898 dev_err(&spi->dev, "Fail cmd read chip id...\n");
c5c77ba1
JK
899 return 0;
900 }
ac1da162 901 /* dev_err(&spi->dev, "chipid (%08x)\n", chipid); */
c5c77ba1
JK
902
903 g_spi.has_thrpt_enh = 1;
904
905 isinit = 1;
906
907 return 1;
908}
909
49dcd0dd 910static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
c5c77ba1 911{
ac1da162 912 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1 913 int ret;
8dfaafd6 914
c5c77ba1 915 if (g_spi.has_thrpt_enh) {
49dcd0dd
GL
916 ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
917 size);
c5c77ba1
JK
918 *size = *size & IRQ_DMA_WD_CNT_MASK;
919 } else {
fbc2fe16
CL
920 u32 tmp;
921 u32 byte_cnt;
c5c77ba1 922
49dcd0dd
GL
923 ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE,
924 &byte_cnt);
c5c77ba1 925 if (!ret) {
ac1da162
GL
926 dev_err(&spi->dev,
927 "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
c5c77ba1
JK
928 goto _fail_;
929 }
930 tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
931 *size = tmp;
932 }
933
934
935
936_fail_:
937 return ret;
938}
939
940
941
49dcd0dd 942static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
c5c77ba1 943{
ac1da162 944 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1 945 int ret;
8dfaafd6 946
c5c77ba1 947 if (g_spi.has_thrpt_enh) {
49dcd0dd
GL
948 ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
949 int_status);
c5c77ba1 950 } else {
fbc2fe16
CL
951 u32 tmp;
952 u32 byte_cnt;
c5c77ba1 953
49dcd0dd
GL
954 ret = wilc_spi_read_reg(wilc, WILC_VMM_TO_HOST_SIZE,
955 &byte_cnt);
c5c77ba1 956 if (!ret) {
ac1da162
GL
957 dev_err(&spi->dev,
958 "Failed read WILC_VMM_TO_HOST_SIZE ...\n");
c5c77ba1
JK
959 goto _fail_;
960 }
961 tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
962
963 {
964 int happended, j;
965
966 j = 0;
967 do {
fbc2fe16 968 u32 irq_flags;
c5c77ba1
JK
969
970 happended = 0;
971
49dcd0dd 972 wilc_spi_read_reg(wilc, 0x1a90, &irq_flags);
c5c77ba1
JK
973 tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
974
975 if (g_spi.nint > 5) {
49dcd0dd
GL
976 wilc_spi_read_reg(wilc, 0x1a94,
977 &irq_flags);
c5c77ba1
JK
978 tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5));
979 }
980
981 {
fbc2fe16 982 u32 unkmown_mask;
c5c77ba1
JK
983
984 unkmown_mask = ~((1ul << g_spi.nint) - 1);
985
986 if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
ac1da162 987 dev_err(&spi->dev, "Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
c5c77ba1
JK
988 happended = 1;
989 }
990 }
991 j++;
992 } while (happended);
993 }
994
995 *int_status = tmp;
996
997 }
998
999_fail_:
1000 return ret;
1001}
1002
49dcd0dd 1003static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
c5c77ba1 1004{
ac1da162 1005 struct spi_device *spi = to_spi_device(wilc->dev);
c5c77ba1
JK
1006 int ret;
1007
1008 if (g_spi.has_thrpt_enh) {
49dcd0dd
GL
1009 ret = spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE,
1010 val);
c5c77ba1 1011 } else {
fbc2fe16 1012 u32 flags;
8dfaafd6 1013
ffda203c 1014 flags = val & (BIT(MAX_NUM_INT) - 1);
c5c77ba1
JK
1015 if (flags) {
1016 int i;
1017
1018 ret = 1;
1019 for (i = 0; i < g_spi.nint; i++) {
1020 /* No matter what you write 1 or 0, it will clear interrupt. */
1021 if (flags & 1)
49dcd0dd 1022 ret = wilc_spi_write_reg(wilc, 0x10c8 + i * 4, 1);
c5c77ba1
JK
1023 if (!ret)
1024 break;
1025 flags >>= 1;
1026 }
1027 if (!ret) {
ac1da162
GL
1028 dev_err(&spi->dev,
1029 "Failed wilc_spi_write_reg, set reg %x ...\n",
1030 0x10c8 + i * 4);
c5c77ba1
JK
1031 goto _fail_;
1032 }
1033 for (i = g_spi.nint; i < MAX_NUM_INT; i++) {
1034 if (flags & 1)
ac1da162
GL
1035 dev_err(&spi->dev,
1036 "Unexpected interrupt cleared %d...\n",
1037 i);
c5c77ba1
JK
1038 flags >>= 1;
1039 }
1040 }
1041
1042 {
fbc2fe16 1043 u32 tbl_ctl;
c5c77ba1
JK
1044
1045 tbl_ctl = 0;
1046 /* select VMM table 0 */
1047 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
ffda203c 1048 tbl_ctl |= BIT(0);
c5c77ba1
JK
1049 /* select VMM table 1 */
1050 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
ffda203c 1051 tbl_ctl |= BIT(1);
c5c77ba1 1052
49dcd0dd
GL
1053 ret = wilc_spi_write_reg(wilc, WILC_VMM_TBL_CTL,
1054 tbl_ctl);
c5c77ba1 1055 if (!ret) {
ac1da162
GL
1056 dev_err(&spi->dev,
1057 "fail write reg vmm_tbl_ctl...\n");
c5c77ba1
JK
1058 goto _fail_;
1059 }
1060
1061 if ((val & EN_VMM) == EN_VMM) {
1062 /**
1063 * enable vmm transfer.
1064 **/
49dcd0dd
GL
1065 ret = wilc_spi_write_reg(wilc,
1066 WILC_VMM_CORE_CTL, 1);
c5c77ba1 1067 if (!ret) {
5142a14e 1068 dev_err(&spi->dev, "fail write reg vmm_core_ctl...\n");
c5c77ba1
JK
1069 goto _fail_;
1070 }
1071 }
1072 }
1073 }
1074_fail_:
1075 return ret;
1076}
1077
49dcd0dd 1078static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
c5c77ba1 1079{
ac1da162 1080 struct spi_device *spi = to_spi_device(wilc->dev);
fbc2fe16 1081 u32 reg;
c5c77ba1
JK
1082 int ret, i;
1083
1084 if (nint > MAX_NUM_INT) {
95b8cb89 1085 dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
c5c77ba1
JK
1086 return 0;
1087 }
1088
1089 g_spi.nint = nint;
1090
1091 /**
1092 * interrupt pin mux select
1093 **/
49dcd0dd 1094 ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, &reg);
c5c77ba1 1095 if (!ret) {
ac1da162
GL
1096 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1097 WILC_PIN_MUX_0);
c5c77ba1
JK
1098 return 0;
1099 }
ffda203c 1100 reg |= BIT(8);
49dcd0dd 1101 ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
c5c77ba1 1102 if (!ret) {
ac1da162
GL
1103 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1104 WILC_PIN_MUX_0);
c5c77ba1
JK
1105 return 0;
1106 }
1107
1108 /**
1109 * interrupt enable
1110 **/
49dcd0dd 1111 ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, &reg);
c5c77ba1 1112 if (!ret) {
ac1da162
GL
1113 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1114 WILC_INTR_ENABLE);
c5c77ba1
JK
1115 return 0;
1116 }
1117
e0a30008 1118 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
ffda203c 1119 reg |= (BIT((27 + i)));
e0a30008 1120
49dcd0dd 1121 ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
c5c77ba1 1122 if (!ret) {
ac1da162
GL
1123 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1124 WILC_INTR_ENABLE);
c5c77ba1
JK
1125 return 0;
1126 }
1127 if (nint) {
49dcd0dd 1128 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
c5c77ba1 1129 if (!ret) {
ac1da162
GL
1130 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1131 WILC_INTR2_ENABLE);
c5c77ba1
JK
1132 return 0;
1133 }
1134
e0a30008 1135 for (i = 0; (i < 3) && (nint > 0); i++, nint--)
ffda203c 1136 reg |= BIT(i);
c5c77ba1 1137
49dcd0dd 1138 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
c5c77ba1 1139 if (!ret) {
ac1da162
GL
1140 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1141 WILC_INTR2_ENABLE);
c5c77ba1
JK
1142 return 0;
1143 }
1144 }
1145
1146 return 1;
1147}
1148/********************************************
1149 *
1150 * Global spi HIF function table
1151 *
1152 ********************************************/
7d37a4a1 1153const struct wilc_hif_func wilc_hif_spi = {
2769d942 1154 .hif_init = wilc_spi_init,
7d37a4a1
AB
1155 .hif_deinit = _wilc_spi_deinit,
1156 .hif_read_reg = wilc_spi_read_reg,
1157 .hif_write_reg = wilc_spi_write_reg,
d4312b6f
GL
1158 .hif_block_rx = wilc_spi_read,
1159 .hif_block_tx = wilc_spi_write,
7d37a4a1
AB
1160 .hif_read_int = wilc_spi_read_int,
1161 .hif_clear_int_ext = wilc_spi_clear_int_ext,
1162 .hif_read_size = wilc_spi_read_size,
d4312b6f
GL
1163 .hif_block_tx_ext = wilc_spi_write,
1164 .hif_block_rx_ext = wilc_spi_read,
7d37a4a1 1165 .hif_sync_ext = wilc_spi_sync_ext,
c5c77ba1 1166};
This page took 0.266893 seconds and 5 git commands to generate.