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