• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <linux/module.h>
2 #include <linux/init.h>
3 #include <linux/kernel.h>
4 #include <linux/fs.h>
5 #include <linux/slab.h>
6 #include <linux/types.h>
7 #include <linux/cdev.h>
8 #include <linux/uaccess.h>
9 #include <linux/device.h>
10 #include <linux/spi/spi.h>
11 
12 #include "linux_wlan_common.h"
13 #include "linux_wlan_spi.h"
14 
15 #define USE_SPI_DMA     0       /* johnny add */
16 
17 #ifdef WILC_ASIC_A0
18  #if defined(PLAT_PANDA_ES_OMAP4460)
19   #define MIN_SPEED 12000000
20   #define MAX_SPEED 24000000
21  #elif defined(PLAT_WMS8304)
22   #define MIN_SPEED 12000000
23   #define MAX_SPEED 24000000 /* 4000000 */
24  #elif defined(CUSTOMER_PLATFORM)
25 /*
26   TODO : define Clock speed under 48M.
27  *
28  * ex)
29  * #define MIN_SPEED 24000000
30  * #define MAX_SPEED 48000000
31  */
32  #else
33   #define MIN_SPEED 24000000
34   #define MAX_SPEED 48000000
35  #endif
36 #else /* WILC_ASIC_A0 */
37 /* Limit clk to 6MHz on FPGA. */
38  #define MIN_SPEED 6000000
39  #define MAX_SPEED 6000000
40 #endif /* WILC_ASIC_A0 */
41 
42 static u32 SPEED = MIN_SPEED;
43 
44 struct spi_device *wilc_spi_dev;
45 void linux_spi_deinit(void *vp);
46 
wilc_bus_probe(struct spi_device * spi)47 static int __init wilc_bus_probe(struct spi_device *spi)
48 {
49 
50 	PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias);
51 	PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz);
52 	wilc_spi_dev = spi;
53 
54 	printk("Driver Initializing success\n");
55 	return 0;
56 }
57 
wilc_bus_remove(struct spi_device * spi)58 static int __exit wilc_bus_remove(struct spi_device *spi)
59 {
60 
61 	return 0;
62 }
63 
64 #ifdef CONFIG_OF
65 static const struct of_device_id wilc1000_of_match[] = {
66 	{ .compatible = "atmel,wilc_spi", },
67 	{}
68 };
69 MODULE_DEVICE_TABLE(of, wilc1000_of_match);
70 #endif
71 
72 struct spi_driver wilc_bus __refdata = {
73 	.driver = {
74 		.name = MODALIAS,
75 #ifdef CONFIG_OF
76 		.of_match_table = wilc1000_of_match,
77 #endif
78 	},
79 	.probe =  wilc_bus_probe,
80 	.remove = __exit_p(wilc_bus_remove),
81 };
82 
83 
linux_spi_deinit(void * vp)84 void linux_spi_deinit(void *vp)
85 {
86 
87 	spi_unregister_driver(&wilc_bus);
88 
89 	SPEED = MIN_SPEED;
90 	PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED);
91 
92 }
93 
94 
95 
linux_spi_init(void * vp)96 int linux_spi_init(void *vp)
97 {
98 	int ret = 1;
99 	static int called;
100 
101 
102 	if (called == 0) {
103 		called++;
104 		ret = spi_register_driver(&wilc_bus);
105 	}
106 
107 	/* change return value to match WILC interface */
108 	(ret < 0) ? (ret = 0) : (ret = 1);
109 
110 	return ret;
111 }
112 
113 #if defined(PLAT_WMS8304)
114 #define TXRX_PHASE_SIZE (4096)
115 #endif
116 
117 #if defined(TXRX_PHASE_SIZE)
118 
linux_spi_write(u8 * b,u32 len)119 int linux_spi_write(u8 *b, u32 len)
120 {
121 	int ret;
122 
123 	if (len > 0 && b != NULL) {
124 		int i = 0;
125 		int blk = len / TXRX_PHASE_SIZE;
126 		int remainder = len % TXRX_PHASE_SIZE;
127 
128 		char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
129 		if (!r_buffer)
130 			return -ENOMEM;
131 
132 		if (blk) {
133 			while (i < blk)	{
134 				struct spi_message msg;
135 				struct spi_transfer tr = {
136 					.tx_buf = b + (i * TXRX_PHASE_SIZE),
137 					.len = TXRX_PHASE_SIZE,
138 					.speed_hz = SPEED,
139 					.bits_per_word = 8,
140 					.delay_usecs = 0,
141 				};
142 
143 				tr.rx_buf = r_buffer;
144 
145 				memset(&msg, 0, sizeof(msg));
146 				spi_message_init(&msg);
147 				msg.spi = wilc_spi_dev;
148 				msg.is_dma_mapped = USE_SPI_DMA;
149 
150 				spi_message_add_tail(&tr, &msg);
151 				ret = spi_sync(wilc_spi_dev, &msg);
152 				if (ret < 0) {
153 					PRINT_ER("SPI transaction failed\n");
154 				}
155 				i++;
156 
157 			}
158 		}
159 		if (remainder) {
160 			struct spi_message msg;
161 			struct spi_transfer tr = {
162 				.tx_buf = b + (blk * TXRX_PHASE_SIZE),
163 				.len = remainder,
164 				.speed_hz = SPEED,
165 				.bits_per_word = 8,
166 				.delay_usecs = 0,
167 			};
168 			tr.rx_buf = r_buffer;
169 
170 			memset(&msg, 0, sizeof(msg));
171 			spi_message_init(&msg);
172 			msg.spi = wilc_spi_dev;
173 			msg.is_dma_mapped = USE_SPI_DMA;                                /* rachel */
174 
175 			spi_message_add_tail(&tr, &msg);
176 			ret = spi_sync(wilc_spi_dev, &msg);
177 			if (ret < 0) {
178 				PRINT_ER("SPI transaction failed\n");
179 			}
180 		}
181 		kfree(r_buffer);
182 	} else {
183 		PRINT_ER("can't write data with the following length: %d\n", len);
184 		PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
185 		ret = -1;
186 	}
187 
188 	/* change return value to match WILC interface */
189 	(ret < 0) ? (ret = 0) : (ret = 1);
190 
191 	return ret;
192 
193 }
194 
195 #else
linux_spi_write(u8 * b,u32 len)196 int linux_spi_write(u8 *b, u32 len)
197 {
198 
199 	int ret;
200 	struct spi_message msg;
201 
202 	if (len > 0 && b != NULL) {
203 		struct spi_transfer tr = {
204 			.tx_buf = b,
205 			.len = len,
206 			.speed_hz = SPEED,
207 			.delay_usecs = 0,
208 		};
209 		char *r_buffer = kzalloc(len, GFP_KERNEL);
210 		if (!r_buffer)
211 			return -ENOMEM;
212 
213 		tr.rx_buf = r_buffer;
214 		PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
215 
216 		memset(&msg, 0, sizeof(msg));
217 		spi_message_init(&msg);
218 /* [[johnny add */
219 		msg.spi = wilc_spi_dev;
220 		msg.is_dma_mapped = USE_SPI_DMA;
221 /* ]] */
222 		spi_message_add_tail(&tr, &msg);
223 
224 		ret = spi_sync(wilc_spi_dev, &msg);
225 		if (ret < 0) {
226 			PRINT_ER("SPI transaction failed\n");
227 		}
228 
229 		kfree(r_buffer);
230 	} else {
231 		PRINT_ER("can't write data with the following length: %d\n", len);
232 		PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
233 		ret = -1;
234 	}
235 
236 	/* change return value to match WILC interface */
237 	(ret < 0) ? (ret = 0) : (ret = 1);
238 
239 
240 	return ret;
241 }
242 
243 #endif
244 
245 #if defined(TXRX_PHASE_SIZE)
246 
linux_spi_read(u8 * rb,u32 rlen)247 int linux_spi_read(u8 *rb, u32 rlen)
248 {
249 	int ret;
250 
251 	if (rlen > 0) {
252 		int i = 0;
253 
254 		int blk = rlen / TXRX_PHASE_SIZE;
255 		int remainder = rlen % TXRX_PHASE_SIZE;
256 
257 		char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
258 		if (!t_buffer)
259 			return -ENOMEM;
260 
261 		if (blk) {
262 			while (i < blk)	{
263 				struct spi_message msg;
264 				struct spi_transfer tr = {
265 					.rx_buf = rb + (i * TXRX_PHASE_SIZE),
266 					.len = TXRX_PHASE_SIZE,
267 					.speed_hz = SPEED,
268 					.bits_per_word = 8,
269 					.delay_usecs = 0,
270 				};
271 				tr.tx_buf = t_buffer;
272 
273 				memset(&msg, 0, sizeof(msg));
274 				spi_message_init(&msg);
275 				msg.spi = wilc_spi_dev;
276 				msg.is_dma_mapped = USE_SPI_DMA;
277 
278 				spi_message_add_tail(&tr, &msg);
279 				ret = spi_sync(wilc_spi_dev, &msg);
280 				if (ret < 0) {
281 					PRINT_ER("SPI transaction failed\n");
282 				}
283 				i++;
284 			}
285 		}
286 		if (remainder) {
287 			struct spi_message msg;
288 			struct spi_transfer tr = {
289 				.rx_buf = rb + (blk * TXRX_PHASE_SIZE),
290 				.len = remainder,
291 				.speed_hz = SPEED,
292 				.bits_per_word = 8,
293 				.delay_usecs = 0,
294 			};
295 			tr.tx_buf = t_buffer;
296 
297 			memset(&msg, 0, sizeof(msg));
298 			spi_message_init(&msg);
299 			msg.spi = wilc_spi_dev;
300 			msg.is_dma_mapped = USE_SPI_DMA;                                /* rachel */
301 
302 			spi_message_add_tail(&tr, &msg);
303 			ret = spi_sync(wilc_spi_dev, &msg);
304 			if (ret < 0) {
305 				PRINT_ER("SPI transaction failed\n");
306 			}
307 		}
308 
309 		kfree(t_buffer);
310 	} else {
311 		PRINT_ER("can't read data with the following length: %u\n", rlen);
312 		ret = -1;
313 	}
314 	/* change return value to match WILC interface */
315 	(ret < 0) ? (ret = 0) : (ret = 1);
316 
317 	return ret;
318 }
319 
320 #else
linux_spi_read(u8 * rb,u32 rlen)321 int linux_spi_read(u8 *rb, u32 rlen)
322 {
323 
324 	int ret;
325 
326 	if (rlen > 0) {
327 		struct spi_message msg;
328 		struct spi_transfer tr = {
329 			.rx_buf = rb,
330 			.len = rlen,
331 			.speed_hz = SPEED,
332 			.delay_usecs = 0,
333 
334 		};
335 		char *t_buffer = kzalloc(rlen, GFP_KERNEL);
336 		if (!t_buffer)
337 			return -ENOMEM;
338 
339 		tr.tx_buf = t_buffer;
340 
341 		memset(&msg, 0, sizeof(msg));
342 		spi_message_init(&msg);
343 /* [[ johnny add */
344 		msg.spi = wilc_spi_dev;
345 		msg.is_dma_mapped = USE_SPI_DMA;
346 /* ]] */
347 		spi_message_add_tail(&tr, &msg);
348 
349 		ret = spi_sync(wilc_spi_dev, &msg);
350 		if (ret < 0) {
351 			PRINT_ER("SPI transaction failed\n");
352 		}
353 		kfree(t_buffer);
354 	} else {
355 		PRINT_ER("can't read data with the following length: %u\n", rlen);
356 		ret = -1;
357 	}
358 	/* change return value to match WILC interface */
359 	(ret < 0) ? (ret = 0) : (ret = 1);
360 
361 	return ret;
362 }
363 
364 #endif
365 
linux_spi_write_read(u8 * wb,u8 * rb,u32 rlen)366 int linux_spi_write_read(u8 *wb, u8 *rb, u32 rlen)
367 {
368 
369 	int ret;
370 
371 	if (rlen > 0) {
372 		struct spi_message msg;
373 		struct spi_transfer tr = {
374 			.rx_buf = rb,
375 			.tx_buf = wb,
376 			.len = rlen,
377 			.speed_hz = SPEED,
378 			.bits_per_word = 8,
379 			.delay_usecs = 0,
380 
381 		};
382 
383 		memset(&msg, 0, sizeof(msg));
384 		spi_message_init(&msg);
385 		msg.spi = wilc_spi_dev;
386 		msg.is_dma_mapped = USE_SPI_DMA;
387 
388 		spi_message_add_tail(&tr, &msg);
389 		ret = spi_sync(wilc_spi_dev, &msg);
390 		if (ret < 0) {
391 			PRINT_ER("SPI transaction failed\n");
392 		}
393 	} else {
394 		PRINT_ER("can't read data with the following length: %u\n", rlen);
395 		ret = -1;
396 	}
397 	/* change return value to match WILC interface */
398 	(ret < 0) ? (ret = 0) : (ret = 1);
399 
400 	return ret;
401 }
402 
linux_spi_set_max_speed(void)403 int linux_spi_set_max_speed(void)
404 {
405 	SPEED = MAX_SPEED;
406 
407 	PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED);
408 	return 1;
409 }
410