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