Linux Audio

Check our new training course

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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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};