Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / drivers / cmmb / siano / smsspilog.c
1 /****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2008, Uri Shkolnik
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21 /*!
22         \file   spibusdrv.c
23
24         \brief  spi bus driver module
25
26         This file contains implementation of the spi bus driver.
27 */
28
29 #include <linux/init.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/moduleparam.h>
33 #include <linux/device.h>
34 #include <linux/dma-mapping.h>
35 #include <linux/platform_device.h>
36 #include <linux/delay.h>
37 #include <mach/gpio.h>
38 #include "smscoreapi.h"
39 #include "smsdbg_prn.h"
40 #include "smsspicommon.h"
41 #include "smsspiphy.h"
42 #include <linux/spi/spi.h>
43 #if     SIANO_HALFDUPLEX
44 #include <linux/kthread.h>//hzb@20100902
45 #endif
46
47 #define ANDROID_2_6_25
48 #ifdef ANDROID_2_6_25
49 #include <linux/workqueue.h>
50 #endif
51
52 #define DRV_NAME        "siano1186"
53
54
55 #define SMS_INTR_PIN                    19  /* 0 for nova sip, 26 for vega in the default, 19 in the reality */
56 #define TX_BUFFER_SIZE                  0x200
57 #if 0
58 #define RX_BUFFER_SIZE                  (0x1000 + SPI_PACKET_SIZE + 0x100)
59 #define NUM_RX_BUFFERS                   64 // change to 128
60 #else
61 #define RX_BUFFER_SIZE                  (0x10000 + SPI_PACKET_SIZE + 0x100)
62 #define NUM_RX_BUFFERS                   4 // change to 128
63 #endif
64
65
66 u32 g_Sms_Int_Counter=0;
67 u32 g_Sms_MsgFound_Counter=0;
68
69 extern unsigned  long   u_irq_count;
70
71 struct _spi_device_st {
72         struct _spi_dev dev;
73         void *phy_dev;
74
75         struct completion write_operation;
76         struct list_head tx_queue;
77         int allocatedPackets;
78         int padding_allowed;
79         char *rxbuf;
80         dma_addr_t rxbuf_phy_addr;
81
82         struct smscore_device_t *coredev;
83         struct list_head txqueue;
84         char *txbuf;
85         dma_addr_t txbuf_phy_addr;
86 };
87
88 struct _smsspi_txmsg {
89         struct list_head node;  /*! internal management */
90         void *buffer;
91         size_t size;
92         int alignment;
93         int add_preamble;
94         struct completion completion;
95         void (*prewrite) (void *);
96         void (*postwrite) (void *);
97 };
98
99 struct _spi_device_st *spi_dev;
100
101 static int spi_resume_fail = 0 ;
102 static int spi_suspended   = 0 ;
103
104
105
106 static void spi_worker_thread(void *arg);
107
108 #if SIANO_HALFDUPLEX
109 int g_IsTokenOwned=false;
110 int g_IsTokenEnable=false;
111 struct semaphore        HalfDuplexSemaphore;
112 struct task_struct      *SPI_Thread;
113 static int SPI_Thread_IsStop=0;
114 #define MSG_HDR_FLAG_STATIC_MSG         0x0001  // Message is dynamic when this bit is '0'
115 #else
116 static DECLARE_WORK(spi_work_queue, (void *)spi_worker_thread);
117 #endif
118
119 static u8 smsspi_preamble[] = { 0xa5, 0x5a, 0xe7, 0x7e };
120
121 // to support dma 16byte burst size
122 static u8 smsspi_startup[] = { 0,0,0,0,0,0,0,0,0, 0, 0xde, 0xc1, 0xa5, 0x51, 0xf1, 0xed };
123
124 //static u32 default_type = SMS_NOVA_A0;
125 static u32 default_type = SMS_VEGA;
126 static u32 intr_pin = SMS_INTR_PIN;
127
128 module_param(default_type, int, 0644);
129 MODULE_PARM_DESC(default_type, "default board type.");
130
131 module_param(intr_pin, int, 0644);
132 MODULE_PARM_DESC(intr_pin, "interrupt pin number.");
133
134 /******************************************/
135
136 void spilog_panic_print(void)
137 {
138     if(spi_dev)
139     {
140         printk("spidev rxbuf_phy_addr =[0x%x]\n",spi_dev->rxbuf_phy_addr) ;
141         printk("spidev txbufphy_addr  =[0x%x]\n",spi_dev->txbuf_phy_addr) ;
142         printk("spidev TX_BUFFER_SIZE = [0x%x]\n",TX_BUFFER_SIZE) ;
143     }
144 }
145
146 static void spi_worker_thread(void *arg)
147 {
148         struct _spi_device_st *spi_device = spi_dev;
149         struct _smsspi_txmsg *msg = NULL;
150         struct _spi_msg txmsg;
151         int i=0;
152
153
154 #if SIANO_HALFDUPLEX
155         static u8 s_SpiTokenMsgBuf[256] = {0};
156         const u8 g_PreambleBytes[4] = { 0xa5, 0x5a, 0xe7, 0x7e};
157         struct SmsMsgHdr_ST s_SpiTokenSendMsg = {MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE, 0, 11, sizeof(struct SmsMsgHdr_ST), MSG_HDR_FLAG_STATIC_MSG};
158
159         memcpy( s_SpiTokenMsgBuf, g_PreambleBytes, sizeof(g_PreambleBytes) );
160         memcpy( &s_SpiTokenMsgBuf[sizeof(g_PreambleBytes)], &s_SpiTokenSendMsg, sizeof(s_SpiTokenSendMsg) );
161
162         PDEBUG("worker start\n");
163         
164         do {
165                 mdelay(3);
166                 if (g_IsTokenEnable){
167                         if (g_IsTokenOwned){
168                                 if (!msg && !list_empty(&spi_device->txqueue))
169                                         msg = (struct _smsspi_txmsg *)list_entry(spi_device->txqueue.next, struct _smsspi_txmsg, node);
170
171                                 if (!msg) {
172                                         // TX queue empty - give up token
173                                         sms_debug("TX queue empty - give up token\n");
174                                         g_IsTokenOwned = false;
175                                         txmsg.len = 256;
176                                         txmsg.buf = s_SpiTokenMsgBuf;
177                                         txmsg.buf_phy_addr = 0;//zzf spi_device->txbuf_phy_addr;
178                                         smsspi_common_transfer_msg(&spi_device->dev,&txmsg, 0);
179                                 } else {
180                                         sms_debug("msg is not null\n");
181                                         if (msg->add_preamble) {// need to add preamble
182                                                 txmsg.len = min(msg->size + sizeof(smsspi_preamble),(size_t) TX_BUFFER_SIZE);
183                                                 txmsg.buf = spi_device->txbuf;
184                                                 txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
185                                                 memcpy(txmsg.buf, smsspi_preamble, sizeof(smsspi_preamble));
186                                                 memcpy(&txmsg.buf[sizeof(smsspi_preamble)],msg->buffer,txmsg.len - sizeof(smsspi_preamble));
187                                                 msg->add_preamble = 0;
188                                                 msg->buffer = (char*)msg->buffer + txmsg.len - sizeof(smsspi_preamble);
189                                                 msg->size -= txmsg.len - sizeof(smsspi_preamble);
190                                                 /* zero out the rest of aligned buffer */
191                                                 memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
192                                                 if(spi_resume_fail||spi_suspended) 
193                                                 {
194                                                         sms_err(KERN_EMERG " SMS1180: spi failed\n");
195                                                 } else {
196                                                         smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 1);
197                                                 }
198                                         } else {// donot need to add preamble
199                                                 txmsg.len = min(msg->size, (size_t) TX_BUFFER_SIZE);
200                                                 txmsg.buf = spi_device->txbuf;
201                                                 txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
202                                                 memcpy(txmsg.buf, msg->buffer, txmsg.len);
203                                 
204                                                 msg->buffer = (char*)msg->buffer + txmsg.len;
205                                                 msg->size -= txmsg.len;
206                                                 /* zero out the rest of aligned buffer */
207                                                 memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
208                                                 if(spi_resume_fail||spi_suspended){
209                                                         sms_err(KERN_EMERG " SMS1180: spi failed\n");
210                                                 } else {
211                                                         smsspi_common_transfer_msg(&spi_device->dev,&txmsg, 0);
212                                                 }
213                                         }
214                                 } 
215
216                         } else {
217                                 if(0)//spi_resume_fail||spi_suspended) 
218                                 {
219                                         sms_err(KERN_EMERG " SMS1180: spi failed\n") ;    
220                                 } else {
221                                         sms_debug(KERN_EMERG "[SMS]spi_worker_thread token enable wait HalfDuplexSemaphore\n") ;
222                                         if (SPI_Thread_IsStop)
223                                                 return -EINTR;
224                                         if (down_interruptible(&HalfDuplexSemaphore))
225                                                 return -EINTR;
226                                         sms_debug(KERN_EMERG "[SMS]spi_worker_thread token enable get HalfDuplexSemaphore\n") ;
227                                         smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
228                                 }
229                         }
230                 }else {
231                         sms_debug(KERN_EMERG "[SMS]spi_worker_thread token disable wait HalfDuplexSemaphore\n") ;
232                         if (SPI_Thread_IsStop)
233                                         return -EINTR;
234                         if (down_interruptible(&HalfDuplexSemaphore))
235                                         return -EINTR;
236                         sms_debug(KERN_EMERG "[SMS]spi_worker_thread token disable get HalfDuplexSemaphore\n") ;
237                         if (!msg && !list_empty(&spi_device->txqueue))
238                                 msg = (struct _smsspi_txmsg *)list_entry(spi_device->txqueue.next, struct _smsspi_txmsg, node);
239                         if (msg) {
240                                 if (msg->add_preamble) {// need to add preamble
241                                         txmsg.len = min(msg->size + sizeof(smsspi_preamble),(size_t) TX_BUFFER_SIZE);
242                                         txmsg.buf = spi_device->txbuf;
243                                         txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
244                                         memcpy(txmsg.buf, smsspi_preamble, sizeof(smsspi_preamble));
245                                         memcpy(&txmsg.buf[sizeof(smsspi_preamble)],msg->buffer,txmsg.len - sizeof(smsspi_preamble));
246                                         msg->add_preamble = 0;
247                                         msg->buffer = (char*)msg->buffer + txmsg.len - sizeof(smsspi_preamble);
248                                         msg->size -= txmsg.len - sizeof(smsspi_preamble);
249                                         /* zero out the rest of aligned buffer */
250                                         memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
251                                         if(spi_resume_fail||spi_suspended) 
252                                         {
253                                                 sms_err(KERN_EMERG " SMS1180: spi failed\n");
254                                         } else {
255                                                 smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 1);
256                                         }
257                                 } else {// donot need to add preamble
258                                         txmsg.len = min(msg->size, (size_t) TX_BUFFER_SIZE);
259                                         txmsg.buf = spi_device->txbuf;
260                                         txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
261                                         memcpy(txmsg.buf, msg->buffer, txmsg.len);
262                         
263                                         msg->buffer = (char*)msg->buffer + txmsg.len;
264                                         msg->size -= txmsg.len;
265                                         /* zero out the rest of aligned buffer */
266                                         memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
267                                         if(spi_resume_fail||spi_suspended) 
268                                         {
269                                                 sms_err(KERN_EMERG " SMS1180: spi failed\n");
270                                         } else {
271                                                 smsspi_common_transfer_msg(&spi_device->dev,&txmsg, 0);
272                                         }
273                                 }
274                         } else {
275                                 if(0)//spi_resume_fail||spi_suspended) 
276                                 {
277                                         sms_err(KERN_EMERG " SMS1180: spi failed\n") ;    
278                                 } else {
279                                         smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
280                                 }
281                         }
282
283                 }
284                         /* if there was write, have we finished ? */
285                 if (msg && !msg->size) {
286                         /* call postwrite call back */
287                         if (msg->postwrite)
288                                 msg->postwrite(spi_device);
289
290                         list_del(&msg->node);
291                         complete(&msg->completion);
292                         msg = NULL;
293                 }
294                 /* if there was read, did we read anything ? */
295
296
297                 //check if we lost msg, if so, recover
298                 if(g_Sms_MsgFound_Counter < g_Sms_Int_Counter){
299                 //      sms_err("we lost msg, probably becouse dma time out\n");
300                         //for(i=0; i<16; i++)
301                         {
302                                 //smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
303                         }
304                         g_Sms_MsgFound_Counter = g_Sms_Int_Counter;
305                 }
306         }while(1);
307 #else
308         PDEBUG("worker start\n");
309         do{
310                 mdelay(6);
311         /* do we have a msg to write ? */
312                 if (!msg && !list_empty(&spi_device->txqueue))
313                         msg = (struct _smsspi_txmsg *)list_entry(spi_device->txqueue.next, struct _smsspi_txmsg, node);
314         if (msg) {
315                         if (msg->add_preamble) {// need to add preamble
316                                 txmsg.len = min(msg->size + sizeof(smsspi_preamble),(size_t) TX_BUFFER_SIZE);
317                                 txmsg.buf = spi_device->txbuf;
318                                 txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
319                                 memcpy(txmsg.buf, smsspi_preamble, sizeof(smsspi_preamble));
320                                 memcpy(&txmsg.buf[sizeof(smsspi_preamble)],msg->buffer,txmsg.len - sizeof(smsspi_preamble));
321                                 msg->add_preamble = 0;
322                                 msg->buffer = (char*)msg->buffer + txmsg.len - sizeof(smsspi_preamble);
323                                 msg->size -= txmsg.len - sizeof(smsspi_preamble);
324                                 /* zero out the rest of aligned buffer */
325                                 memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
326                 if(spi_resume_fail||spi_suspended) 
327                 {
328                     sms_err(KERN_EMERG " SMS1180: spi failed\n");
329                 } else {
330                     smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 1);
331                 }
332                         } else {// donot need to add preamble
333                                 txmsg.len = min(msg->size, (size_t) TX_BUFFER_SIZE);
334                                 txmsg.buf = spi_device->txbuf;
335                                 txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
336                                 memcpy(txmsg.buf, msg->buffer, txmsg.len);
337
338                                 msg->buffer = (char*)msg->buffer + txmsg.len;
339                                 msg->size -= txmsg.len;
340                                 /* zero out the rest of aligned buffer */
341                                 memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len);
342                 if(spi_resume_fail||spi_suspended) 
343                 {
344                     sms_err(KERN_EMERG " SMS1180: spi failed\n");
345                 } else {
346                     smsspi_common_transfer_msg(&spi_device->dev,&txmsg, 0);
347                 }
348                         }
349                 } else {
350             if(spi_resume_fail||spi_suspended) 
351             {
352                 sms_err(KERN_EMERG " SMS1180: spi failed\n") ;     
353             } else {
354                 smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
355             }
356         }
357
358                 /* if there was write, have we finished ? */
359                 if (msg && !msg->size) {
360                         /* call postwrite call back */
361                         if (msg->postwrite)
362                                 msg->postwrite(spi_device);
363
364                         list_del(&msg->node);
365                         complete(&msg->completion);
366                         msg = NULL;
367                 }
368                 /* if there was read, did we read anything ? */
369
370
371                 //check if we lost msg, if so, recover
372                 if(g_Sms_MsgFound_Counter < g_Sms_Int_Counter)
373                 {
374                         sms_err("we lost msg, probably becouse dma time out\n");
375                         //for(i=0; i<16; i++)
376                         {
377                                 //smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
378                         }
379                         g_Sms_MsgFound_Counter = g_Sms_Int_Counter;
380                 }
381         } while (!list_empty(&spi_device->txqueue) || msg);
382 #endif
383 }
384
385 unsigned  long u_msgres_count =0;
386 static void msg_found(void *context, void *buf, int offset, int len)
387 {
388         struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
389         struct smscore_buffer_t *cb =
390             (struct smscore_buffer_t
391              *)(container_of(buf, struct smscore_buffer_t, p));
392
393     g_Sms_MsgFound_Counter++;
394     u_msgres_count ++;
395     
396     sms_debug("Msg_found count = %d\n", u_msgres_count);
397     //printk("Msg_found count = %d\n", u_msgres_count);
398
399     if(len > RX_BUFFER_SIZE || offset >RX_BUFFER_SIZE )
400     {
401         sms_debug("SMS1180: msg rx over,len=0x%x,offset=0x%x\n",len,offset ) ;
402         sms_debug("SMS1180: cb->p = [0x%x]\n",(unsigned int) cb->p) ;
403         sms_debug("SMS1180: cb->phys=[0x%x]\n",(unsigned int) cb->phys) ;
404     } 
405     
406         cb->offset = offset;
407         cb->size = len;
408
409         smscore_onresponse(spi_device->coredev, cb);
410
411
412 }
413
414 static void smsspi_int_handler(void *context)
415 {
416         g_Sms_Int_Counter++;
417     
418     if(spi_resume_fail||spi_suspended) 
419     {
420         sms_err(KERN_EMERG " SMS1180: spi failed\n") ;
421         return ;                       
422     }
423 #if SIANO_HALFDUPLEX
424         up(&HalfDuplexSemaphore);
425         sms_debug(KERN_EMERG "[SMS]smsspi_int_handler send HalfDuplexSemaphore@intr\n") ;
426 #else
427         schedule_work(&spi_work_queue);
428 #endif
429 }
430
431
432
433 static int smsspi_queue_message_and_wait(struct _spi_device_st *spi_device,
434                                          struct _smsspi_txmsg *msg)
435 {
436     init_completion(&msg->completion);
437         list_add_tail(&msg->node, &spi_device->txqueue);
438 #if SIANO_HALFDUPLEX
439         if(!g_IsTokenEnable){
440                 sms_debug(KERN_EMERG "[SMS]smsspi_queue_message_and_wait token disable send HalfDuplexSemaphore@writemsg\n") ;
441                 up(&HalfDuplexSemaphore);
442         } else {
443                 sms_debug(KERN_EMERG "[SMS]smsspi_queue_message_and_wait send HalfDuplexSemaphore\n") ;
444         }
445 #else
446         schedule_work(&spi_work_queue);
447 #endif
448         wait_for_completion(&msg->completion);
449         return 0;
450 }
451
452
453 static int smsspi_SetIntLine(void *context)
454 {
455         struct _Msg {
456                 struct SmsMsgHdr_ST hdr;
457                 u32 data[3];
458         } Msg = {
459                 {
460                 MSG_SMS_SPI_INT_LINE_SET_REQ, 0, HIF_TASK,
461                             sizeof(struct _Msg), 0}, {
462                 0, intr_pin, 1000}
463         };
464         struct _smsspi_txmsg msg;
465
466         PDEBUG("Sending SPI Set Interrupt command sequence\n");
467
468         msg.buffer = &Msg;
469         msg.size = sizeof(Msg);
470         msg.alignment = SPI_PACKET_SIZE;
471         msg.add_preamble = 1;
472         msg.prewrite = NULL;
473         msg.postwrite = NULL;   /* smsspiphy_restore_clock; */
474         smsspi_queue_message_and_wait(context, &msg);
475         return 0;
476 }
477
478
479 static int smsspi_preload(void *context)
480 {
481         struct _smsspi_txmsg msg;
482         struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
483     int ret;
484
485         prepareForFWDnl(spi_device->phy_dev);
486         PDEBUG("Sending SPI init sequence\n");
487
488
489         msg.buffer = smsspi_startup;
490         msg.size = sizeof(smsspi_startup);
491         msg.alignment = 4;
492         msg.add_preamble = 0;
493         msg.prewrite = NULL;    /* smsspiphy_reduce_clock; */
494         msg.postwrite = NULL;
495
496     printk(KERN_EMERG "smsmdtv: call smsspi_queue_message_and_wait\n") ;
497         smsspi_queue_message_and_wait(context, &msg);
498
499         ret = smsspi_SetIntLine(context);
500         sms_info("smsspi_preload set int line ret = 0x%x",ret);
501     //return ret;
502         return 0;
503
504 }
505
506
507 static int smsspi_postload(void *context)
508 {
509         struct _Msg {
510                 struct SmsMsgHdr_ST hdr;
511                 u32 data[1];
512         } Msg = {
513                 {
514                 MSG_SMS_SET_PERIODIC_STATS_REQ, 0, HIF_TASK,
515                             sizeof(struct _Msg), 0}, {
516                 1}
517         };
518         struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
519         struct _smsspi_txmsg msg;
520
521         sms_debug("Sending Period Statistics Req\n");
522     
523     //This function just speed up the SPI clock
524         fwDnlComplete(spi_device->phy_dev, 0);
525         msg.buffer = &Msg;
526         msg.size = sizeof(Msg);
527         msg.alignment = SPI_PACKET_SIZE;
528         msg.add_preamble = 1;
529         msg.prewrite = NULL;
530         msg.postwrite = NULL;   /* smsspiphy_restore_clock; */
531
532         g_Sms_Int_Counter=0;
533         g_Sms_Int_Counter=0;
534
535         u_irq_count = 0;
536
537         return 0;
538 }
539
540
541 static int smsspi_write(void *context, void *txbuf, size_t len)
542 {
543         struct _smsspi_txmsg msg;
544
545         msg.buffer = txbuf;
546         msg.size = len;
547         msg.prewrite = NULL;
548         msg.postwrite = NULL;
549
550         if (len > 0x1000) {
551                 /* The FW is the only long message. Do not add preamble,
552                 and do not padd it */
553                 msg.alignment = 4;
554                 msg.add_preamble = 0;
555                 msg.prewrite = smschipreset;
556         } else {
557                 msg.alignment = SPI_PACKET_SIZE;
558                 msg.add_preamble = 1;
559         }
560
561         return smsspi_queue_message_and_wait(context, &msg);
562 }
563
564 struct _rx_buffer_st *allocate_rx_buf(void *context, int size)
565 {
566         struct smscore_buffer_t *buf;
567         struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
568         if (size > RX_BUFFER_SIZE) {
569                 PERROR("Requested size is bigger than max buffer size.\n");
570                 return NULL;
571         }
572         buf = smscore_getbuffer(spi_device->coredev);
573 //      printk("smsmdtv: Recieved Rx buf %p physical 0x%x (contained in %p)\n", buf->p,
574 //             buf->phys, buf);
575
576         /* note: this is not mistake! the rx_buffer_st is identical to part of
577            smscore_buffer_t and we return the address of the start of the
578            identical part */
579
580 //  smscore_getbuffer return null, lets also return null
581         if(NULL == buf)
582         {
583                 return NULL;
584         }
585
586         return (struct _rx_buffer_st *) &buf->p;
587 }
588
589 static void free_rx_buf(void *context, struct _rx_buffer_st *buf)
590 {
591         struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
592         struct smscore_buffer_t *cb =
593             (struct smscore_buffer_t
594              *)(container_of(((void *)buf), struct smscore_buffer_t, p));
595 //      printk("smsmdtv: buffer %p is released.\n", cb);
596         smscore_putbuffer(spi_device->coredev, cb);
597 }
598
599 /*! Release device STUB
600
601 \param[in]      dev:            device control block
602 \return         void
603 */
604 static void smsspi_release(struct device *dev)
605 {
606         PDEBUG("nothing to do\n");
607         /* Nothing to release */
608 }
609
610 static int smsspi_driver_probe(struct platform_device *pdev)
611 {
612     PDEBUG("smsspi_probe\n") ;
613     return 0 ;
614 }
615
616 extern void smschar_reset_device(void) ;
617 extern void smschar_set_suspend(int suspend_on);
618
619 extern int sms_suspend_count ;
620
621 #if 0   //hzb rockchip@20100525 
622 static struct platform_device smsspi_device = {
623         .name = "smsspi",
624         .id = 1,
625         .dev = {
626                 .release = smsspi_release,
627                 },
628 };
629 #endif
630
631 static struct platform_driver smsspi_driver = {
632     .probe   = smsspi_driver_probe,
633
634     .driver  = {
635          .name = "smsspi",
636     },       
637 };
638
639 void smsspi_poweron(void)
640 {
641     int ret=0;
642     ret = smsspibus_ssp_resume(spi_dev->phy_dev) ;
643     if( ret== -1)
644     {
645        sms_err(KERN_INFO "smsspibus_ssp_resume failed\n") ;
646
647         }
648 }
649
650
651 void smsspi_off(void)
652 {
653     smschar_reset_device() ;
654
655     smsspibus_ssp_suspend(spi_dev->phy_dev) ;
656 }
657
658
659 static int siano1186_probe( struct spi_device *Smsdevice)
660 {
661     struct smsdevice_params_t params;
662     int ret;
663     struct _spi_device_st *spi_device;
664     struct _spi_dev_cb_st common_cb;
665
666     sms_debug(KERN_INFO "siano1186_probe\n") ;
667
668     spi_device =
669     kmalloc(sizeof(struct _spi_device_st), GFP_KERNEL);
670     if(!spi_device)
671     {
672         sms_err("spi_device is null smsspi_register\n") ;
673         return 0;
674     }
675     spi_dev = spi_device;
676
677     INIT_LIST_HEAD(&spi_device->txqueue);
678
679     spi_device->txbuf = dma_alloc_coherent(NULL, max(TX_BUFFER_SIZE,PAGE_SIZE),&spi_device->txbuf_phy_addr, GFP_KERNEL | GFP_DMA);
680
681     if (!spi_device->txbuf) {
682         sms_err(KERN_INFO "%s dma_alloc_coherent(...) failed\n", __func__);
683         ret = -ENOMEM;
684         goto txbuf_error;
685     }
686     
687     sms_debug(KERN_INFO "smsmdtv: spi_device->txbuf = 0x%x  spi_device->txbuf_phy_addr= 0x%x\n",
688             (unsigned int)spi_device->txbuf, spi_device->txbuf_phy_addr);
689
690     spi_device->phy_dev =  smsspiphy_init(Smsdevice, smsspi_int_handler, spi_device);
691
692     if (spi_device->phy_dev == 0) {
693         sms_err(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
694         goto phy_error;
695     }
696
697     common_cb.allocate_rx_buf = allocate_rx_buf;
698     common_cb.free_rx_buf = free_rx_buf;
699     common_cb.msg_found_cb = msg_found;
700     common_cb.transfer_data_cb = smsspibus_xfer;
701
702     ret =  smsspicommon_init(&spi_device->dev, spi_device, spi_device->phy_dev, &common_cb);
703     if (ret) {
704         sms_err(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
705         goto common_error;
706     }
707
708     /* register in smscore */
709     memset(&params, 0, sizeof(params));
710     params.context = spi_device;
711     params.device = &Smsdevice->dev;
712     params.buffer_size = RX_BUFFER_SIZE;
713     params.num_buffers = NUM_RX_BUFFERS;
714     params.flags = SMS_DEVICE_NOT_READY;
715     params.sendrequest_handler = smsspi_write;
716     strcpy(params.devpath, "spi");
717     params.device_type = default_type;
718
719     if (0) {
720         /* device family */
721         /* params.setmode_handler = smsspi_setmode; */
722     } else {
723         params.flags =
724         SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY |
725         SMS_ROM_NO_RESPONSE;
726         params.preload_handler = smsspi_preload;
727         params.postload_handler = smsspi_postload;
728     }
729
730 #if SIANO_HALFDUPLEX
731         g_IsTokenOwned = false;
732         init_MUTEX_LOCKED(&HalfDuplexSemaphore);
733         SPI_Thread = kthread_run(spi_worker_thread,NULL,"cmmb_spi_thread");
734         SPI_Thread_IsStop = 0;
735 #endif
736
737
738     ret = smscore_register_device(&params, &spi_device->coredev);
739     if (ret < 0) {
740         sms_err(KERN_INFO "%s smscore_register_device(...) failed\n", __func__);
741         goto reg_device_error;
742     }
743
744     ret = smscore_start_device(spi_device->coredev);
745     if (ret < 0) {
746         sms_err(KERN_INFO "%s smscore_start_device(...) failed\n", __func__);
747         goto start_device_error;
748     }
749     spi_resume_fail = 0 ;
750     spi_suspended = 0 ;
751
752     sms_info(KERN_INFO "siano1186_probe exiting\n") ;
753    
754     PDEBUG("exiting\n");
755     return 0;
756
757 start_device_error:
758     smscore_unregister_device(spi_device->coredev);
759
760 reg_device_error:
761
762 common_error:
763     smsspiphy_deinit(spi_device->phy_dev);
764
765 phy_error:
766     
767 #if 0  //spi buff kmalloc  
768     kfree(spi_device->txbuf);
769 #else
770     dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,spi_device->txbuf_phy_addr);
771 #endif
772    
773 txbuf_error:
774     kfree(spi_device);
775     sms_err("exiting error %d\n", ret);
776
777     return ret;
778 }
779
780
781 void smsspi_remove(void)
782 {
783         struct _spi_device_st *spi_device = spi_dev;
784         sms_info(KERN_INFO "smsmdtv: in smsspi_unregister\n") ;
785         int ret;
786 #if SIANO_HALFDUPLEX
787         SPI_Thread_IsStop = 1;
788   up(&HalfDuplexSemaphore);
789   sms_info("stop kthread \n");
790         ret = kthread_stop(SPI_Thread);
791         sms_info("stop kthread ret = 0x%x\n",ret);
792 #endif
793         /* stop interrupts */
794         smsspiphy_deinit(spi_device->phy_dev);
795         
796         smscore_unregister_device(spi_device->coredev);
797
798         dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,spi_device->txbuf_phy_addr);
799         
800         kfree(spi_device);
801
802         sms_info("smsspi_remove exiting\n");
803 }
804
805 static struct spi_driver siano1186_driver = {
806         .driver = {
807                    .name = DRV_NAME,
808                    .bus = &spi_bus_type,
809                    .owner = THIS_MODULE,
810                    },
811         .probe = siano1186_probe,
812         .remove = __devexit_p(smsspi_remove),
813 };
814
815 int smsspi_register(void)
816 {
817     sms_info(KERN_INFO "smsmdtv: in smsspi_register\n") ;
818     spi_register_driver(&siano1186_driver); 
819 }
820
821 void smsspi_unregister(void)
822 {
823         spi_unregister_driver(&siano1186_driver);
824 }