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