1 /**
2  *
3  * \file
4  *
5  * \brief This module contains NMC1000 SPI protocol bus APIs implementation.
6  *
7  * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * \asf_license_stop
39  *
40  */
41 #include "common/include/nm_common.h"
42 
43 #ifdef CONF_WINC_USE_SPI
44 
45 /* Don't force USE_OLD_SPI_SW, instead we will pass it from Zephyr side
46 #define USE_OLD_SPI_SW
47 */
48 
49 #include "bus_wrapper/include/nm_bus_wrapper.h"
50 #include "nmspi.h"
51 
52 #define NMI_PERIPH_REG_BASE 0x1000
53 #define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
54 #define NMI_CHIPID	(NMI_PERIPH_REG_BASE)
55 #define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
56 #define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
57 
58 #define NMI_SPI_REG_BASE 0xe800
59 #define NMI_SPI_CTL (NMI_SPI_REG_BASE)
60 #define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE+0x4)
61 #define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE+0x8)
62 #define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE+0xc)
63 #define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE+0x10)
64 #define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE+0x20)
65 #define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE+0x24)
66 #define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE+0x2c)
67 #define NMI_SPI_MISC_CTRL (NMI_SPI_REG_BASE+0x48)
68 
69 #define NMI_SPI_PROTOCOL_OFFSET (NMI_SPI_PROTOCOL_CONFIG-NMI_SPI_REG_BASE)
70 
71 #define SPI_BASE                NMI_SPI_REG_BASE
72 
73 #define CMD_DMA_WRITE			0xc1
74 #define CMD_DMA_READ			0xc2
75 #define CMD_INTERNAL_WRITE		0xc3
76 #define CMD_INTERNAL_READ		0xc4
77 #define CMD_TERMINATE			0xc5
78 #define CMD_REPEAT				0xc6
79 #define CMD_DMA_EXT_WRITE		0xc7
80 #define CMD_DMA_EXT_READ		0xc8
81 #define CMD_SINGLE_WRITE		0xc9
82 #define CMD_SINGLE_READ			0xca
83 #define CMD_RESET				0xcf
84 
85 #define N_OK					 1
86 #define N_FAIL					 0
87 #define N_RESET					-1
88 #define N_RETRY					-2
89 
90 #define SPI_RESP_RETRY_COUNT 	(10)
91 #define SPI_RETRY_COUNT			(10)
92 #define DATA_PKT_SZ_256 		256
93 #define DATA_PKT_SZ_512			512
94 #define DATA_PKT_SZ_1K			1024
95 #define DATA_PKT_SZ_4K			(4 * 1024)
96 #define DATA_PKT_SZ_8K			(8 * 1024)
97 #define DATA_PKT_SZ				DATA_PKT_SZ_8K
98 
99 static uint8 	gu8Crc_off	=   0;
100 
nmi_spi_read(uint8 * b,uint16 sz)101 static sint8 nmi_spi_read(uint8* b, uint16 sz)
102 {
103 	tstrNmSpiRw spi;
104 	spi.pu8InBuf = NULL;
105 	spi.pu8OutBuf = b;
106 	spi.u16Sz = sz;
107 	return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
108 }
109 
nmi_spi_write(uint8 * b,uint16 sz)110 static sint8 nmi_spi_write(uint8* b, uint16 sz)
111 {
112 	tstrNmSpiRw spi;
113 	spi.pu8InBuf = b;
114 	spi.pu8OutBuf = NULL;
115 	spi.u16Sz = sz;
116 	return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
117 }
118 #ifndef USE_OLD_SPI_SW
nmi_spi_rw(uint8 * bin,uint8 * bout,uint16 sz)119 static sint8 nmi_spi_rw(uint8 *bin,uint8* bout,uint16 sz)
120 {
121 	tstrNmSpiRw spi;
122 	spi.pu8InBuf = bin;
123 	spi.pu8OutBuf = bout;
124 	spi.u16Sz = sz;
125 	return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
126 }
127 #endif
128 /********************************************
129 
130 	Crc7
131 
132 ********************************************/
133 
134 static const uint8 crc7_syndrome_table[256] = {
135 	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
136 	0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
137 	0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
138 	0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
139 	0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
140 	0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
141 	0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
142 	0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
143 	0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
144 	0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
145 	0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
146 	0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
147 	0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
148 	0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
149 	0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
150 	0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
151 	0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
152 	0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
153 	0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
154 	0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
155 	0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
156 	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
157 	0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
158 	0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
159 	0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
160 	0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
161 	0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
162 	0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
163 	0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
164 	0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
165 	0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
166 	0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
167 };
168 
169 
crc7_byte(uint8 crc,uint8 data)170 static uint8 crc7_byte(uint8 crc, uint8 data)
171 {
172 	return crc7_syndrome_table[(crc << 1) ^ data];
173 }
174 
crc7(uint8 crc,const uint8 * buffer,uint32 len)175 static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
176 {
177 	while (len--)
178 		crc = crc7_byte(crc, *buffer++);
179 	return crc;
180 }
181 
182 /********************************************
183 
184 	Spi protocol Function
185 
186 ********************************************/
187 
188 #define CMD_DMA_WRITE			0xc1
189 #define CMD_DMA_READ			0xc2
190 #define CMD_INTERNAL_WRITE		0xc3
191 #define CMD_INTERNAL_READ		0xc4
192 #define CMD_TERMINATE			0xc5
193 #define CMD_REPEAT				0xc6
194 #define CMD_DMA_EXT_WRITE		0xc7
195 #define CMD_DMA_EXT_READ		0xc8
196 #define CMD_SINGLE_WRITE		0xc9
197 #define CMD_SINGLE_READ			0xca
198 #define CMD_RESET				0xcf
199 
200 #define DATA_PKT_SZ_256 		256
201 #define DATA_PKT_SZ_512			512
202 #define DATA_PKT_SZ_1K			1024
203 #define DATA_PKT_SZ_4K			(4 * 1024)
204 #define DATA_PKT_SZ_8K			(8 * 1024)
205 #define DATA_PKT_SZ				DATA_PKT_SZ_8K
206 
spi_cmd(uint8 cmd,uint32 adr,uint32 u32data,uint32 sz,uint8 clockless)207 static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 clockless)
208 {
209 	uint8 bc[9];
210 	uint8 len = 5;
211 	sint8 result = N_OK;
212 
213 	bc[0] = cmd;
214 	switch (cmd) {
215 	case CMD_SINGLE_READ:				/* single word (4 bytes) read */
216 		bc[1] = (uint8)(adr >> 16);
217 		bc[2] = (uint8)(adr >> 8);
218 		bc[3] = (uint8)adr;
219 		len = 5;
220 		break;
221 	case CMD_INTERNAL_READ:			/* internal register read */
222 		bc[1] = (uint8)(adr >> 8);
223 		if(clockless)  bc[1] |= (1 << 7);
224 		bc[2] = (uint8)adr;
225 		bc[3] = 0x00;
226 		len = 5;
227 		break;
228 	case CMD_TERMINATE:					/* termination */
229 		bc[1] = 0x00;
230 		bc[2] = 0x00;
231 		bc[3] = 0x00;
232 		len = 5;
233 		break;
234 	case CMD_REPEAT:						/* repeat */
235 		bc[1] = 0x00;
236 		bc[2] = 0x00;
237 		bc[3] = 0x00;
238 		len = 5;
239 		break;
240 	case CMD_RESET:							/* reset */
241 		bc[1] = 0xff;
242 		bc[2] = 0xff;
243 		bc[3] = 0xff;
244 		len = 5;
245 		break;
246 	case CMD_DMA_WRITE:					/* dma write */
247 	case CMD_DMA_READ:					/* dma read */
248 		bc[1] = (uint8)(adr >> 16);
249 		bc[2] = (uint8)(adr >> 8);
250 		bc[3] = (uint8)adr;
251 		bc[4] = (uint8)(sz >> 8);
252 		bc[5] = (uint8)(sz);
253 		len = 7;
254 		break;
255 	case CMD_DMA_EXT_WRITE:		/* dma extended write */
256 	case CMD_DMA_EXT_READ:			/* dma extended read */
257 		bc[1] = (uint8)(adr >> 16);
258 		bc[2] = (uint8)(adr >> 8);
259 		bc[3] = (uint8)adr;
260 		bc[4] = (uint8)(sz >> 16);
261 		bc[5] = (uint8)(sz >> 8);
262 		bc[6] = (uint8)(sz);
263 		len = 8;
264 		break;
265 	case CMD_INTERNAL_WRITE:		/* internal register write */
266 		bc[1] = (uint8)(adr >> 8);
267 		if(clockless)  bc[1] |= (1 << 7);
268 		bc[2] = (uint8)(adr);
269 		bc[3] = (uint8)(u32data >> 24);
270 		bc[4] = (uint8)(u32data >> 16);
271 		bc[5] = (uint8)(u32data >> 8);
272 		bc[6] = (uint8)(u32data);
273 		len = 8;
274 		break;
275 	case CMD_SINGLE_WRITE:			/* single word write */
276 		bc[1] = (uint8)(adr >> 16);
277 		bc[2] = (uint8)(adr >> 8);
278 		bc[3] = (uint8)(adr);
279 		bc[4] = (uint8)(u32data >> 24);
280 		bc[5] = (uint8)(u32data >> 16);
281 		bc[6] = (uint8)(u32data >> 8);
282 		bc[7] = (uint8)(u32data);
283 		len = 9;
284 		break;
285 	default:
286 		result = N_FAIL;
287 		break;
288 	}
289 
290 	if (result) {
291 		if (!gu8Crc_off)
292 			bc[len-1] = (crc7(0x7f, (const uint8 *)&bc[0], len-1)) << 1;
293 		else
294 			len-=1;
295 
296 		if (M2M_SUCCESS != nmi_spi_write(bc, len)) {
297 			M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
298 			result = N_FAIL;
299 		}
300 	}
301 
302 	return result;
303 }
304 
spi_data_rsp(uint8 cmd)305 static sint8 spi_data_rsp(uint8 cmd)
306 {
307 	uint8 len;
308 	uint8 rsp[3];
309 	sint8 result = N_OK;
310 
311     if (!gu8Crc_off)
312 		len = 2;
313 	else
314 		len = 3;
315 
316 	if (M2M_SUCCESS != nmi_spi_read(&rsp[0], len)) {
317 		M2M_ERR("[nmi spi]: Failed bus error...\n");
318 		result = N_FAIL;
319 		goto _fail_;
320 	}
321 
322 	if((rsp[len-1] != 0)||(rsp[len-2] != 0xC3))
323 	{
324 		M2M_ERR("[nmi spi]: Failed data response read, %x %x %x\n",rsp[0],rsp[1],rsp[2]);
325 		result = N_FAIL;
326 		goto _fail_;
327 	}
328 _fail_:
329 
330 	return result;
331 }
332 
spi_cmd_rsp(uint8 cmd)333 static sint8 spi_cmd_rsp(uint8 cmd)
334 {
335 	uint8 rsp;
336 	sint8 result = N_OK;
337 	sint8 s8RetryCnt;
338 
339 	/**
340 		Command/Control response
341 	**/
342 	if ((cmd == CMD_RESET) ||
343 		 (cmd == CMD_TERMINATE) ||
344 		 (cmd == CMD_REPEAT)) {
345 		if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
346 			result = N_FAIL;
347 			goto _fail_;
348 		}
349 	}
350 
351 	/* wait for response */
352 	s8RetryCnt = SPI_RESP_RETRY_COUNT;
353 	do
354 	{
355 		if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
356 			M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
357 			result = N_FAIL;
358 			goto _fail_;
359 		}
360 	} while((rsp != cmd) && (s8RetryCnt-- >0));
361 
362 	/**
363 		State response
364 	**/
365 	/* wait for response */
366 	s8RetryCnt = SPI_RESP_RETRY_COUNT;
367 	do
368 	{
369 		if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
370 			M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
371 			result = N_FAIL;
372 			goto _fail_;
373 		}
374 	} while((rsp != 0x00) && (s8RetryCnt-- >0));
375 
376 _fail_:
377 
378 	return result;
379 }
380 #ifndef USE_OLD_SPI_SW
spi_cmd_complete(uint8_t cmd,uint32_t adr,uint8_t * b,uint32_t sz,uint8_t clockless)381 static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
382 {
383 	uint8_t wb[32], rb[32];
384 	uint8_t wix, rix;
385 	uint32_t len2;
386 	uint8_t rsp;
387 	int len = 0;
388 	int result = N_OK;
389 
390 	wb[0] = cmd;
391 	switch (cmd) {
392 	case CMD_SINGLE_READ:				/* single word (4 bytes) read */
393 		wb[1] = (uint8_t)(adr >> 16);
394 		wb[2] = (uint8_t)(adr >> 8);
395 		wb[3] = (uint8_t)adr;
396 		len = 5;
397 		break;
398 	case CMD_INTERNAL_READ:			/* internal register read */
399 		wb[1] = (uint8_t)(adr >> 8);
400 		if(clockless == 1)  wb[1] |= (1 << 7);
401 		wb[2] = (uint8_t)adr;
402 		wb[3] = 0x00;
403 		len = 5;
404 		break;
405 	case CMD_TERMINATE:					/* termination */
406 		wb[1] = 0x00;
407 		wb[2] = 0x00;
408 		wb[3] = 0x00;
409 		len = 5;
410 		break;
411 	case CMD_REPEAT:						/* repeat */
412 		wb[1] = 0x00;
413 		wb[2] = 0x00;
414 		wb[3] = 0x00;
415 		len = 5;
416 		break;
417 	case CMD_RESET:							/* reset */
418 		wb[1] = 0xff;
419 		wb[2] = 0xff;
420 		wb[3] = 0xff;
421 		len = 5;
422 		break;
423 	case CMD_DMA_WRITE:					/* dma write */
424 	case CMD_DMA_READ:					/* dma read */
425 		wb[1] = (uint8_t)(adr >> 16);
426 		wb[2] = (uint8_t)(adr >> 8);
427 		wb[3] = (uint8_t)adr;
428 		wb[4] = (uint8_t)(sz >> 8);
429 		wb[5] = (uint8_t)(sz);
430 		len = 7;
431 		break;
432 	case CMD_DMA_EXT_WRITE:		/* dma extended write */
433 	case CMD_DMA_EXT_READ:			/* dma extended read */
434 		wb[1] = (uint8_t)(adr >> 16);
435 		wb[2] = (uint8_t)(adr >> 8);
436 		wb[3] = (uint8_t)adr;
437 		wb[4] = (uint8_t)(sz >> 16);
438 		wb[5] = (uint8_t)(sz >> 8);
439 		wb[6] = (uint8_t)(sz);
440 		len = 8;
441 		break;
442 	case CMD_INTERNAL_WRITE:		/* internal register write */
443 		wb[1] = (uint8_t)(adr >> 8);
444 		if(clockless == 1)  wb[1] |= (1 << 7);
445 		wb[2] = (uint8_t)(adr);
446 		wb[3] = b[3];
447 		wb[4] = b[2];
448 		wb[5] = b[1];
449 		wb[6] = b[0];
450 		len = 8;
451 		break;
452 	case CMD_SINGLE_WRITE:			/* single word write */
453 		wb[1] = (uint8_t)(adr >> 16);
454 		wb[2] = (uint8_t)(adr >> 8);
455 		wb[3] = (uint8_t)(adr);
456 		wb[4] = b[3];
457 		wb[5] = b[2];
458 		wb[6] = b[1];
459 		wb[7] = b[0];
460 		len = 9;
461 		break;
462 	default:
463 		result = N_FAIL;
464 		break;
465 	}
466 
467 	if (result != N_OK) {
468 		return result;
469 	}
470 
471 	if (!gu8Crc_off) {
472 		wb[len-1] = (crc7(0x7f, (const uint8_t *)&wb[0], len-1)) << 1;
473 	} else {
474 		len -=1;
475 	}
476 
477 #define NUM_SKIP_BYTES (1)
478 #define NUM_RSP_BYTES (2)
479 #define NUM_DATA_HDR_BYTES (1)
480 #define NUM_DATA_BYTES (4)
481 #define NUM_CRC_BYTES (2)
482 #define NUM_DUMMY_BYTES (3)
483 
484 	if ((cmd == CMD_RESET) ||
485 		(cmd == CMD_TERMINATE) ||
486 		(cmd == CMD_REPEAT)) {
487 			len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
488 	} else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
489 		if (!gu8Crc_off) {
490 			len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
491 			+ NUM_CRC_BYTES + NUM_DUMMY_BYTES);
492 		} else {
493 			len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
494 			+ NUM_DUMMY_BYTES);
495 		}
496 	} else {
497 		len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
498 	}
499 #undef NUM_DUMMY_BYTES
500 
501 	if(len2 > (sizeof(wb)/sizeof(wb[0]))) {
502 		M2M_ERR("[nmi spi]: spi buffer size too small (%d) (%d)\n",
503 			len2, (sizeof(wb)/sizeof(wb[0])));
504 		result = N_FAIL;
505 		return result;
506 	}
507 	/* zero spi write buffers. */
508 	for(wix = len; wix< len2; wix++) {
509 		wb[wix] = 0;
510 	}
511 	rix = len;
512 
513 	if (nmi_spi_rw(wb, rb, len2) != M2M_SUCCESS) {
514 		M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
515 		result = N_FAIL;
516 		return result;
517 	}
518 
519 #if 0
520 	{
521 		int jj;
522 		printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2);
523 		for(jj=0; jj<sizeof(wb)/sizeof(wb[0]); jj++) {
524 
525 			if(jj >= len2) break;
526 			if(((jj+1)%16) != 0) {
527 				if((jj%16) == 0) {
528 					printk("wb[%02x]: %02x ", jj, wb[jj]);
529 				} else {
530 					printk("%02x ", wb[jj]);
531 				}
532 			} else {
533 				printk("%02x\n", wb[jj]);
534 			}
535 		}
536 		printk("\n");
537 
538 		for(jj=0; jj<sizeof(rb)/sizeof(rb[0]); jj++) {
539 
540 				if(jj >= len2) break;
541 				if(((jj+1)%16) != 0) {
542 					if((jj%16) == 0) {
543 						printk("rb[%02x]: %02x ", jj, rb[jj]);
544 					} else {
545 						printk("%02x ", rb[jj]);
546 					}
547 				} else {
548 					printk("%02x\n", rb[jj]);
549 				}
550 			}
551 		printk("\n");
552 	}
553 #endif
554 
555 	/**
556 	Command/Control response
557 	**/
558 	if ((cmd == CMD_RESET) ||
559 		(cmd == CMD_TERMINATE) ||
560 		(cmd == CMD_REPEAT)) {
561 			rix++; /* skip 1 byte */
562 	}
563 
564 	rsp = rb[rix++];
565 
566 
567 	if (rsp != cmd) {
568 		M2M_ERR("[nmi spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
569 		result = N_FAIL;
570 		return result;
571 	}
572 
573 	/**
574 	State response
575 	**/
576 	rsp = rb[rix++];
577 	if (rsp != 0x00) {
578 		M2M_ERR("[nmi spi]: Failed cmd state response state (%02x)\n", rsp);
579 		result = N_FAIL;
580 		return result;
581 	}
582 
583 	if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
584 		|| (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
585 			int retry;
586 			//uint16_t crc1, crc2;
587 			uint8_t crc[2];
588 			/**
589 			Data Respnose header
590 			**/
591 			retry = SPI_RESP_RETRY_COUNT;
592 			do {
593 				/* ensure there is room in buffer later to read data and crc */
594 				if(rix < len2) {
595 					rsp = rb[rix++];
596 				} else {
597 					retry = 0;
598 					break;
599 				}
600 				if (((rsp >> 4) & 0xf) == 0xf)
601 					break;
602 			} while (retry--);
603 
604 			if (retry <= 0) {
605 				M2M_ERR("[nmi spi]: Error, data read response (%02x)\n", rsp);
606 				result = N_RESET;
607 				return result;
608 			}
609 
610 			if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
611 				/**
612 				Read bytes
613 				**/
614 				if((rix+3) < len2) {
615 					b[0] = rb[rix++];
616 					b[1] = rb[rix++];
617 					b[2] = rb[rix++];
618 					b[3] = rb[rix++];
619 				} else {
620 					M2M_ERR("[nmi spi]: buffer overrun when reading data.\n");
621 					result = N_FAIL;
622 					return result;
623 				}
624 
625 				if (!gu8Crc_off) {
626 					/**
627 					Read Crc
628 					**/
629 					if((rix+1) < len2) {
630 						crc[0] = rb[rix++];
631 						crc[1] = rb[rix++];
632 					} else {
633 						M2M_ERR("[nmi spi]: buffer overrun when reading crc.\n");
634 						result = N_FAIL;
635 						return result;
636 					}
637 				}
638 			} else if((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
639 				int ix;
640 
641 				/* some data may be read in response to dummy bytes. */
642 				for(ix=0; (rix < len2) && (ix < sz);) {
643 					b[ix++] = rb[rix++];
644 				}
645 #if 0
646 				if(ix) M2M_INFO("ttt %d %d\n", sz, ix);
647 #endif
648 				sz -= ix;
649 
650 				if(sz > 0) {
651 					int nbytes;
652 
653 					if (sz <= (DATA_PKT_SZ-ix)) {
654 						nbytes = sz;
655 					} else {
656 						nbytes = DATA_PKT_SZ-ix;
657 					}
658 
659 					/**
660 					Read bytes
661 					**/
662 					if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
663 						M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
664 						result = N_FAIL;
665 						goto _error_;
666 					}
667 
668 					/**
669 					Read Crc
670 					**/
671 					if (!gu8Crc_off) {
672 						if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
673 							M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
674 							result = N_FAIL;
675 							goto _error_;
676 						}
677 					}
678 
679 
680 					ix += nbytes;
681 					sz -= nbytes;
682 				}
683 
684 				/*  if any data in left unread, then read the rest using normal DMA code.*/
685 				while(sz > 0) {
686 					int nbytes;
687 
688 					if (sz <= DATA_PKT_SZ) {
689 						nbytes = sz;
690 					} else {
691 						nbytes = DATA_PKT_SZ;
692 					}
693 
694 					/**
695 					read data response only on the next DMA cycles not
696 					the first DMA since data response header is already
697 					handled above for the first DMA.
698 					**/
699 					/**
700 					Data Respnose header
701 					**/
702 					retry = SPI_RESP_RETRY_COUNT;
703 					do {
704 						if (nmi_spi_read(&rsp, 1) != M2M_SUCCESS) {
705 							M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
706 							result = N_FAIL;
707 							break;
708 						}
709 						if (((rsp >> 4) & 0xf) == 0xf)
710 							break;
711 					} while (retry--);
712 
713 					if (result == N_FAIL)
714 						break;
715 
716 
717 					/**
718 					Read bytes
719 					**/
720 					if (nmi_spi_read(&b[ix], nbytes) != M2M_SUCCESS) {
721 						M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
722 						result = N_FAIL;
723 						break;
724 					}
725 
726 					/**
727 					Read Crc
728 					**/
729 					if (!gu8Crc_off) {
730 						if (nmi_spi_read(crc, 2) != M2M_SUCCESS) {
731 							M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
732 							result = N_FAIL;
733 							break;
734 						}
735 					}
736 
737 					ix += nbytes;
738 					sz -= nbytes;
739 				}
740 			}
741 	}
742 _error_:
743 	return result;
744 }
745 #endif
746 #if defined USE_OLD_SPI_SW
spi_data_read(uint8 * b,uint16 sz,uint8 clockless)747 static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
748 {
749 	sint16 retry, ix, nbytes;
750 	sint8 result = N_OK;
751 	uint8 crc[2];
752 	uint8 rsp;
753 
754 	/**
755 		Data
756 	**/
757 	ix = 0;
758 	do {
759 		if (sz <= DATA_PKT_SZ)
760 			nbytes = sz;
761 		else
762 			nbytes = DATA_PKT_SZ;
763 
764 		/**
765 			Data Respnose header
766 		**/
767 		retry = SPI_RESP_RETRY_COUNT;
768 		do {
769 			if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
770 				M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
771 				result = N_FAIL;
772 				break;
773 			}
774 			if (((rsp >> 4) & 0xf) == 0xf)
775 				break;
776 		} while (retry--);
777 
778 		if (result == N_FAIL)
779 			break;
780 
781 		if (retry <= 0) {
782 			M2M_ERR("[nmi spi]: Failed data response read...(%02x)\n", rsp);
783 			result = N_FAIL;
784 			break;
785 		}
786 
787 		/**
788 			Read bytes
789 		**/
790 		if (M2M_SUCCESS != nmi_spi_read(&b[ix], nbytes)) {
791 			M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
792 			result = N_FAIL;
793 			break;
794 		}
795 		if(!clockless)
796 		{
797 			/**
798 			Read Crc
799 			**/
800 			if (!gu8Crc_off) {
801 				if (M2M_SUCCESS != nmi_spi_read(crc, 2)) {
802 					M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
803 					result = N_FAIL;
804 					break;
805 				}
806 			}
807 		}
808 		ix += nbytes;
809 		sz -= nbytes;
810 
811 	} while (sz);
812 
813 	return result;
814 }
815 #endif
816 
spi_data_write(uint8 * b,uint16 sz)817 static sint8 spi_data_write(uint8 *b, uint16 sz)
818 {
819 	sint16 ix;
820 	uint16 nbytes;
821 	sint8 result = 1;
822 	uint8 cmd, order, crc[2] = {0};
823 	//uint8 rsp;
824 
825 	/**
826 		Data
827 	**/
828 	ix = 0;
829 	do {
830 		if (sz <= DATA_PKT_SZ)
831 			nbytes = sz;
832 		else
833 			nbytes = DATA_PKT_SZ;
834 
835 		/**
836 			Write command
837 		**/
838 		cmd = 0xf0;
839 		if (ix == 0)  {
840 			if (sz <= DATA_PKT_SZ)
841 				order = 0x3;
842 			else
843 				order = 0x1;
844 		} else {
845 			if (sz <= DATA_PKT_SZ)
846 				order = 0x3;
847 			else
848 				order = 0x2;
849 		}
850 		cmd |= order;
851 		if (M2M_SUCCESS != nmi_spi_write(&cmd, 1)) {
852 			M2M_ERR("[nmi spi]: Failed data block cmd write, bus error...\n");
853 			result = N_FAIL;
854 			break;
855 		}
856 
857 		/**
858 			Write data
859 		**/
860 		if (M2M_SUCCESS != nmi_spi_write(&b[ix], nbytes)) {
861 			M2M_ERR("[nmi spi]: Failed data block write, bus error...\n");
862 			result = N_FAIL;
863 			break;
864 		}
865 
866 		/**
867 			Write Crc
868 		**/
869 		if (!gu8Crc_off) {
870 			if (M2M_SUCCESS != nmi_spi_write(crc, 2)) {
871 				M2M_ERR("[nmi spi]: Failed data block crc write, bus error...\n");
872 				result = N_FAIL;
873 				break;
874 			}
875 		}
876 
877 		ix += nbytes;
878 		sz -= nbytes;
879 	} while (sz);
880 
881 
882 	return result;
883 }
884 
885 /********************************************
886 
887 	Spi Internal Read/Write Function
888 
889 ********************************************/
890 
891 /********************************************
892 
893 	Spi interfaces
894 
895 ********************************************/
896 
spi_write_reg(uint32 addr,uint32 u32data)897 static sint8 spi_write_reg(uint32 addr, uint32 u32data)
898 {
899 	uint8 retry = SPI_RETRY_COUNT;
900 	sint8 result = N_OK;
901 	uint8 cmd = CMD_SINGLE_WRITE;
902 	uint8 clockless = 0;
903 
904 _RETRY_:
905 	if (addr <= 0x30)
906 	{
907 		/**
908 		NMC1000 clockless registers.
909 		**/
910 		cmd = CMD_INTERNAL_WRITE;
911 		clockless = 1;
912 	}
913 	else
914 	{
915 		cmd = CMD_SINGLE_WRITE;
916 		clockless = 0;
917 	}
918 
919 #if defined USE_OLD_SPI_SW
920 	result = spi_cmd(cmd, addr, u32data, 4, clockless);
921 	if (result != N_OK) {
922 		M2M_ERR("[nmi spi]: Failed cmd, write reg (%08x)...\n", (unsigned int)addr);
923 		goto _FAIL_;
924 	}
925 
926 	result = spi_cmd_rsp(cmd);
927 	if (result != N_OK) {
928 		M2M_ERR("[nmi spi]: Failed cmd response, write reg (%08x)...\n", (unsigned int)addr);
929 		goto _FAIL_;
930 	}
931 
932 #else
933 
934 	result = spi_cmd_complete(cmd, addr, (uint8*)&u32data, 4, clockless);
935 	if (result != N_OK) {
936 		M2M_ERR( "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
937 		goto _FAIL_;
938 	}
939 
940 #endif
941 _FAIL_:
942 	if(result != N_OK)
943 	{
944 		nm_bsp_sleep(1);
945 		spi_cmd(CMD_RESET, 0, 0, 0, 0);
946 		spi_cmd_rsp(CMD_RESET);
947 		M2M_ERR("Reset and retry %d %lx %lx\n",retry,addr,u32data);
948 		nm_bsp_sleep(1);
949 		retry--;
950 		if(retry) goto _RETRY_;
951 	}
952 
953 	return result;
954 }
955 
nm_spi_write(uint32 addr,uint8 * buf,uint16 size)956 static sint8 nm_spi_write(uint32 addr, uint8 *buf, uint16 size)
957 {
958 	sint8 result;
959 	uint8 retry = SPI_RETRY_COUNT;
960 	uint8 cmd = CMD_DMA_EXT_WRITE;
961 
962 
963 _RETRY_:
964 	/**
965 		Command
966 	**/
967 #if defined USE_OLD_SPI_SW
968 	//Workaround hardware problem with single byte transfers over SPI bus
969 	if (size == 1)
970 		size = 2;
971 
972 	result = spi_cmd(cmd, addr, 0, size,0);
973 	if (result != N_OK) {
974 		M2M_ERR("[nmi spi]: Failed cmd, write block (%08x)...\n", (unsigned int)addr);
975 		goto _FAIL_;
976 	}
977 
978 	result = spi_cmd_rsp(cmd);
979 	if (result != N_OK) {
980 		M2M_ERR("[nmi spi ]: Failed cmd response, write block (%08x)...\n", (unsigned int)addr);
981 		goto _FAIL_;
982 	}
983 #else
984 	result = spi_cmd_complete(cmd, addr, NULL, size, 0);
985 	if (result != N_OK) {
986 		M2M_ERR( "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
987 		goto _FAIL_;
988 	}
989 #endif
990 
991 	/**
992 		Data
993 	**/
994 	result = spi_data_write(buf, size);
995 	if (result != N_OK) {
996 		M2M_ERR("[nmi spi]: Failed block data write...\n");
997 		goto _FAIL_;
998 	}
999 	/**
1000 		Data RESP
1001 	**/
1002 	result = spi_data_rsp(cmd);
1003 	if (result != N_OK) {
1004 		M2M_ERR("[nmi spi]: Failed block data write...\n");
1005 		goto _FAIL_;
1006 	}
1007 
1008 _FAIL_:
1009 	if(result != N_OK)
1010 	{
1011 		nm_bsp_sleep(1);
1012 		spi_cmd(CMD_RESET, 0, 0, 0, 0);
1013 		spi_cmd_rsp(CMD_RESET);
1014 		M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
1015 		nm_bsp_sleep(1);
1016 		retry--;
1017 		if(retry) goto _RETRY_;
1018 	}
1019 
1020 
1021 	return result;
1022 }
1023 
spi_read_reg(uint32 addr,uint32 * u32data)1024 static sint8 spi_read_reg(uint32 addr, uint32 *u32data)
1025 {
1026 	uint8 retry = SPI_RETRY_COUNT;
1027 	sint8 result = N_OK;
1028 	uint8 cmd = CMD_SINGLE_READ;
1029 	uint8 tmp[4];
1030 	uint8 clockless = 0;
1031 
1032 _RETRY_:
1033 
1034 	if (addr <= 0xff)
1035 	{
1036 		/**
1037 		NMC1000 clockless registers.
1038 		**/
1039 		cmd = CMD_INTERNAL_READ;
1040 		clockless = 1;
1041 	}
1042 	else
1043 	{
1044 		cmd = CMD_SINGLE_READ;
1045 		clockless = 0;
1046 	}
1047 
1048 #if defined USE_OLD_SPI_SW
1049 	result = spi_cmd(cmd, addr, 0, 4, clockless);
1050 	if (result != N_OK) {
1051 		M2M_ERR("[nmi spi]: Failed cmd, read reg (%08x)...\n", (unsigned int)addr);
1052 		goto _FAIL_;
1053 	}
1054 
1055 	result = spi_cmd_rsp(cmd);
1056 	if (result != N_OK) {
1057 		M2M_ERR("[nmi spi]: Failed cmd response, read reg (%08x)...\n", (unsigned int)addr);
1058 		goto _FAIL_;
1059 	}
1060 
1061 	/* to avoid endianess issues */
1062 	result = spi_data_read(&tmp[0], 4, clockless);
1063 	if (result != N_OK) {
1064 		M2M_ERR("[nmi spi]: Failed data read...\n");
1065 		goto _FAIL_;
1066 	}
1067 #else
1068 	result = spi_cmd_complete(cmd, addr, (uint8*)&tmp[0], 4, clockless);
1069 	if (result != N_OK) {
1070 		M2M_ERR( "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
1071 		goto _FAIL_;
1072 	}
1073 
1074 #endif
1075 
1076 	*u32data = tmp[0] |
1077 		((uint32)tmp[1] << 8) |
1078 		((uint32)tmp[2] << 16) |
1079 		((uint32)tmp[3] << 24);
1080 
1081 _FAIL_:
1082 	if(result != N_OK)
1083 	{
1084 
1085 		nm_bsp_sleep(1);
1086 		spi_cmd(CMD_RESET, 0, 0, 0, 0);
1087 		spi_cmd_rsp(CMD_RESET);
1088 		M2M_ERR("Reset and retry %d %lx\n",retry,addr);
1089 		nm_bsp_sleep(1);
1090 		retry--;
1091 		if(retry) goto _RETRY_;
1092 	}
1093 
1094 	return result;
1095 }
1096 
nm_spi_read(uint32 addr,uint8 * buf,uint16 size)1097 static sint8 nm_spi_read(uint32 addr, uint8 *buf, uint16 size)
1098 {
1099 	uint8 cmd = CMD_DMA_EXT_READ;
1100 	sint8 result;
1101 	uint8 retry = SPI_RETRY_COUNT;
1102 #if defined USE_OLD_SPI_SW
1103 	uint8 tmp[2];
1104 	uint8 single_byte_workaround = 0;
1105 #endif
1106 
1107 _RETRY_:
1108 
1109 	/**
1110 		Command
1111 	**/
1112 #if defined USE_OLD_SPI_SW
1113 	if (size == 1)
1114 	{
1115 		//Workaround hardware problem with single byte transfers over SPI bus
1116 		size = 2;
1117 		single_byte_workaround = 1;
1118 	}
1119 	result = spi_cmd(cmd, addr, 0, size,0);
1120 	if (result != N_OK) {
1121 		M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", (unsigned int)addr);
1122 		goto _FAIL_;
1123 	}
1124 
1125 	result = spi_cmd_rsp(cmd);
1126 	if (result != N_OK) {
1127 		M2M_ERR("[nmi spi]: Failed cmd response, read block (%08x)...\n", (unsigned int)addr);
1128 		goto _FAIL_;
1129 	}
1130 
1131 	/**
1132 		Data
1133 	**/
1134 	if (single_byte_workaround)
1135 	{
1136 		result = spi_data_read(tmp, size,0);
1137 		buf[0] = tmp[0];
1138 	}
1139 	else
1140 		result = spi_data_read(buf, size,0);
1141 
1142 	if (result != N_OK) {
1143 		M2M_ERR("[nmi spi]: Failed block data read...\n");
1144 		goto _FAIL_;
1145 	}
1146 #else
1147 	result = spi_cmd_complete(cmd, addr, buf, size, 0);
1148 	if (result != N_OK) {
1149 		M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
1150 		goto _FAIL_;
1151 	}
1152 #endif
1153 
1154 _FAIL_:
1155 	if(result != N_OK)
1156 	{
1157 		nm_bsp_sleep(1);
1158 		spi_cmd(CMD_RESET, 0, 0, 0, 0);
1159 		spi_cmd_rsp(CMD_RESET);
1160 		M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
1161 		nm_bsp_sleep(1);
1162 		retry--;
1163 		if(retry) goto _RETRY_;
1164 	}
1165 
1166 	return result;
1167 }
1168 
1169 /********************************************
1170 
1171 	Bus interfaces
1172 
1173 ********************************************/
1174 
spi_init_pkt_sz(void)1175 static void spi_init_pkt_sz(void)
1176 {
1177 	uint32 val32;
1178 
1179 	/* Make sure SPI max. packet size fits the defined DATA_PKT_SZ.  */
1180 	val32 = nm_spi_read_reg(SPI_BASE+0x24);
1181 	val32 &= ~(0x7 << 4);
1182 	switch(DATA_PKT_SZ)
1183 	{
1184 	case 256:  val32 |= (0 << 4); break;
1185 	case 512:  val32 |= (1 << 4); break;
1186 	case 1024: val32 |= (2 << 4); break;
1187 	case 2048: val32 |= (3 << 4); break;
1188 	case 4096: val32 |= (4 << 4); break;
1189 	case 8192: val32 |= (5 << 4); break;
1190 
1191 	}
1192 	nm_spi_write_reg(SPI_BASE+0x24, val32);
1193 }
1194 
nm_spi_reset(void)1195 sint8 nm_spi_reset(void)
1196 {
1197 	spi_cmd(CMD_RESET, 0, 0, 0, 0);
1198 	spi_cmd_rsp(CMD_RESET);
1199 	return M2M_SUCCESS;
1200 }
1201 
1202 /*
1203 *	@fn		nm_spi_init
1204 *	@brief	Initialize the SPI
1205 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1206 *	@author	M. Abdelmawla
1207 *	@date	11 July 2012
1208 *	@version	1.0
1209 */
nm_spi_init(void)1210 sint8 nm_spi_init(void)
1211 {
1212 	uint32 chipid;
1213 	uint32 reg = 0;
1214 
1215 
1216 	/**
1217 		configure protocol
1218 	**/
1219 	gu8Crc_off = 0;
1220 
1221 	// TODO: We can remove the CRC trials if there is a definite way to reset
1222 	// the SPI to it's initial value.
1223 	if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)) {
1224 		/* Read failed. Try with CRC off. This might happen when module
1225 		is removed but chip isn't reset*/
1226 		gu8Crc_off = 1;
1227 		M2M_ERR("[nmi spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
1228 		if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)){
1229 			// Reaad failed with both CRC on and off, something went bad
1230 			M2M_ERR( "[nmi spi]: Failed internal read protocol...\n");
1231 			return 0;
1232 		}
1233 	}
1234 	if(gu8Crc_off == 0)
1235 	{
1236 		reg &= ~0xc;	/* disable crc checking */
1237 		reg &= ~0x70;
1238 		reg |= (0x5 << 4);
1239 		if (!spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg)) {
1240 			M2M_ERR( "[nmi spi]: Failed internal write protocol reg...\n");
1241 			return 0;
1242 		}
1243 		gu8Crc_off = 1;
1244 	}
1245 
1246 	/**
1247 		make sure can read back chip id correctly
1248 	**/
1249 	if (!spi_read_reg(0x1000, &chipid)) {
1250 		M2M_ERR("[nmi spi]: Fail cmd read chip id...\n");
1251 		return M2M_ERR_BUS_FAIL;
1252 	}
1253 
1254 	M2M_DBG("[nmi spi]: chipid (%08x)\n", (unsigned int)chipid);
1255 	spi_init_pkt_sz();
1256 
1257 
1258 	return M2M_SUCCESS;
1259 }
1260 
1261 /*
1262 *	@fn		nm_spi_init
1263 *	@brief	DeInitialize the SPI
1264 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1265 *	@author	Samer Sarhan
1266 *	@date	27 Feb 2015
1267 *	@version	1.0
1268 */
nm_spi_deinit(void)1269 sint8 nm_spi_deinit(void)
1270 {
1271 	gu8Crc_off = 0;
1272 	return M2M_SUCCESS;
1273 }
1274 
1275 /*
1276 *	@fn		nm_spi_read_reg
1277 *	@brief	Read register
1278 *	@param [in]	u32Addr
1279 *				Register address
1280 *	@return	Register value
1281 *	@author	M. Abdelmawla
1282 *	@date	11 July 2012
1283 *	@version	1.0
1284 */
nm_spi_read_reg(uint32 u32Addr)1285 uint32 nm_spi_read_reg(uint32 u32Addr)
1286 {
1287 	uint32 u32Val;
1288 
1289 	spi_read_reg(u32Addr, &u32Val);
1290 
1291 	return u32Val;
1292 }
1293 
1294 /*
1295 *	@fn		nm_spi_read_reg_with_ret
1296 *	@brief	Read register with error code return
1297 *	@param [in]	u32Addr
1298 *				Register address
1299 *	@param [out]	pu32RetVal
1300 *				Pointer to u32 variable used to return the read value
1301 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1302 *	@author	M. Abdelmawla
1303 *	@date	11 July 2012
1304 *	@version	1.0
1305 */
nm_spi_read_reg_with_ret(uint32 u32Addr,uint32 * pu32RetVal)1306 sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
1307 {
1308 	sint8 s8Ret;
1309 
1310 	s8Ret = spi_read_reg(u32Addr,pu32RetVal);
1311 
1312 	if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1313 	else s8Ret = M2M_ERR_BUS_FAIL;
1314 
1315 	return s8Ret;
1316 }
1317 
1318 /*
1319 *	@fn		nm_spi_write_reg
1320 *	@brief	write register
1321 *	@param [in]	u32Addr
1322 *				Register address
1323 *	@param [in]	u32Val
1324 *				Value to be written to the register
1325 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1326 *	@author	M. Abdelmawla
1327 *	@date	11 July 2012
1328 *	@version	1.0
1329 */
nm_spi_write_reg(uint32 u32Addr,uint32 u32Val)1330 sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val)
1331 {
1332 	sint8 s8Ret;
1333 
1334 	s8Ret = spi_write_reg(u32Addr, u32Val);
1335 
1336 	if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1337 	else s8Ret = M2M_ERR_BUS_FAIL;
1338 
1339 	return s8Ret;
1340 }
1341 
1342 /*
1343 *	@fn		nm_spi_read_block
1344 *	@brief	Read block of data
1345 *	@param [in]	u32Addr
1346 *				Start address
1347 *	@param [out]	puBuf
1348 *				Pointer to a buffer used to return the read data
1349 *	@param [in]	u16Sz
1350 *				Number of bytes to read. The buffer size must be >= u16Sz
1351 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1352 *	@author	M. Abdelmawla
1353 *	@date	11 July 2012
1354 *	@version	1.0
1355 */
nm_spi_read_block(uint32 u32Addr,uint8 * puBuf,uint16 u16Sz)1356 sint8 nm_spi_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
1357 {
1358 	sint8 s8Ret;
1359 
1360 	s8Ret = nm_spi_read(u32Addr, puBuf, u16Sz);
1361 
1362 	if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1363 	else s8Ret = M2M_ERR_BUS_FAIL;
1364 
1365 	return s8Ret;
1366 }
1367 
1368 /*
1369 *	@fn		nm_spi_write_block
1370 *	@brief	Write block of data
1371 *	@param [in]	u32Addr
1372 *				Start address
1373 *	@param [in]	puBuf
1374 *				Pointer to the buffer holding the data to be written
1375 *	@param [in]	u16Sz
1376 *				Number of bytes to write. The buffer size must be >= u16Sz
1377 *	@return	M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
1378 *	@author	M. Abdelmawla
1379 *	@date	11 July 2012
1380 *	@version	1.0
1381 */
nm_spi_write_block(uint32 u32Addr,uint8 * puBuf,uint16 u16Sz)1382 sint8 nm_spi_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
1383 {
1384 	sint8 s8Ret;
1385 
1386 	s8Ret = nm_spi_write(u32Addr, puBuf, u16Sz);
1387 
1388 	if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
1389 	else s8Ret = M2M_ERR_BUS_FAIL;
1390 
1391 	return s8Ret;
1392 }
1393 
1394 #endif
1395