1eee1d560bc7eac90bf024e1b7480faf0ef836ce
[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                 if (r_buffer)
218                         kfree(r_buffer);
219         } else {
220                 PRINT_ER("can't write data with the following length: %d\n", len);
221                 PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
222                 ret = -1;
223         }
224
225         /* change return value to match WILC interface */
226         (ret < 0) ? (ret = 0) : (ret = 1);
227
228         return ret;
229
230 }
231
232 #else
233 int linux_spi_write(uint8_t *b, uint32_t len)
234 {
235
236         int ret;
237         struct spi_message msg;
238
239         if (len > 0 && b != NULL) {
240                 struct spi_transfer tr = {
241                         .tx_buf = b,
242                         .len = len,
243                         .speed_hz = SPEED,
244                         .delay_usecs = 0,
245                 };
246                 char *r_buffer = kzalloc(len, GFP_KERNEL);
247                 if (!r_buffer) {
248                         PRINT_ER("Failed to allocate memory for r_buffer\n");
249                 }
250                 tr.rx_buf = r_buffer;
251                 PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
252
253                 memset(&msg, 0, sizeof(msg));
254                 spi_message_init(&msg);
255 /* [[johnny add */
256                 msg.spi = wilc_spi_dev;
257                 msg.is_dma_mapped = USE_SPI_DMA;
258 /* ]] */
259                 spi_message_add_tail(&tr, &msg);
260
261                 ret = spi_sync(wilc_spi_dev, &msg);
262                 if (ret < 0) {
263                         PRINT_ER("SPI transaction failed\n");
264                 }
265
266                 kfree(r_buffer);
267         } else {
268                 PRINT_ER("can't write data with the following length: %d\n", len);
269                 PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
270                 ret = -1;
271         }
272
273         /* change return value to match WILC interface */
274         (ret < 0) ? (ret = 0) : (ret = 1);
275
276
277         return ret;
278 }
279
280 #endif
281
282 #if defined (NM73131_0_BOARD)
283
284 int linux_spi_read(unsigned char *rb, unsigned long rlen)
285 {
286
287         int ret;
288
289         if (rlen > 0) {
290                 struct spi_message msg;
291                 struct spi_transfer tr = {
292                         .rx_buf = rb,
293                         .len = rlen,
294                         .speed_hz = SPEED,
295                         .delay_usecs = 0,
296
297                 };
298
299                 spi_message_init(&msg);
300                 spi_message_add_tail(&tr, &msg);
301                 ret = spi_sync(wilc_spi_dev, &msg);
302                 if (ret < 0) {
303                         PRINT_ER("SPI transaction failed\n");
304                 }
305         } else {
306                 PRINT_ER("can't read data with the following length: %ld\n", rlen);
307                 ret = -1;
308         }
309         /* change return value to match WILC interface */
310         (ret < 0) ? (ret = 0) : (ret = 1);
311
312         return ret;
313 }
314
315 #elif defined(TXRX_PHASE_SIZE)
316
317 int linux_spi_read(unsigned char *rb, unsigned long rlen)
318 {
319         int ret;
320
321         if (rlen > 0) {
322                 int i = 0;
323
324                 int blk = rlen / TXRX_PHASE_SIZE;
325                 int remainder = rlen % TXRX_PHASE_SIZE;
326
327                 char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
328                 if (!t_buffer) {
329                         PRINT_ER("Failed to allocate memory for t_buffer\n");
330                 }
331
332                 if (blk) {
333                         while (i < blk) {
334                                 struct spi_message msg;
335                                 struct spi_transfer tr = {
336                                         .rx_buf = rb + (i * TXRX_PHASE_SIZE),
337                                         .len = TXRX_PHASE_SIZE,
338                                         .speed_hz = SPEED,
339                                         .bits_per_word = 8,
340                                         .delay_usecs = 0,
341                                 };
342                                 tr.tx_buf = t_buffer;
343
344                                 memset(&msg, 0, sizeof(msg));
345                                 spi_message_init(&msg);
346                                 msg.spi = wilc_spi_dev;
347                                 msg.is_dma_mapped = USE_SPI_DMA;
348
349                                 spi_message_add_tail(&tr, &msg);
350                                 ret = spi_sync(wilc_spi_dev, &msg);
351                                 if (ret < 0) {
352                                         PRINT_ER("SPI transaction failed\n");
353                                 }
354                                 i++;
355                         }
356                 }
357                 if (remainder) {
358                         struct spi_message msg;
359                         struct spi_transfer tr = {
360                                 .rx_buf = rb + (blk * TXRX_PHASE_SIZE),
361                                 .len = remainder,
362                                 .speed_hz = SPEED,
363                                 .bits_per_word = 8,
364                                 .delay_usecs = 0,
365                         };
366                         tr.tx_buf = t_buffer;
367
368                         memset(&msg, 0, sizeof(msg));
369                         spi_message_init(&msg);
370                         msg.spi = wilc_spi_dev;
371                         msg.is_dma_mapped = USE_SPI_DMA;                                /* rachel */
372
373                         spi_message_add_tail(&tr, &msg);
374                         ret = spi_sync(wilc_spi_dev, &msg);
375                         if (ret < 0) {
376                                 PRINT_ER("SPI transaction failed\n");
377                         }
378                 }
379
380                 if (t_buffer)
381                         kfree(t_buffer);
382         } else {
383                 PRINT_ER("can't read data with the following length: %ld\n", rlen);
384                 ret = -1;
385         }
386         /* change return value to match WILC interface */
387         (ret < 0) ? (ret = 0) : (ret = 1);
388
389         return ret;
390 }
391
392 #else
393 int linux_spi_read(unsigned char *rb, unsigned long rlen)
394 {
395
396         int ret;
397
398         if (rlen > 0) {
399                 struct spi_message msg;
400                 struct spi_transfer tr = {
401                         .rx_buf = rb,
402                         .len = rlen,
403                         .speed_hz = SPEED,
404                         .delay_usecs = 0,
405
406                 };
407                 char *t_buffer = kzalloc(rlen, GFP_KERNEL);
408                 if (!t_buffer) {
409                         PRINT_ER("Failed to allocate memory for t_buffer\n");
410                 }
411                 tr.tx_buf = t_buffer;
412
413                 memset(&msg, 0, sizeof(msg));
414                 spi_message_init(&msg);
415 /* [[ johnny add */
416                 msg.spi = wilc_spi_dev;
417                 msg.is_dma_mapped = USE_SPI_DMA;
418 /* ]] */
419                 spi_message_add_tail(&tr, &msg);
420
421                 ret = spi_sync(wilc_spi_dev, &msg);
422                 if (ret < 0) {
423                         PRINT_ER("SPI transaction failed\n");
424                 }
425                 kfree(t_buffer);
426         } else {
427                 PRINT_ER("can't read data with the following length: %ld\n", rlen);
428                 ret = -1;
429         }
430         /* change return value to match WILC interface */
431         (ret < 0) ? (ret = 0) : (ret = 1);
432
433         return ret;
434 }
435
436 #endif
437
438 int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen)
439 {
440
441         int ret;
442
443         if (rlen > 0) {
444                 struct spi_message msg;
445                 struct spi_transfer tr = {
446                         .rx_buf = rb,
447                         .tx_buf = wb,
448                         .len = rlen,
449                         .speed_hz = SPEED,
450                         .bits_per_word = 8,
451                         .delay_usecs = 0,
452
453                 };
454
455                 memset(&msg, 0, sizeof(msg));
456                 spi_message_init(&msg);
457                 msg.spi = wilc_spi_dev;
458                 msg.is_dma_mapped = USE_SPI_DMA;
459
460                 spi_message_add_tail(&tr, &msg);
461                 ret = spi_sync(wilc_spi_dev, &msg);
462                 if (ret < 0) {
463                         PRINT_ER("SPI transaction failed\n");
464                 }
465         } else {
466                 PRINT_ER("can't read data with the following length: %d\n", rlen);
467                 ret = -1;
468         }
469         /* change return value to match WILC interface */
470         (ret < 0) ? (ret = 0) : (ret = 1);
471
472         return ret;
473 }
474
475 int linux_spi_set_max_speed(void)
476 {
477         SPEED = MAX_SPEED;
478
479         PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED);
480         return 1;
481 }