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