Loading...
Note: File does not exist in v3.1.
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
4 * All rights reserved.
5 */
6
7#include <linux/clk.h>
8#include <linux/spi/spi.h>
9#include <linux/crc7.h>
10
11#include "netdev.h"
12#include "cfg80211.h"
13
14struct wilc_spi {
15 int crc_off;
16};
17
18static const struct wilc_hif_func wilc_hif_spi;
19
20/********************************************
21 *
22 * Spi protocol Function
23 *
24 ********************************************/
25
26#define CMD_DMA_WRITE 0xc1
27#define CMD_DMA_READ 0xc2
28#define CMD_INTERNAL_WRITE 0xc3
29#define CMD_INTERNAL_READ 0xc4
30#define CMD_TERMINATE 0xc5
31#define CMD_REPEAT 0xc6
32#define CMD_DMA_EXT_WRITE 0xc7
33#define CMD_DMA_EXT_READ 0xc8
34#define CMD_SINGLE_WRITE 0xc9
35#define CMD_SINGLE_READ 0xca
36#define CMD_RESET 0xcf
37
38#define DATA_PKT_SZ_256 256
39#define DATA_PKT_SZ_512 512
40#define DATA_PKT_SZ_1K 1024
41#define DATA_PKT_SZ_4K (4 * 1024)
42#define DATA_PKT_SZ_8K (8 * 1024)
43#define DATA_PKT_SZ DATA_PKT_SZ_8K
44
45#define USE_SPI_DMA 0
46
47#define WILC_SPI_COMMAND_STAT_SUCCESS 0
48#define WILC_GET_RESP_HDR_START(h) (((h) >> 4) & 0xf)
49
50struct wilc_spi_cmd {
51 u8 cmd_type;
52 union {
53 struct {
54 u8 addr[3];
55 u8 crc[];
56 } __packed simple_cmd;
57 struct {
58 u8 addr[3];
59 u8 size[2];
60 u8 crc[];
61 } __packed dma_cmd;
62 struct {
63 u8 addr[3];
64 u8 size[3];
65 u8 crc[];
66 } __packed dma_cmd_ext;
67 struct {
68 u8 addr[2];
69 __be32 data;
70 u8 crc[];
71 } __packed internal_w_cmd;
72 struct {
73 u8 addr[3];
74 __be32 data;
75 u8 crc[];
76 } __packed w_cmd;
77 } u;
78} __packed;
79
80struct wilc_spi_read_rsp_data {
81 u8 rsp_cmd_type;
82 u8 status;
83 u8 resp_header;
84 u8 resp_data[4];
85 u8 crc[];
86} __packed;
87
88struct wilc_spi_rsp_data {
89 u8 rsp_cmd_type;
90 u8 status;
91} __packed;
92
93static int wilc_bus_probe(struct spi_device *spi)
94{
95 int ret;
96 struct wilc *wilc;
97 struct wilc_spi *spi_priv;
98
99 spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);
100 if (!spi_priv)
101 return -ENOMEM;
102
103 ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
104 if (ret) {
105 kfree(spi_priv);
106 return ret;
107 }
108
109 spi_set_drvdata(spi, wilc);
110 wilc->dev = &spi->dev;
111 wilc->bus_data = spi_priv;
112 wilc->dev_irq_num = spi->irq;
113
114 wilc->rtc_clk = devm_clk_get(&spi->dev, "rtc_clk");
115 if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
116 return -EPROBE_DEFER;
117 else if (!IS_ERR(wilc->rtc_clk))
118 clk_prepare_enable(wilc->rtc_clk);
119
120 return 0;
121}
122
123static int wilc_bus_remove(struct spi_device *spi)
124{
125 struct wilc *wilc = spi_get_drvdata(spi);
126
127 if (!IS_ERR(wilc->rtc_clk))
128 clk_disable_unprepare(wilc->rtc_clk);
129
130 wilc_netdev_cleanup(wilc);
131 return 0;
132}
133
134static const struct of_device_id wilc_of_match[] = {
135 { .compatible = "microchip,wilc1000", },
136 { /* sentinel */ }
137};
138MODULE_DEVICE_TABLE(of, wilc_of_match);
139
140static struct spi_driver wilc_spi_driver = {
141 .driver = {
142 .name = MODALIAS,
143 .of_match_table = wilc_of_match,
144 },
145 .probe = wilc_bus_probe,
146 .remove = wilc_bus_remove,
147};
148module_spi_driver(wilc_spi_driver);
149MODULE_LICENSE("GPL");
150
151static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
152{
153 struct spi_device *spi = to_spi_device(wilc->dev);
154 int ret;
155 struct spi_message msg;
156
157 if (len > 0 && b) {
158 struct spi_transfer tr = {
159 .tx_buf = b,
160 .len = len,
161 .delay = {
162 .value = 0,
163 .unit = SPI_DELAY_UNIT_USECS
164 },
165 };
166 char *r_buffer = kzalloc(len, GFP_KERNEL);
167
168 if (!r_buffer)
169 return -ENOMEM;
170
171 tr.rx_buf = r_buffer;
172 dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
173
174 memset(&msg, 0, sizeof(msg));
175 spi_message_init(&msg);
176 msg.spi = spi;
177 msg.is_dma_mapped = USE_SPI_DMA;
178 spi_message_add_tail(&tr, &msg);
179
180 ret = spi_sync(spi, &msg);
181 if (ret < 0)
182 dev_err(&spi->dev, "SPI transaction failed\n");
183
184 kfree(r_buffer);
185 } else {
186 dev_err(&spi->dev,
187 "can't write data with the following length: %d\n",
188 len);
189 ret = -EINVAL;
190 }
191
192 return ret;
193}
194
195static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
196{
197 struct spi_device *spi = to_spi_device(wilc->dev);
198 int ret;
199
200 if (rlen > 0) {
201 struct spi_message msg;
202 struct spi_transfer tr = {
203 .rx_buf = rb,
204 .len = rlen,
205 .delay = {
206 .value = 0,
207 .unit = SPI_DELAY_UNIT_USECS
208 },
209
210 };
211 char *t_buffer = kzalloc(rlen, GFP_KERNEL);
212
213 if (!t_buffer)
214 return -ENOMEM;
215
216 tr.tx_buf = t_buffer;
217
218 memset(&msg, 0, sizeof(msg));
219 spi_message_init(&msg);
220 msg.spi = spi;
221 msg.is_dma_mapped = USE_SPI_DMA;
222 spi_message_add_tail(&tr, &msg);
223
224 ret = spi_sync(spi, &msg);
225 if (ret < 0)
226 dev_err(&spi->dev, "SPI transaction failed\n");
227 kfree(t_buffer);
228 } else {
229 dev_err(&spi->dev,
230 "can't read data with the following length: %u\n",
231 rlen);
232 ret = -EINVAL;
233 }
234
235 return ret;
236}
237
238static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
239{
240 struct spi_device *spi = to_spi_device(wilc->dev);
241 int ret;
242
243 if (rlen > 0) {
244 struct spi_message msg;
245 struct spi_transfer tr = {
246 .rx_buf = rb,
247 .tx_buf = wb,
248 .len = rlen,
249 .bits_per_word = 8,
250 .delay = {
251 .value = 0,
252 .unit = SPI_DELAY_UNIT_USECS
253 },
254
255 };
256
257 memset(&msg, 0, sizeof(msg));
258 spi_message_init(&msg);
259 msg.spi = spi;
260 msg.is_dma_mapped = USE_SPI_DMA;
261
262 spi_message_add_tail(&tr, &msg);
263 ret = spi_sync(spi, &msg);
264 if (ret < 0)
265 dev_err(&spi->dev, "SPI transaction failed\n");
266 } else {
267 dev_err(&spi->dev,
268 "can't read data with the following length: %u\n",
269 rlen);
270 ret = -EINVAL;
271 }
272
273 return ret;
274}
275
276static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
277{
278 struct spi_device *spi = to_spi_device(wilc->dev);
279 struct wilc_spi *spi_priv = wilc->bus_data;
280 int ix, nbytes;
281 int result = 0;
282 u8 cmd, order, crc[2] = {0};
283
284 /*
285 * Data
286 */
287 ix = 0;
288 do {
289 if (sz <= DATA_PKT_SZ) {
290 nbytes = sz;
291 order = 0x3;
292 } else {
293 nbytes = DATA_PKT_SZ;
294 if (ix == 0)
295 order = 0x1;
296 else
297 order = 0x02;
298 }
299
300 /*
301 * Write command
302 */
303 cmd = 0xf0;
304 cmd |= order;
305
306 if (wilc_spi_tx(wilc, &cmd, 1)) {
307 dev_err(&spi->dev,
308 "Failed data block cmd write, bus error...\n");
309 result = -EINVAL;
310 break;
311 }
312
313 /*
314 * Write data
315 */
316 if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
317 dev_err(&spi->dev,
318 "Failed data block write, bus error...\n");
319 result = -EINVAL;
320 break;
321 }
322
323 /*
324 * Write Crc
325 */
326 if (!spi_priv->crc_off) {
327 if (wilc_spi_tx(wilc, crc, 2)) {
328 dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
329 result = -EINVAL;
330 break;
331 }
332 }
333
334 /*
335 * No need to wait for response
336 */
337 ix += nbytes;
338 sz -= nbytes;
339 } while (sz);
340
341 return result;
342}
343
344/********************************************
345 *
346 * Spi Internal Read/Write Function
347 *
348 ********************************************/
349static u8 wilc_get_crc7(u8 *buffer, u32 len)
350{
351 return crc7_be(0xfe, buffer, len);
352}
353
354static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
355 u8 clockless)
356{
357 struct spi_device *spi = to_spi_device(wilc->dev);
358 struct wilc_spi *spi_priv = wilc->bus_data;
359 u8 wb[32], rb[32];
360 int cmd_len, resp_len;
361 u8 crc[2];
362 struct wilc_spi_cmd *c;
363 struct wilc_spi_read_rsp_data *r;
364
365 memset(wb, 0x0, sizeof(wb));
366 memset(rb, 0x0, sizeof(rb));
367 c = (struct wilc_spi_cmd *)wb;
368 c->cmd_type = cmd;
369 if (cmd == CMD_SINGLE_READ) {
370 c->u.simple_cmd.addr[0] = adr >> 16;
371 c->u.simple_cmd.addr[1] = adr >> 8;
372 c->u.simple_cmd.addr[2] = adr;
373 } else if (cmd == CMD_INTERNAL_READ) {
374 c->u.simple_cmd.addr[0] = adr >> 8;
375 if (clockless == 1)
376 c->u.simple_cmd.addr[0] |= BIT(7);
377 c->u.simple_cmd.addr[1] = adr;
378 c->u.simple_cmd.addr[2] = 0x0;
379 } else {
380 dev_err(&spi->dev, "cmd [%x] not supported\n", cmd);
381 return -EINVAL;
382 }
383
384 cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
385 resp_len = sizeof(*r);
386 if (!spi_priv->crc_off) {
387 c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
388 cmd_len += 1;
389 resp_len += 2;
390 }
391
392 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
393 dev_err(&spi->dev,
394 "spi buffer size too small (%d) (%d) (%zu)\n",
395 cmd_len, resp_len, ARRAY_SIZE(wb));
396 return -EINVAL;
397 }
398
399 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
400 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
401 return -EINVAL;
402 }
403
404 r = (struct wilc_spi_read_rsp_data *)&rb[cmd_len];
405 if (r->rsp_cmd_type != cmd) {
406 dev_err(&spi->dev,
407 "Failed cmd response, cmd (%02x), resp (%02x)\n",
408 cmd, r->rsp_cmd_type);
409 return -EINVAL;
410 }
411
412 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
413 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
414 r->status);
415 return -EINVAL;
416 }
417
418 if (WILC_GET_RESP_HDR_START(r->resp_header) != 0xf) {
419 dev_err(&spi->dev, "Error, data read response (%02x)\n",
420 r->resp_header);
421 return -EINVAL;
422 }
423
424 if (b)
425 memcpy(b, r->resp_data, 4);
426
427 if (!spi_priv->crc_off)
428 memcpy(crc, r->crc, 2);
429
430 return 0;
431}
432
433static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,
434 u8 clockless)
435{
436 struct spi_device *spi = to_spi_device(wilc->dev);
437 struct wilc_spi *spi_priv = wilc->bus_data;
438 u8 wb[32], rb[32];
439 int cmd_len, resp_len;
440 struct wilc_spi_cmd *c;
441 struct wilc_spi_rsp_data *r;
442
443 memset(wb, 0x0, sizeof(wb));
444 memset(rb, 0x0, sizeof(rb));
445 c = (struct wilc_spi_cmd *)wb;
446 c->cmd_type = cmd;
447 if (cmd == CMD_INTERNAL_WRITE) {
448 c->u.internal_w_cmd.addr[0] = adr >> 8;
449 if (clockless == 1)
450 c->u.internal_w_cmd.addr[0] |= BIT(7);
451
452 c->u.internal_w_cmd.addr[1] = adr;
453 c->u.internal_w_cmd.data = cpu_to_be32(data);
454 cmd_len = offsetof(struct wilc_spi_cmd, u.internal_w_cmd.crc);
455 if (!spi_priv->crc_off)
456 c->u.internal_w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
457 } else if (cmd == CMD_SINGLE_WRITE) {
458 c->u.w_cmd.addr[0] = adr >> 16;
459 c->u.w_cmd.addr[1] = adr >> 8;
460 c->u.w_cmd.addr[2] = adr;
461 c->u.w_cmd.data = cpu_to_be32(data);
462 cmd_len = offsetof(struct wilc_spi_cmd, u.w_cmd.crc);
463 if (!spi_priv->crc_off)
464 c->u.w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
465 } else {
466 dev_err(&spi->dev, "write cmd [%x] not supported\n", cmd);
467 return -EINVAL;
468 }
469
470 if (!spi_priv->crc_off)
471 cmd_len += 1;
472
473 resp_len = sizeof(*r);
474
475 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
476 dev_err(&spi->dev,
477 "spi buffer size too small (%d) (%d) (%zu)\n",
478 cmd_len, resp_len, ARRAY_SIZE(wb));
479 return -EINVAL;
480 }
481
482 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
483 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
484 return -EINVAL;
485 }
486
487 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
488 if (r->rsp_cmd_type != cmd) {
489 dev_err(&spi->dev,
490 "Failed cmd response, cmd (%02x), resp (%02x)\n",
491 cmd, r->rsp_cmd_type);
492 return -EINVAL;
493 }
494
495 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
496 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
497 r->status);
498 return -EINVAL;
499 }
500
501 return 0;
502}
503
504static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
505{
506 struct spi_device *spi = to_spi_device(wilc->dev);
507 struct wilc_spi *spi_priv = wilc->bus_data;
508 u8 wb[32], rb[32];
509 int cmd_len, resp_len;
510 int retry, ix = 0;
511 u8 crc[2];
512 struct wilc_spi_cmd *c;
513 struct wilc_spi_rsp_data *r;
514
515 memset(wb, 0x0, sizeof(wb));
516 memset(rb, 0x0, sizeof(rb));
517 c = (struct wilc_spi_cmd *)wb;
518 c->cmd_type = cmd;
519 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_READ) {
520 c->u.dma_cmd.addr[0] = adr >> 16;
521 c->u.dma_cmd.addr[1] = adr >> 8;
522 c->u.dma_cmd.addr[2] = adr;
523 c->u.dma_cmd.size[0] = sz >> 8;
524 c->u.dma_cmd.size[1] = sz;
525 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd.crc);
526 if (!spi_priv->crc_off)
527 c->u.dma_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
528 } else if (cmd == CMD_DMA_EXT_WRITE || cmd == CMD_DMA_EXT_READ) {
529 c->u.dma_cmd_ext.addr[0] = adr >> 16;
530 c->u.dma_cmd_ext.addr[1] = adr >> 8;
531 c->u.dma_cmd_ext.addr[2] = adr;
532 c->u.dma_cmd_ext.size[0] = sz >> 16;
533 c->u.dma_cmd_ext.size[1] = sz >> 8;
534 c->u.dma_cmd_ext.size[2] = sz;
535 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd_ext.crc);
536 if (!spi_priv->crc_off)
537 c->u.dma_cmd_ext.crc[0] = wilc_get_crc7(wb, cmd_len);
538 } else {
539 dev_err(&spi->dev, "dma read write cmd [%x] not supported\n",
540 cmd);
541 return -EINVAL;
542 }
543 if (!spi_priv->crc_off)
544 cmd_len += 1;
545
546 resp_len = sizeof(*r);
547
548 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
549 dev_err(&spi->dev, "spi buffer size too small (%d)(%d) (%zu)\n",
550 cmd_len, resp_len, ARRAY_SIZE(wb));
551 return -EINVAL;
552 }
553
554 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
555 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
556 return -EINVAL;
557 }
558
559 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
560 if (r->rsp_cmd_type != cmd) {
561 dev_err(&spi->dev,
562 "Failed cmd response, cmd (%02x), resp (%02x)\n",
563 cmd, r->rsp_cmd_type);
564 return -EINVAL;
565 }
566
567 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
568 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
569 r->status);
570 return -EINVAL;
571 }
572
573 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_EXT_WRITE)
574 return 0;
575
576 while (sz > 0) {
577 int nbytes;
578 u8 rsp;
579
580 if (sz <= DATA_PKT_SZ)
581 nbytes = sz;
582 else
583 nbytes = DATA_PKT_SZ;
584
585 /*
586 * Data Response header
587 */
588 retry = 100;
589 do {
590 if (wilc_spi_rx(wilc, &rsp, 1)) {
591 dev_err(&spi->dev,
592 "Failed resp read, bus err\n");
593 return -EINVAL;
594 }
595 if (WILC_GET_RESP_HDR_START(rsp) == 0xf)
596 break;
597 } while (retry--);
598
599 /*
600 * Read bytes
601 */
602 if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
603 dev_err(&spi->dev,
604 "Failed block read, bus err\n");
605 return -EINVAL;
606 }
607
608 /*
609 * Read Crc
610 */
611 if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
612 dev_err(&spi->dev,
613 "Failed block crc read, bus err\n");
614 return -EINVAL;
615 }
616
617 ix += nbytes;
618 sz -= nbytes;
619 }
620 return 0;
621}
622
623static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
624{
625 struct spi_device *spi = to_spi_device(wilc->dev);
626 int result;
627 u8 cmd = CMD_SINGLE_READ;
628 u8 clockless = 0;
629
630 if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
631 /* Clockless register */
632 cmd = CMD_INTERNAL_READ;
633 clockless = 1;
634 }
635
636 result = wilc_spi_single_read(wilc, cmd, addr, data, clockless);
637 if (result) {
638 dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
639 return result;
640 }
641
642 le32_to_cpus(data);
643
644 return 0;
645}
646
647static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
648{
649 struct spi_device *spi = to_spi_device(wilc->dev);
650 int result;
651
652 if (size <= 4)
653 return -EINVAL;
654
655 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, buf, size);
656 if (result) {
657 dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
658 return result;
659 }
660
661 return 0;
662}
663
664static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
665{
666 struct spi_device *spi = to_spi_device(wilc->dev);
667 int result;
668
669 result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, dat, 0);
670 if (result) {
671 dev_err(&spi->dev, "Failed internal write cmd...\n");
672 return result;
673 }
674
675 return 0;
676}
677
678static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
679{
680 struct spi_device *spi = to_spi_device(wilc->dev);
681 int result;
682
683 result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, data, 0);
684 if (result) {
685 dev_err(&spi->dev, "Failed internal read cmd...\n");
686 return result;
687 }
688
689 le32_to_cpus(data);
690
691 return 0;
692}
693
694/********************************************
695 *
696 * Spi interfaces
697 *
698 ********************************************/
699
700static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
701{
702 struct spi_device *spi = to_spi_device(wilc->dev);
703 int result;
704 u8 cmd = CMD_SINGLE_WRITE;
705 u8 clockless = 0;
706
707 if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
708 /* Clockless register */
709 cmd = CMD_INTERNAL_WRITE;
710 clockless = 1;
711 }
712
713 result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless);
714 if (result) {
715 dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
716 return result;
717 }
718
719 return 0;
720}
721
722static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
723{
724 struct spi_device *spi = to_spi_device(wilc->dev);
725 int result;
726
727 /*
728 * has to be greated than 4
729 */
730 if (size <= 4)
731 return -EINVAL;
732
733 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size);
734 if (result) {
735 dev_err(&spi->dev,
736 "Failed cmd, write block (%08x)...\n", addr);
737 return result;
738 }
739
740 /*
741 * Data
742 */
743 result = spi_data_write(wilc, buf, size);
744 if (result) {
745 dev_err(&spi->dev, "Failed block data write...\n");
746 return result;
747 }
748
749 return 0;
750}
751
752/********************************************
753 *
754 * Bus interfaces
755 *
756 ********************************************/
757
758static int wilc_spi_deinit(struct wilc *wilc)
759{
760 /*
761 * TODO:
762 */
763 return 0;
764}
765
766static int wilc_spi_init(struct wilc *wilc, bool resume)
767{
768 struct spi_device *spi = to_spi_device(wilc->dev);
769 struct wilc_spi *spi_priv = wilc->bus_data;
770 u32 reg;
771 u32 chipid;
772 static int isinit;
773 int ret;
774
775 if (isinit) {
776 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
777 if (ret)
778 dev_err(&spi->dev, "Fail cmd read chip id...\n");
779
780 return ret;
781 }
782
783 /*
784 * configure protocol
785 */
786
787 /*
788 * TODO: We can remove the CRC trials if there is a definite
789 * way to reset
790 */
791 /* the SPI to it's initial value. */
792 ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);
793 if (ret) {
794 /*
795 * Read failed. Try with CRC off. This might happen when module
796 * is removed but chip isn't reset
797 */
798 spi_priv->crc_off = 1;
799 dev_err(&spi->dev,
800 "Failed read with CRC on, retrying with CRC off\n");
801 ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);
802 if (ret) {
803 /*
804 * Read failed with both CRC on and off,
805 * something went bad
806 */
807 dev_err(&spi->dev, "Failed internal read protocol\n");
808 return ret;
809 }
810 }
811 if (spi_priv->crc_off == 0) {
812 reg &= ~0xc; /* disable crc checking */
813 reg &= ~0x70;
814 reg |= (0x5 << 4);
815 ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);
816 if (ret) {
817 dev_err(&spi->dev,
818 "[wilc spi %d]: Failed internal write reg\n",
819 __LINE__);
820 return ret;
821 }
822 spi_priv->crc_off = 1;
823 }
824
825 /*
826 * make sure can read back chip id correctly
827 */
828 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
829 if (ret) {
830 dev_err(&spi->dev, "Fail cmd read chip id...\n");
831 return ret;
832 }
833
834 isinit = 1;
835
836 return 0;
837}
838
839static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
840{
841 int ret;
842
843 ret = spi_internal_read(wilc,
844 WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE, size);
845 *size = FIELD_GET(IRQ_DMA_WD_CNT_MASK, *size);
846
847 return ret;
848}
849
850static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
851{
852 return spi_internal_read(wilc, WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE,
853 int_status);
854}
855
856static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
857{
858 return spi_internal_write(wilc, WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,
859 val);
860}
861
862static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
863{
864 struct spi_device *spi = to_spi_device(wilc->dev);
865 u32 reg;
866 int ret, i;
867
868 if (nint > MAX_NUM_INT) {
869 dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
870 return -EINVAL;
871 }
872
873 /*
874 * interrupt pin mux select
875 */
876 ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®);
877 if (ret) {
878 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
879 WILC_PIN_MUX_0);
880 return ret;
881 }
882 reg |= BIT(8);
883 ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
884 if (ret) {
885 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
886 WILC_PIN_MUX_0);
887 return ret;
888 }
889
890 /*
891 * interrupt enable
892 */
893 ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®);
894 if (ret) {
895 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
896 WILC_INTR_ENABLE);
897 return ret;
898 }
899
900 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
901 reg |= (BIT((27 + i)));
902
903 ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
904 if (ret) {
905 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
906 WILC_INTR_ENABLE);
907 return ret;
908 }
909 if (nint) {
910 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);
911 if (ret) {
912 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
913 WILC_INTR2_ENABLE);
914 return ret;
915 }
916
917 for (i = 0; (i < 3) && (nint > 0); i++, nint--)
918 reg |= BIT(i);
919
920 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);
921 if (ret) {
922 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
923 WILC_INTR2_ENABLE);
924 return ret;
925 }
926 }
927
928 return 0;
929}
930
931/* Global spi HIF function table */
932static const struct wilc_hif_func wilc_hif_spi = {
933 .hif_init = wilc_spi_init,
934 .hif_deinit = wilc_spi_deinit,
935 .hif_read_reg = wilc_spi_read_reg,
936 .hif_write_reg = wilc_spi_write_reg,
937 .hif_block_rx = wilc_spi_read,
938 .hif_block_tx = wilc_spi_write,
939 .hif_read_int = wilc_spi_read_int,
940 .hif_clear_int_ext = wilc_spi_clear_int_ext,
941 .hif_read_size = wilc_spi_read_size,
942 .hif_block_tx_ext = wilc_spi_write,
943 .hif_block_rx_ext = wilc_spi_read,
944 .hif_sync_ext = wilc_spi_sync_ext,
945};