tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / misc / gpsip / cgdriver / CgxDriverLinux.c
1 /******************************************************************************
2  *                                LEGAL NOTICE                                *
3  *                                                                            *
4  *  USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
5  *  DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
6  *  WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT     *
7  *  FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
8  *  OR DOCUMENTATION.                                                         *
9  *  NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR    *
10  *  OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
11  *  THE LICENSE TERMS AS STATED.                                              *
12  *                                                                            *
13  ******************************************************************************/
14 /* Version: 1.8.9\3686 */
15 /* Build  : 13 */
16 /* Date   : 12/08/2012 */
17
18
19 /**
20     \cond OS_LINUX
21 */
22
23 /**
24         \file
25         \brief Linux specific driver code
26         \attention This file should not be modified.
27                 If you think something is wrong here, please contact CellGuide
28         Specific code required for the CellGuide GPS driver for Linux.
29 */
30 // ===========================================================================
31
32 #define __CGXLINUXDRIVER_C__
33 #include <asm/io.h>
34 #include <linux/version.h>
35 #include <linux/module.h>
36 #include <linux/init.h>
37 #include <linux/fs.h>
38 #include <linux/mm.h>
39 #include <linux/pagemap.h>
40 #include <linux/vmalloc.h>
41 #include <linux/delay.h>
42 #include <linux/cdev.h>
43 #include <linux/interrupt.h>
44 #include <linux/workqueue.h>
45 #include <linux/poll.h>
46 #include <linux/device.h>
47 #include <linux/major.h>
48 #include <linux/sched.h>
49 #include <linux/spinlock.h>
50 #include <linux/errno.h>
51 #include <linux/completion.h>
52 #include <linux/dma-mapping.h>
53
54 #ifdef CONFIG_OF
55 #include <linux/of.h>
56 #include <linux/of_address.h>
57 #include <linux/of_irq.h>
58 #include <linux/of_gpio.h>
59 #endif
60
61 #include "CgTypes.h"
62 #include "CgReturnCodes.h"
63 #include "CgCpu.h"
64 #include "CgxDriverCore.h"
65 #include "CgxDriverOs.h"
66 #include "CgxDriverPlatform.h"
67
68 #include "platform.h"
69 #include "CgCpuOs.h"
70
71
72 extern U32 CGCORE_REG_OFFSET_CORE_RESETS;
73 extern U32 CGCORE_REG_OFFSET_VERSION;
74 extern  U32 poffset;
75
76
77 struct class       * gps_class;
78 struct device      * gps_dev;
79
80
81
82 /*paulluo add test*/
83 //#define FIX_MEMORY
84 #ifdef CGCORE_ACCESS_VIA_SPI
85 extern int  gpsspidev_init(void);
86 extern void gpsspidev_exit(void);
87 #endif
88
89
90 // ===========================================================================
91
92 //
93 // Driver instance structure.
94 //
95 typedef struct {
96         struct cdev                              cdev;
97         int                                              nNumOpens;
98         int                                              DataReady_irq;
99         int                                              GpsIntr_irq;
100         struct completion                xferCompleted; // was rcvSem
101         TCgxDriverPhysicalMemory chunk;
102         TCgxDriverState                  state;
103         void                                     *xfer_buff_ptr;          // Internal buffer pointer
104         unsigned long                    xfer_buff_len;           // Internal buffer len (bytes)
105         int                                              xfer_buff_pg_order;  // Internal buffer page order (log2(n))
106         int                                              xfer_buff_mmapped;       // Internal buffer is mapped
107         struct fasync_struct    *async_queue;
108         wait_queue_head_t                resumeq;
109         char                                     pm_resumed;
110 } DRVCONTEXT;
111
112 // Use a static DriverContext, as only one driver instance is needed
113 static DRVCONTEXT                          DrvContext;
114 //bxd add for first alloc mem failed from engine
115 static void *init_buff_ptr;
116
117 static void GpsIntr_BH(struct work_struct *work);
118 DECLARE_WORK(girq_work, GpsIntr_BH);
119 static struct workqueue_struct *girq_wq  = NULL;
120 #define GIRQ_WQ_NAME                    "GIRQ WorkQueue"
121
122 static void DataReady_BH(struct work_struct *work);
123 DECLARE_WORK(drdy_work, DataReady_BH);
124 static struct workqueue_struct *drdy_wq  = NULL;
125 #define DRDY_WQ_NAME                    "DRDY WorkQueue"
126
127 // In certain devices, there will not be an irq for DMA ready, but instead, a wait-able, exported sync-object.
128 #ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
129
130         static void DataReady_Completion_WorkQueue(struct work_struct *work);
131         DECLARE_WORK(drdy_completion_work, DataReady_Completion_WorkQueue);
132         static struct workqueue_struct *drdy_completion_wq       = NULL;
133         #define DRDY_COMPLETION_WQ_NAME                 "DRDY Completion WorkQueue"
134
135         extern struct completion CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT;
136
137         /*
138         DataReady Interrupt Handlers:
139         DataReady_BH: The Bottom-Half (Handler Thread)
140         DataReady_TH: The Top-Half (ISR)
141         CgxDriverDataReadyInterruptHandlerStart: Register the DataReady ISR
142         */
143         static void DataReady_Completion_WorkQueue(struct work_struct *work)
144         {
145                 //      DBG_FUNC_NAME("DataReady_BH")
146                 //      DBGMSG("START");
147                 while (1)
148                 {
149                         wait_for_completion( &CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT );
150                         CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
151                 }
152
153                 //      DBGMSG("END");
154         }
155 #endif
156
157 static int                                        cgxdrv_major = 0;   /* 0 = dynamic major */
158 #define MODULE_NAME                      "cgxdrv"
159
160
161 /*
162         DataReady Interrupt Handlers:
163         DataReady_BH: The Bottom-Half (Handler Thread)
164         DataReady_TH: The Top-Half (ISR)
165         CgxDriverDataReadyInterruptHandlerStart: Register the DataReady ISR
166  */
167 static void DataReady_BH(struct work_struct *work)
168 {
169         //      DBG_FUNC_NAME("DataReady_BH")
170         //      DBGMSG("START");
171         CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
172         //enable_irq( DrvContext.DataReady_irq );
173         //      DBGMSG("END");
174 }
175
176 static irqreturn_t DataReady_TH(int irq, void *dev_id)
177 {
178         //      DBG_FUNC_NAME("DataReady_TH")
179         //      DBGMSG("START");
180         //disable_irq_nosync( irq );
181
182         queue_work(drdy_wq, &drdy_work);
183         //      DBGMSG("END");
184
185         return IRQ_HANDLED;
186 }
187
188
189 #ifdef CGCORE_ACCESS_VIA_SPI
190 u32 GetRequestLen(void)
191 {
192    TCgxDriverState *pState = &DrvContext.state;
193   
194    return pState->transfer.bytes.required;
195 }
196
197 void DataReady_TH_start(void )
198 {
199
200     CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
201
202 }
203 #endif
204 void* Data_Get_DrvContext(void)
205 {
206
207         return DrvContext.xfer_buff_ptr;
208 }
209
210 void CCgCpuDmaHandle(int irq,void* dev_id)
211 {
212         CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
213 }
214
215
216 TCgReturnCode CgxDriverDataReadyInterruptHandlerStart(void *pDriver)
217 {
218         DBG_FUNC_NAME("CgxDriverDataReadyInterruptHandlerStart")
219         DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
220
221         int      rv = 0;
222
223         // First check if there is an irq dedicated to the DataReady event
224         pDriverInfo->DataReady_irq = CgxDriverDataReadyInterruptCode();
225         if( pDriverInfo->DataReady_irq != 0)
226         {
227                 drdy_wq = create_singlethread_workqueue(DRDY_WQ_NAME);
228
229                 if (drdy_wq == NULL) {
230                         DBGMSG("create_singlethread_workqueue(" DRDY_WQ_NAME ") Failed");
231                         return ECgInitFailure;
232                 }
233
234                 rv = request_irq( pDriverInfo->DataReady_irq, DataReady_TH, IRQF_DISABLED, "drdy-bh", NULL );
235                 if (rv != 0) {
236                         DBGMSG1("request_irq(%d) Failed", pDriverInfo->DataReady_irq );
237                         return ECgInitFailure;
238                 }
239                 DBGMSG1("request_irq(DRDY/%d) OK", pDriverInfo->DataReady_irq );
240         }
241         else
242         {
243                 // There is no irq. Lets check if there is an exported sync-object
244                 #ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
245                         drdy_completion_wq = create_singlethread_workqueue(DRDY_COMPLETION_WQ_NAME);
246                         if ( OK(drdy_completion_wq) )
247                                 queue_work(drdy_completion_wq, &drdy_completion_work);
248                         else
249                                 return ECgInitFailure;
250                 #else
251                         DBGMSG1("request_irq(DRDY/%d) Skipped", pDriverInfo->DataReady_irq );
252                 #endif
253         }
254
255         return ECgOk;
256 }
257
258
259
260 /*
261         GpsIntr Interrupt Handlers:
262         GpsIntr_BH: The Bottom-Half (Handler Thread)
263         GpsIntr_TH: The Top-Half (ISR)
264         CgxDriverGeneralInterruptHandlerStart: Register the GpsIntr ISR
265  */
266 static void GpsIntr_BH(struct work_struct *work)
267 {
268         //      DBG_FUNC_NAME("GpsIntr_BH")
269         //      DBGMSG("START");
270         CgxDriverGpsInterruptHandler(&DrvContext, &DrvContext.state);
271         //      DBGMSG("END");
272         enable_irq( DrvContext.GpsIntr_irq );
273 }
274
275 static irqreturn_t GpsIntr_TH(int irq, void *dev_id)
276 {
277         //      DBG_FUNC_NAME("GpsIntr_TH")
278         //      DBGMSG("START");
279         disable_irq_nosync( irq );
280
281         queue_work(girq_wq, &girq_work);
282
283         //      DBGMSG("END");
284         return IRQ_HANDLED;
285 }
286
287 TCgReturnCode CgxDriverGpsInterruptHandlerStart(void *pDriver)
288 {
289         DBG_FUNC_NAME("CgxDriverGpsInterruptHandlerStart")
290         DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
291
292         int      rv = 0;
293         pDriverInfo->GpsIntr_irq = CgxDriverGpsInterruptCode();
294         if (pDriverInfo->GpsIntr_irq != 0)
295         {
296                 girq_wq = create_singlethread_workqueue(GIRQ_WQ_NAME);
297                 if (girq_wq == NULL) {
298                         DBGMSG("create_singlethread_workqueue(" GIRQ_WQ_NAME ") Failed");
299                         return ECgInitFailure;
300                         }
301                 #ifdef CGCORE_ACCESS_VIA_SPI
302                 rv = request_irq( pDriverInfo->GpsIntr_irq, GpsIntr_TH, IRQF_TRIGGER_RISING, "girq-bh", NULL );
303                 #else
304                 rv = request_irq( pDriverInfo->GpsIntr_irq, GpsIntr_TH, IRQF_DISABLED, "girq-bh", NULL );
305                 #endif
306                 if (rv != 0) {
307                         DBGMSG1("request_irq(%d) Failed", pDriverInfo->GpsIntr_irq );
308                         return ECgInitFailure;
309                         }
310                 DBGMSG1("request_irq(GPS/%d) OK", pDriverInfo->GpsIntr_irq );
311         }
312         else
313                 DBGMSG1("request_irq(GPS/%d) Skipped", pDriverInfo->GpsIntr_irq );
314
315         return ECgOk;
316 }
317
318
319
320
321
322 TCgReturnCode CgxDriverTransferEndCreate(void *pDriver)
323 {
324         DBG_FUNC_NAME("CgxDriverTransferEndCreate")
325         DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
326
327         DBGMSG( "Entering... Initializing completion semaphore" );
328
329         init_completion( &pDriverInfo->xferCompleted );
330
331         DBGMSG1( "Initialized Semaphore=%u", pDriverInfo->xferCompleted.done );
332
333         return ECgOk;
334 }
335
336
337
338 TCgReturnCode CgxDriverTransferEndSignal(void *pDriver)
339 {
340         //DBG_FUNC_NAME("CgxDriverTransferEndSignal")
341         DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
342
343 /*      DBGMSG( "Entering" );*/
344
345         //DBGMSG1( "Marking completion... Semaphore=%u", pDriverInfo->xferCompleted.done );
346         complete( &pDriverInfo->xferCompleted );
347         //DBGMSG1( "Marked completion... After Semaphore=%u", pDriverInfo->xferCompleted.done );
348
349         return ECgOk;
350 }
351
352
353 TCgReturnCode CgxDriverTransferEndWait(void *pDriver, U32 aTimeoutMS)
354 {
355         DRVCONTEXT       *pDriverInfo = (DRVCONTEXT *)pDriver;
356         TCgReturnCode   rc = ECgOk;
357         unsigned long   timeout = aTimeoutMS * HZ / 1000;
358         unsigned long   rv = 0 ;
359         DBG_FUNC_NAME("CgxDriverTransferEndWait")
360
361         DBGMSG1( "Timeout=%lu", timeout );
362
363
364         for (;;) {
365             if (pDriverInfo->state.flags.resume == 1) {
366                         DBGMSG("Resume!");
367                         return ECgResume;
368                         }
369                 //DBGMSG1( "Waiting for completion... Semaphore=%u", pDriverInfo->xferCompleted.done );
370                         /*bxd modify because of can't entry susnpend when use wait_for_completion_interruptible_timeout func */
371             //rv = wait_for_completion_interruptible_timeout( &pDriverInfo->xferCompleted, timeout );
372                         rv = wait_for_completion_timeout( &pDriverInfo->xferCompleted, timeout );
373                         if (rv != -ERESTARTSYS)
374                                 break;
375                 }
376
377         if ((rv == 0) && (timeout > 0))
378         {
379                 rc = ECgTimeout;
380                 DBGMSG( "Timed-out" );
381         }
382         else
383         {
384                 DBGMSG1( "wait_for_completion_interruptible_timeout returned=%d", rv );
385         }
386
387     if (pDriverInfo->state.flags.resume == 1) {
388                 DBGMSG("Resume!");
389                 rc = ECgResume;
390         }
391
392         return rc;
393 }
394
395
396 TCgReturnCode CgxDriverTransferEndDestroy(void *pDriver)
397 {
398     return ECgOk;
399 }
400
401
402 //#define FIX_MEMORY
403
404 #ifdef FIX_MEMORY
405 unsigned char buf_data[6*1024*1024];
406 #else
407  void* buf_data;
408 #endif
409
410 #ifndef CGCORE_ACCESS_VIA_SPI
411 void clear_buf_data(void)
412 {
413         memset(DrvContext.xfer_buff_ptr,0,DrvContext.xfer_buff_len);
414 }
415 #endif
416
417 TCgReturnCode CgxDriverAllocInternalBuff(void *pDriver, U32 aLength, void **apBuffer, U32 aProcessID)
418 {
419         DBG_FUNC_NAME("CgxDriverAllocInternalBuff")
420         DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
421         DBGMSG( "Entering..." );
422
423         /* Already alloc'ed, return error and ask to free 1st */
424         if (DrvContext.xfer_buff_ptr != NULL) {
425                 DBGMSG( "Returning ECgNotSupported" );
426                 return ECgNotSupported;
427         }
428
429
430       #ifndef FIX_MEMORY
431         DrvContext.xfer_buff_pg_order = get_order(aLength);
432         //bxd add for first alloc mem failed from engine
433         if(init_buff_ptr != NULL)
434                 DrvContext.xfer_buff_ptr = init_buff_ptr;
435         else
436                 DrvContext.xfer_buff_ptr          = (void *)__get_free_pages(GFP_KERNEL, DrvContext.xfer_buff_pg_order);
437         DrvContext.xfer_buff_len          = PAGE_SIZE * (1 << DrvContext.xfer_buff_pg_order);
438         buf_data  = DrvContext.xfer_buff_ptr;
439         #else
440         DrvContext.xfer_buff_pg_order = get_order(aLength);
441         DrvContext.xfer_buff_ptr          =(void*)&buf_data[0];
442         DrvContext.xfer_buff_len          = 6*1024*1024;
443
444         #endif
445
446
447         if (DrvContext.xfer_buff_ptr == NULL) {
448                 DBGMSG( "Returning ECgErrMemory" );
449                 return ECgErrMemory;
450         }
451
452         pDriverInfo->state.buffer.length = DrvContext.xfer_buff_len;
453         pDriverInfo->state.buffer.virtAddr = DrvContext.xfer_buff_ptr;
454         pDriverInfo->state.buffer.physAddr = __pa((void *)DrvContext.xfer_buff_ptr) ;
455         DBGMSG2( "Returning ECgOk - Requested: %lu - Granted: %lu", aLength, DrvContext.xfer_buff_len );
456
457         *apBuffer = (void *)pDriverInfo->state.buffer.physAddr;
458 #if defined(CGTEST) || defined(DEBUG)
459         memset(pDriverInfo->state.buffer.virtAddr, 0x43, aLength);
460 #endif
461         DBGMSG3(">>>>>>> memory allocated at DrvContext.xfer_buff_ptr=[0x%08X] buffer.virtAddr=[0x%08X], buffer.physAddr=[0x%08X]",DrvContext.xfer_buff_ptr, pDriverInfo->state.buffer.virtAddr, pDriverInfo->state.buffer.physAddr );
462         return ECgOk;
463 }
464
465 #ifdef CGCORE_ACCESS_VIA_SPI
466 int get_blocksize(void)
467 {
468     return DrvContext.state.transfer.blockSize;
469 }
470 #endif
471
472
473 void *CgxDriverGetInternalBuff(void *pSource, U32 length)
474 {
475 //      if (length != DrvContext.xfer_buff_len)
476 //              return NULL;
477
478         return DrvContext.xfer_buff_ptr;
479 }
480
481
482
483 TCgReturnCode CgxDriverFreeInternalBuff(void *pDriver, U32 unUsed)
484 {
485         /* Already alloc'ed, return error and ask to free 1st */
486         if (DrvContext.xfer_buff_ptr == NULL)
487                 return ECgNotSupported;
488
489         /* Buffer is mmap'ed. return error and ask to free 1st */
490         if (DrvContext.xfer_buff_mmapped)
491                 return ECgNotAllowed;
492
493 #ifndef FIX_MEMORY
494 //bxd
495         //free_pages((unsigned long)DrvContext.xfer_buff_ptr, DrvContext.xfer_buff_pg_order);
496 #endif
497
498         DrvContext.xfer_buff_ptr          = NULL;
499         DrvContext.xfer_buff_len          = 0;
500         DrvContext.xfer_buff_pg_order = 0;
501
502         //bxd add for first alloc mem failed from engine
503         //if(init_buff_ptr != NULL)
504         //      init_buff_ptr = NULL;
505
506         return ECgOk;
507 }
508
509
510
511 unsigned long CgxCopyFromUser(void *to, const void *fromuser, unsigned long n)
512 {
513         return copy_from_user(to, fromuser, n);
514 }
515
516
517
518 static void getdata32_to_data64(TCgDriverControl_32bit *In32,TCgDriverControl *In64)
519 {
520         In64->read.alignedLength = In32->read.alignedLength;
521         In64->read.blockLength     = In32->read.blockLength;
522         In64->read.byteOrder        = In32->read.byteOrder;
523         In64->read.buf                    = Data_Get_DrvContext();
524         In64->read.bufPhys            = In32->read.bufPhys;
525         In64->read.timeoutMS        = In32->read.timeoutMS;
526         In64->wait.timeoutMS        = In32->wait.timeoutMS;
527         In64->wait.blockNumber    = In32->wait.blockNumber;
528 //      In64->write.pSource           = &In32->write.pSource;
529         In64->write.length              = In32->write.length;
530         In64->GPIO.code                =  In32->GPIO.code; 
531         In64->GPIO.out                   = In32->GPIO.out;
532         In64->GPIO.mode               = In32->GPIO.mode;
533         In64->readReg.offset         = In32->readReg.offset;
534         In64->writeReg.offset        = In32->writeReg.offset;
535         In64->writeReg.value         = In32->writeReg.value;
536         In64->cancel.onByteCount = In32->cancel.onByteCount;
537         In64->reset.resetLevel        = In32->reset.resetLevel;
538         In64->alloc.length                 = In32->alloc.length;
539         In64->alloc.processId          = In32->alloc.processId;
540         In64->tcxoControl.enable   = In32->tcxoControl.enable;
541
542
543 #if 0
544         printk("read.alignedLength: 0x%x\n",      In32->read.alignedLength);    
545         printk("read.blockLength: 0x%x\n",      In32->read.blockLength);
546         printk("read.byteOrder: 0x%x\n",      In32->read.byteOrder);
547         printk("read.buf: 0x%x\n",       In32->read.buf);
548         printk("read.bufPhys: 0x%x\n",      In32->read.bufPhys);
549         printk("read.timeoutMS: 0x%x\n",       In32->read.timeoutMS);
550
551         printk("wait.timeoutMS: 0x%x\n",          In32->wait.timeoutMS);
552         printk("wait.blockNumber: 0x%x\n",         In32->wait.blockNumber);
553         printk("write.pSource: 0x%x\n",              In32->write.pSource);
554         printk("write.length: 0x%x\n",          In32->write.length);
555         printk("GPIO.code: 0x%x\n",           In32->GPIO.code);
556
557         printk("GPIO.out: 0x%x\n",           In32->GPIO.out);
558         printk("GPIO.mode: 0x%x\n",           In32->GPIO.mode);
559         printk("readReg.offset: 0x%x\n",           In32->readReg.offset);
560         printk("writeReg.offset: 0x%x\n",           In32->writeReg.offset);
561         printk("writeReg.value: 0x%x\n",           In32->writeReg.value);
562         printk("cancel.onByteCount: 0x%x\n",           In32->cancel.onByteCount);
563         printk("reset.resetLevel: 0x%x\n",           In32->reset.resetLevel);
564         printk("alloc.length: 0x%x\n",           In32->alloc.length);
565         printk("alloc.processId: 0x%x\n",           In32->alloc.processId);
566         printk("tcxoControl.enable: 0x%x\n",           In32->tcxoControl.enable);
567
568
569         printk("read.alignedLength In64: 0x%x\n",      In64->read.alignedLength);       
570         printk("read.blockLength In64: 0x%x\n",      In64->read.blockLength);
571         printk("read.byteOrder In64: 0x%x\n",      In64->read.byteOrder);
572         printk("read.buf In64: 0x%x\n",       In64->read.buf);
573         printk("read.bufPhys In64: 0x%x\n",      In64->read.bufPhys);
574         printk("read.timeoutMS In64: 0x%x\n",       In64->read.timeoutMS);
575
576         printk("wait.timeoutMS In64: 0x%x\n",          In64->wait.timeoutMS);
577         printk("wait.blockNumber In64: 0x%x\n",         In64->wait.blockNumber);
578         printk("write.pSource In64: 0x%x\n",              In64->write.pSource);
579         printk("write.length In64: 0x%x\n",          In64->write.length);
580         printk("GPIO.code In64: 0x%x\n",           In64->GPIO.code);
581
582         printk("GPIO.out In64: 0x%x\n",           In64->GPIO.out);
583         printk("GPIO.mode In64: 0x%x\n",           In64->GPIO.mode);
584         printk("readReg.offset In64: 0x%x\n",           In64->readReg.offset);
585         printk("writeReg.offset In64: 0x%x\n",           In64->writeReg.offset);
586         printk("writeReg.value In64: 0x%x\n",           In64->writeReg.value);
587         printk("cancel.onByteCount In64: 0x%x\n",           In64->cancel.onByteCount);
588         printk("reset.resetLevel In64: 0x%x\n",           In64->reset.resetLevel);
589         printk("alloc.length In64: 0x%x\n",           In64->alloc.length);
590         printk("alloc.processId In64: 0x%x\n",           In64->alloc.processId);
591         printk("tcxoControl.enable In64: 0x%x\n",           In64->tcxoControl.enable);
592 #endif    
593 }
594
595
596
597 static void putdata64_to_data32(TCgDriverStatus_32bit *Out32,TCgDriverStatus *Out64)
598 {
599           Out32->rc                                             =  Out64->rc;
600           Out32->buffer.bufferPhysAddr        =  (unsigned int)Out64->buffer.bufferPhysAddr;
601           Out32->buffer.bufferAppVirtAddr   =   poffset;
602           Out32->buffer.size                             =   Out64->buffer.size;
603           Out32->GPIO.code                             =   Out64->GPIO.code;
604           Out32->GPIO.val                                =   Out64->GPIO.val;
605           //Out32->version.buildVersion            =    &Out64->version.buildVersion[0];
606           //Out32->version.buildNumber           =    &Out64->version.buildNumber[0];
607           //Out32->version.buildDate                =    &Out64->version.buildDate[0];
608           //Out32->version.buildTime                =    &Out64->version.buildTime[0];
609           //Out32->version.buildMode               =   &Out64->version.buildMode[0];
610           //Out32->version.buildName              =   &Out64->version.buildName[0];
611           Out32->readReg.offset                   =   Out64->readReg.offset;
612           Out32->readReg.value                    =   Out64->readReg.value;
613           //Out32->cpuRevision.revisionCode =   &Out64->cpuRevision.revisionCode[0];
614           Out32->readRtc.year                       =   Out64->readRtc.year;
615           Out32->readRtc.month                   =   Out64->readRtc.month;
616           Out32->readRtc.day                       =    Out64->readRtc.day;
617           Out32->readRtc.hour                     =     Out64->readRtc.hour;
618           Out32->readRtc.minute                  =    Out64->readRtc.minute;
619           Out32->readRtc.second                 =    Out64->readRtc.second; 
620           Out32->readRtc.dayInWeek          =   Out64->readRtc.dayInWeek;
621           Out32->readRtc.tick                        =   Out64->readRtc.tick;
622           Out32->state.flags.terminate         =  Out64->state.flags.terminate;
623           Out32->state.flags.wait                   =  Out64->state.flags.wait;
624           Out32->state.flags.overrun             =   Out64->state.flags.overrun;
625           Out32->state.flags.resume              =    Out64->state.flags.resume;
626           Out32->state.counters.interrupt.all  =   Out64->state.counters.interrupt.all;
627           Out32->state.counters.interrupt.snapStart  =   Out64->state.counters.interrupt.snapStart;
628           Out32->state.counters.interrupt.overrun     =      Out64->state.counters.interrupt.overrun;
629           Out32->state.transfer.bufferPhys                 =  Out64->state.transfer.bufferPhys;
630           Out32->state.transfer.originalBuffer            =   (unsigned int)( Out64->state.transfer.originalBuffer);
631           Out32->state.transfer.byteOrder                 =   Out64->state.transfer.byteOrder;
632           Out32->state.transfer.done                            = Out64->state.transfer.done;
633           Out32->state.transfer.bytes.required         =  Out64->state.transfer.bytes.required;
634           Out32->state.transfer.bytes.received        =  Out64->state.transfer.bytes.received;
635           Out32->state.transfer.blocks.required      =   Out64->state.transfer.blocks.required;
636           Out32->state.transfer.blocks.received      =    Out64->state.transfer.blocks.received;
637           Out32->state.transfer.chunks.required    =   Out64->state.transfer.blocks.received;
638           Out32->state.transfer.chunks.received    =   Out64->state.transfer.chunks.received;
639           Out32->state.transfer.chunks.active        =  Out64->state.transfer.chunks.active;
640           Out32->state.transfer.cancel.request     =   Out64->state.transfer.cancel.request;
641           Out32->state.transfer.cancel.onByte      = Out64->state.transfer.cancel.onByte;
642           Out32->state.transfer.cancel.onChunk   =  Out64->state.transfer.cancel.onChunk;
643           //Out32->state.transfer.bufferOffset         = Out64->state.transfer.bufferOffset;
644           Out32->state.transfer.blockSize              =  Out64->state.transfer.blockSize;
645           Out32->state.transfer.lastBlockSize          =  Out64->state.transfer.lastBlockSize;
646           Out32->state.buffer.physAddr                    = Out64->state.buffer.physAddr;
647           Out32->state.buffer.virtAddr                     =  (unsigned int)(Out64->state.buffer.virtAddr);
648           Out32->state.buffer.length                         =   Out64->state.buffer.length;
649           Out32->state.buffer.driverContextVirtBufferAddr  =  (unsigned int)(Out64->state.buffer.driverContextVirtBufferAddr);
650           Out32->state.constructionRc                                        = Out64->state.constructionRc;
651 #if 0
652            printk("Out64.readReg.offset: 0x%x\n",           Out64->readReg.offset);
653           printk("Out64.readReg.value: 0x%x\n",           Out64->readReg.value);
654           printk("Out32.readReg.offset: 0x%x\n",           Out32->readReg.offset);
655           printk("Out32.readReg.value: 0x%x\n",           Out32->readReg.value);
656           #endif
657 }
658 #if 0
659 static void printdata32(TCgDriverStatus_32bit *Out32)
660 {
661
662           printk(" Out32->rc: 0x%x\n",            Out32->rc);
663           printk(" Out32->buffer.bufferPhysAddr: 0x%x\n",           Out32->buffer.bufferPhysAddr);
664         printk(" Out32->buffer.bufferAppVirtAddr: 0x%x\n",            Out32->buffer.bufferAppVirtAddr);
665         printk(" Out32->buffer.size : 0x%x\n",            Out32->buffer.size );
666         printk(" Out32->GPIO.code : 0x%x\n",            Out32->GPIO.code );
667         printk(" Out32->GPIO.val: 0x%x\n",            Out32->GPIO.val);
668
669                   printk(" Out32->version.buildVersion: 0x%x\n",            Out32->version.buildVersion);
670           printk(" Out32->version.buildNumber: 0x%x\n",            Out32->version.buildNumber);
671           printk(" Out32->version.buildDate : 0x%x\n",            Out32->version.buildDate );
672           printk(" Out32->version.buildTime: 0x%x\n",            Out32->version.buildTime);
673           printk(" Out32->version.buildMode : 0x%x\n",            Out32->version.buildMode );
674           printk(" Out32->version.buildName: 0x%x\n",            Out32->version.buildName);
675         
676         printk(" Out32->readReg.offset: 0x%x\n",            Out32->readReg.offset);
677         printk(" Out32->readReg.value: 0x%x\n",            Out32->readReg.value);
678         printk(" Out32->readRtc.year : 0x%x\n",            Out32->readRtc.year );
679         printk(" Out32->readRtc.month: 0x%x\n",           Out32->readRtc.month);
680         printk(" Out32->readRtc.day: 0x%x\n",            Out32->readRtc.day);
681         printk(" Out32->readRtc.hour: 0x%x\n",            Out32->readRtc.hour);
682         printk(" Out32->readRtc.minute: 0x%x\n",            Out32->readRtc.minute);
683         printk(" Out32->readRtc.second: 0x%x\n",            Out32->readRtc.second);
684         printk(" Out32->readRtc.dayInWeek: 0x%x\n",            Out32->readRtc.dayInWeek);
685         printk(" Out32->readRtc.tick: 0x%x\n",            Out32->readRtc.tick);
686         
687         
688         
689         
690          printk(" Out32->state.flags.terminate: 0x%x\n",            Out32->state.flags.terminate);
691          printk(" Out32->state.flags.wait: 0x%x\n",            Out32->state.flags.wait);
692          printk(" Out32->state.flags.overrun: 0x%x\n",            Out32->state.flags.overrun);
693          printk(" Out32->state.flags.resume: 0x%x\n",            Out32->state.flags.resume);
694          printk(" Out32->state.counters.interrupt.all: 0x%x\n",            Out32->state.counters.interrupt.all);
695          printk(" Out32->state.counters.interrupt.snapStart: 0x%x\n",           Out32->state.counters.interrupt.snapStart);
696          printk(" Out32->state.counters.interrupt.overrun: 0x%x\n",            Out32->state.counters.interrupt.overrun);
697          printk(" Out32->state.transfer.bufferPhys: 0x%x\n",            Out32->state.transfer.bufferPhys);
698          printk(" Out32->state.transfer.originalBuffer: 0x%x\n",            Out32->state.transfer.originalBuffer);
699          printk(" Out32->state.transfer.byteOrder: 0x%x\n",            Out32->state.transfer.byteOrder);
700          printk(" Out32->state.transfer.done: 0x%x\n",            Out32->state.transfer.done);
701          printk(" Out32->state.transfer.bytes.required: 0x%x\n",            Out32->state.transfer.bytes.required);
702          printk(" Out32->state.transfer.bytes.received: 0x%x\n",            Out32->state.transfer.bytes.received);
703          printk(" Out32->state.transfer.blocks.required: 0x%x\n",           Out32->state.transfer.blocks.required);
704          printk(" Out32->state.transfer.blocks.received: 0x%x\n",            Out32->state.transfer.blocks.received);
705          printk(" Out32->state.transfer.chunks.required: 0x%x\n",            Out32->state.transfer.chunks.required);
706          printk(" Out32->state.transfer.chunks.received: 0x%x\n",            Out32->state.transfer.chunks.received);
707          printk(" Out32->state.transfer.chunks.active: 0x%x\n",            Out32->state.transfer.chunks.active);
708          printk(" Out32->state.transfer.cancel.request: 0x%x\n",            Out32->state.transfer.cancel.request);
709          printk(" Out32->state.transfer.cancel.onByte: 0x%x\n",            Out32->state.transfer.cancel.onByte);
710          printk(" Out32->state.transfer.cancel.onChunk : 0x%x\n",            Out32->state.transfer.cancel.onChunk );
711          printk(" Out32->state.transfer.bufferOffset: 0x%x\n",            Out32->state.transfer.bufferOffset);
712          printk(" Out32->state.transfer.blockSize: 0x%x\n",            Out32->state.transfer.blockSize);
713          printk(" Out32->state.transfer.lastBlockSize: 0x%x\n",            Out32->state.transfer.lastBlockSize);
714          printk(" Out32->state.buffer.physAddr: 0x%x\n",            Out32->state.buffer.physAddr);
715          printk(" Out32->state.buffer.virtAddr: 0x%x\n",            Out32->state.buffer.virtAddr);
716          
717           printk(" Out32->state.buffer.length: 0x%x\n",            Out32->state.buffer.length);
718           printk(" Out32->state.buffer.driverContextVirtBufferAddr: 0x%x\n",            Out32->state.buffer.driverContextVirtBufferAddr);
719           printk(" Out32->state.constructionRc: 0x%x\n",            Out32->state.constructionRc);
720           printk(" Out32->rc: 0x%x\n",            Out32->rc);
721           printk(" Out32->rc: 0x%x\n",            Out32->rc);
722           
723
724         
725         
726         
727         
728
729         
730         
731         
732           //Out32->cpuRevision.revisionCode =   &Out64->cpuRevision.revisionCode[0];
733
734 }
735 #endif
736 //======================================================================
737 // CGX_IOControl - Called when DeviceIOControl called
738 //
739 //static int CGX_IOControl(struct inode *inode,struct file *filp,
740 static long CGX_IOControl(struct file *filp,
741
742                                   unsigned int cmd, unsigned long arg)
743 {
744         DBG_FUNC_NAME("CGX_IOControl")
745         TCgReturnCode     rc  = ECgOk;
746         TCgDriverControl   In;
747         TCgDriverStatus Out;
748         
749         TCgDriverControl_32bit   In_32;
750         TCgDriverStatus_32bit   Out_32;
751         
752 //printk("cmd:0x%x,arg:0x%x\n",cmd,arg);
753  /*     DBGMSG1( "Entering...[%d]" , cmd); */
754
755
756         // Check we can read the TCgDriverControl from User Space
757         if ( !access_ok( VERIFY_READ, (void __user *)arg, sizeof(TCgDriverControl_32bit) )  ) {
758                 DBGMSG( "Returning -EFAULT 1" );
759                 return -EFAULT;
760         }
761
762         // Check we can write the TCgDriverStatus to User Space
763         if ( !access_ok( VERIFY_WRITE, (void __user *)arg, sizeof(TCgDriverStatus_32bit) )  ) {
764                 DBGMSG( "Returning -EFAULT 2" );
765                 return -EFAULT;
766         }
767
768         if (  copy_from_user( &In_32, (void __user *)arg, sizeof(In_32) )  ) {
769                 DBGMSG( "Returning -EFAULT 3" );
770                 return -EFAULT;
771         }
772         
773         getdata32_to_data64(&In_32,&In);
774         
775         rc = CgxDriverExecute( &DrvContext, &DrvContext.state, cmd, &In, &Out);
776
777         putdata64_to_data32(&Out_32,&Out);
778        
779         if (  copy_to_user( (void __user *)arg, &Out_32, sizeof(Out_32) )  ) {
780                 DBGMSG( "Returning -EFAULT 4" );
781                 return -EFAULT;
782         }
783
784         DBGMSG1( "Returning %d", (OK(rc)) ? 0 : -ENOTTY );
785         return (OK(rc)) ? 0 : -ENOTTY;
786
787 }
788
789
790 int CGX_CompleteDrv(void)
791 {
792         complete(&DrvContext.xferCompleted);
793                 return 0;
794 }
795
796 EXPORT_SYMBOL_GPL(CGX_CompleteDrv);
797
798 //======================================================================
799 // CGX_Fasync - Called when driver closed
800 //
801 static int       CGX_Fasync( int fd, struct file *filp, int mode)
802 {
803         return fasync_helper(fd, filp, mode, &DrvContext.async_queue);
804 }
805
806 unsigned int CgxDriverCheckAllocInternalBuff(void)
807 {
808
809         if (DrvContext.xfer_buff_ptr != NULL) {
810                 printk( "\n already alloc page \n" );
811                 return 0;
812         }
813         return 1;
814 }
815
816
817
818 //======================================================================
819 // CGX_Close - Called when driver closed
820 //
821 static int       CGX_Close( struct inode *inode, struct file *filp)
822 {
823 /*      DBGMSG( "Entering..." ); */
824
825 #if 0
826         //gaole add begin
827         int rc = 0;
828
829         CgCoreReleaseRes();
830         if (CgxDriverCheckAllocInternalBuff() == 0)
831         {
832                 printk("\n gaole: close check if old page be released \n");
833
834                 rc = CgxDriverFreeInternalBuff(NULL, 0);
835
836                 if(ECgOk  !=  rc)
837                 {
838                         printk("\n gaole: close run CgxDriverFreeInternalBuff error,error code is %d \n",rc);
839                 }
840
841         }
842
843         rc = CgCpuDmaStop(0);
844         if(ECgOk  !=  rc)
845         {
846                 printk("\n gaole: run CgCpuDmaStop error,error code is %d \n",rc);
847
848         }
849         CgGpsReset();
850 #endif
851
852         CgCpuDmaDestroy(0,0);
853         // gaole add end
854
855
856         if (DrvContext.nNumOpens)
857                 DrvContext.nNumOpens--;
858
859         if ( filp->f_flags & FASYNC) {
860                         CGX_Fasync(-1, filp, 0); /* Remove from async queue */
861         }
862
863 /*      DBGMSG( "Returning 0" ); */
864         return 0;
865 }
866
867
868 //======================================================================
869 // CGX_Read - Called when driver read
870 //
871 static ssize_t CGX_Read( struct file *filp, char __user *buff, size_t count, loff_t *offp)
872 {
873         while (DrvContext.pm_resumed == 0) {
874                 if (filp->f_flags & O_NONBLOCK)
875                         return -EAGAIN;
876                 //DBGMSG( "Waiting for resume to take place... Going to sleep\n" );
877                 if (wait_event_interruptible(DrvContext.resumeq, (DrvContext.pm_resumed != 0)))
878                         return -ERESTARTSYS;
879         }
880
881         /*
882          * Copy 1 char sizeof(*(char*)) from DrvContext.pm_resumed to buff
883          */
884         if (put_user(DrvContext.pm_resumed, (char __user *)buff)) {
885                 return -EFAULT;
886         }
887
888         DrvContext.pm_resumed = 0;
889         return 1;
890 }
891
892
893 //======================================================================
894 // CGX_Write - Called when driver written
895 //
896 static ssize_t CGX_Write( struct file *filp, const char __user *buff, size_t count, loff_t *offp)
897 {
898         return 0;
899 }
900
901
902 //======================================================================
903 // CGX_Poll - Called when driver select()/poll()
904 //
905 static unsigned int CGX_Poll(struct file *filp, poll_table *wait)
906 {
907         poll_wait(filp, &DrvContext.resumeq,  wait);
908
909         if (DrvContext.pm_resumed == 'R')
910                 return (POLLIN | POLLRDNORM);
911
912         return 0;
913 }
914
915 //======================================================================
916 // CGX_Seek - Called when SetFilePtr called
917 //
918 static loff_t  CGX_Seek (struct file *filp, loff_t off, int whence)
919 {
920         return 0;
921 }
922
923
924
925
926
927
928 //======================================================================
929 // CGX_Open - Called when driver opened
930 //
931 static int CGX_Open( struct inode *inode, struct file *filp )
932 {
933
934         /*
935          * XXX-PK-XXX: Hold lock on DrvContext
936          */
937         CgCpuDmaCreate(0,0);
938
939 /*      DBGMSG( "Entering..." ); */
940
941         // Count the number of opens.
942         DrvContext.nNumOpens++;
943
944 /*      DBGMSG( "Returning 0" ); */
945         return 0;
946 }
947
948
949 /*
950  * CGX_vma_open and CGX_vma_close keep track of how many times
951  * the buffer is mapped, to avoid Freeing it while in use.
952  */
953 static void CGX_vma_open(struct vm_area_struct *vma)
954 {
955         DBG_FUNC_NAME("CGX_vma_open")
956         DrvContext.xfer_buff_mmapped++;
957         DBGMSG4("vma open [%d]: virt 0x%lx, Offs %lu, Len %lu",
958                         DrvContext.xfer_buff_mmapped,
959                         vma->vm_start, vma->vm_pgoff << PAGE_SHIFT, vma->vm_end - vma->vm_start );
960 }
961
962 static void CGX_vma_close(struct vm_area_struct *vma)
963 {
964         DBG_FUNC_NAME("CGX_vma_close")
965 /*      DBGMSG( "Entering..." ); */
966
967         DrvContext.xfer_buff_mmapped--;
968         DBGMSG1("vma close [%d]", DrvContext.xfer_buff_mmapped );
969
970 /*      DBGMSG( "Exit" ); */
971 }
972
973 #if LINUX_VERSION_CODE >= 132634
974 static int CGX_vma_nopage(struct vm_area_struct *vma, struct vm_fault *vmf)
975 {
976     return VM_FAULT_SIGBUS; // Remapping is not allowed !
977 }
978 #else
979 static struct page *CGX_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
980 {
981     return NOPAGE_SIGBUS; // Remapping is not allowed !
982 }
983 #endif
984
985 static struct vm_operations_struct cgx_remap_ops = {
986         .open =   CGX_vma_open,
987         .close =  CGX_vma_close,
988         #if LINUX_VERSION_CODE >= 132634
989                 .fault = CGX_vma_nopage,
990         #else
991         .nopage = CGX_vma_nopage,
992         #endif
993 };
994
995 static int CGX_Mmap(struct file *filp, struct vm_area_struct *vma)
996 {
997         DBG_FUNC_NAME("CGX_Mmap")
998         int     rv;
999         unsigned long len         = (vma->vm_end - vma->vm_start);
1000         unsigned long off         = vma->vm_pgoff << PAGE_SHIFT;
1001         unsigned long physical = __pa((void *)DrvContext.xfer_buff_ptr) + off;
1002
1003         DBGMSG3( "Entering... len=%lu off=%lu DrvContext.xfer_buff_len=%lu", len, off, DrvContext.xfer_buff_len );
1004
1005         if ( len > (DrvContext.xfer_buff_len - off) ) {
1006                 DBGMSG( "Returning -EINVAL" );
1007                 return -EINVAL;
1008         }
1009
1010 #ifdef CGCORE_ACCESS_VIA_SPI
1011         rv = remap_pfn_range(vma, vma->vm_start,
1012                                                  physical >> PAGE_SHIFT, len,
1013                                                  (vma->vm_page_prot));
1014 #else
1015
1016         rv = remap_pfn_range(vma, vma->vm_start,
1017                                                  physical >> PAGE_SHIFT, len,
1018                                                  pgprot_noncached(vma->vm_page_prot));
1019
1020 #endif
1021
1022
1023
1024         if (rv < 0) {
1025                 DBGMSG1( "Returning %d", rv );
1026                 return rv;
1027         }
1028
1029         vma->vm_ops = &cgx_remap_ops;
1030         CGX_vma_open(vma);
1031 /*      DBGMSG( "Returning 0" ); */
1032         return 0;
1033 }
1034
1035
1036 #if 0
1037 #warning CGX_AddSysDev is needed only for debugging !
1038 static int CGX_AddSysDev(struct sys_device *dev)
1039 {
1040         DBGMSG( "Got to CGX_AddSysDev\n" );
1041         return 0;
1042 }
1043 #endif
1044
1045
1046 static int CGX_PMSuspend(struct device *dev, pm_message_t state)
1047 {
1048  #if 0
1049         //DBGMSG( "Got to CGX_PMSuspend\n" );
1050         printk("%s\n",__func__);
1051         //if (DrvContext.nNumOpens > 0)
1052         if(flag_power_up == 1)
1053         {
1054                 CgxDriverPowerDown();
1055                 CgxDriverRFPowerDown();
1056         }
1057  #endif 
1058         return 0;
1059 }
1060
1061
1062 static int CGX_PMResume(struct device *dev)
1063 {
1064  #if 0
1065         //DBGMSG( "Got to CGX_PMResume\n" );
1066         printk("%s\n",__func__);
1067         //if (DrvContext.nNumOpens > 0)
1068         if(flag_power_up == 1)
1069         {
1070
1071                 DrvContext.state.flags.resume = 1;
1072         #if 0
1073                 DrvContext.pm_resumed = 'R';
1074
1075                 /* awake read()ers and poll()ers (select) */
1076                 wake_up_interruptible(&DrvContext.resumeq);
1077
1078                 /* signal async readers */
1079                 if (DrvContext.async_queue)
1080                         kill_fasync(&DrvContext.async_queue, SIGIO, POLL_IN);
1081         #endif
1082                 CgxDriverPowerUp();
1083                 CgxDriverRFPowerUp();
1084         }
1085 #endif 
1086         return 0;
1087 }
1088
1089
1090
1091 //======================================================================
1092 // CGX_Init - Driver initialization function
1093 //
1094 struct file_operations cgx_fops = {
1095                 .owner =         THIS_MODULE,
1096                 .llseek =       CGX_Seek,
1097                 .read =   CGX_Read,
1098                 .write =         CGX_Write,
1099                 .poll =   CGX_Poll,
1100                 //bxd
1101                 //.ioctl =       CGX_IOControl,
1102                 .unlocked_ioctl  =       CGX_IOControl,
1103         #ifdef CONFIG_COMPAT
1104                  .compat_ioctl     = CGX_IOControl,
1105         #endif
1106                 .open =   CGX_Open,
1107                 .fasync =   CGX_Fasync,
1108                 .release =   CGX_Close,
1109                 .mmap =   CGX_Mmap,
1110 };
1111
1112 #ifdef CONFIG_OF
1113 #ifndef CGCORE_ACCESS_VIA_SPI
1114 struct gps_2351_addr gps_2351;
1115 u32 gps_get_core_base(void)
1116 {
1117         return gps_2351.gps_base;
1118 }
1119
1120 u32 gps_get_ahb_base(void)
1121 {
1122         return gps_2351.ahb_base;
1123 }
1124
1125 u32 gps_get_irq(void)
1126 {
1127         return gps_2351.irq_num;
1128 }
1129
1130 u32 gps_get_lna_gpio(void)
1131 {
1132         return gps_2351.lna_gpio;
1133 }
1134
1135 #ifdef CONFIG_ARCH_SCX30G
1136 u32 gps_get_pmu_base(void)
1137 {
1138         return gps_2351.pmu_base;
1139 }
1140 #endif
1141
1142 static int cgxdrv_gps_source_init(void)
1143 {
1144         int ret;
1145
1146         struct device_node *np;
1147         struct resource res;
1148
1149         np = of_find_node_by_name(NULL, "gps_2351");
1150         if (!np) {
1151                 printk("Can't get the gps_2351 node!\n");
1152                 return -ENODEV;
1153         }
1154         printk(" find the gps_2351 node!\n");
1155
1156         ret = of_address_to_resource(np, 0, &res);
1157         if (ret < 0) {
1158                 printk("Can't get the gps reg base!\n");
1159                 return -EIO;
1160         }
1161         gps_2351.gps_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
1162         printk("gps reg base is 0x%x\n", gps_2351.gps_base);
1163
1164         ret = of_address_to_resource(np, 1, &res);
1165         if (ret < 0) {
1166                 printk("Can't get the ahbreg base!\n");
1167                 return -EIO;
1168         }
1169         gps_2351.ahb_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
1170         printk("ahb reg base is 0x%x\n", gps_2351.ahb_base);
1171
1172         #ifdef CONFIG_ARCH_SCX30G
1173         ret = of_address_to_resource(np, 2, &res);
1174         if (ret < 0) {
1175                 printk("Can't get the pmu base!\n");
1176                 return -EIO;
1177         }
1178         gps_2351.pmu_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
1179         printk("pmu_base base is 0x%x\n", gps_2351.pmu_base);
1180         #endif
1181
1182         gps_2351.irq_num = irq_of_parse_and_map(np, 0);
1183         if (gps_2351.irq_num == 0) {
1184                 printk("Can't get the gps irq_num!\n");
1185                 return -EIO;
1186         }
1187         printk(" gps_2351.gps_irq_num is %d\n", gps_2351.irq_num);
1188
1189         gps_2351.lna_gpio = of_get_gpio(np, 0);
1190         if(gps_2351.lna_gpio < 0){
1191                 printk("fail to get gps lna gpio\n");
1192         }
1193         return ret;
1194 }
1195 #endif
1196 #endif
1197 static int __init  CGX_Init(void)
1198 {
1199         DBG_FUNC_NAME("CGX_Init")
1200         int              rv;
1201         dev_t      devno = MKDEV(cgxdrv_major, 0);
1202
1203 /*      DBGMSG( "Entering..." ); */
1204
1205         DBGMSG("Initializing");
1206
1207         #ifdef CONFIG_OF
1208         #ifndef CGCORE_ACCESS_VIA_SPI
1209         cgxdrv_gps_source_init();
1210         #endif
1211         #endif
1212
1213         //bxd add for first alloc mem failed from engine
1214         init_buff_ptr = (void *)__get_free_pages(GFP_KERNEL, 8);
1215         if(init_buff_ptr == NULL)
1216                 printk("init_buff_ptr alloc failed\n");
1217
1218 #ifndef CGCORE_ACCESS_VIA_SPI
1219         sprd_get_rf2351_ops(&gps_rf_ops);
1220 #endif
1221
1222 #ifdef CGCORE_ACCESS_VIA_SPI
1223         gpsspidev_init();
1224 #endif
1225
1226         /* Init structure */
1227         memset (&(DrvContext), 0, sizeof (DRVCONTEXT));
1228         init_waitqueue_head(&DrvContext.resumeq);
1229
1230         /* Register char dev (Major can be provided at load time) */
1231         if (cgxdrv_major) {
1232           rv = register_chrdev_region(devno, 1, "cgxdrv");
1233       printk(KERN_ERR "[CGX|%s] register_chrdev_region \r\n", __FUNCTION__);
1234         } else {
1235           rv = alloc_chrdev_region(&devno, 0, 1, "cgxdrv");
1236           cgxdrv_major = MAJOR(devno);
1237       printk(KERN_ERR "[CGX|%s] alloc_chrdev_region, cgxdrv_major=%d \r\n", __FUNCTION__, cgxdrv_major);
1238         }
1239
1240         if (rv < 0) {
1241           printk(KERN_ERR MODULE_NAME " Error can't get major %d\r\n", cgxdrv_major);
1242           goto out;
1243         }
1244
1245         if ( CgxDriverConstruct(&DrvContext, &DrvContext.state) != ECgOk ) {
1246           DBGMSG("CgxDriverConstruct Failed");
1247           rv = -ENOMEM;
1248           goto out1;
1249         }
1250
1251         // Device is ready... Activate it
1252         cdev_init(&DrvContext.cdev, &cgx_fops);
1253         DrvContext.cdev.owner = THIS_MODULE;
1254         DrvContext.cdev.ops   = &cgx_fops;
1255         rv = cdev_add (&DrvContext.cdev, devno, 1);
1256         if (rv) {
1257           // Cleanup
1258           DBGMSG1(" Error %d adding cgxdrv device\r\n", rv);
1259           goto out2;
1260         }
1261
1262     /* Create the device class. */
1263     gps_class = class_create(THIS_MODULE, "cgxdrv_class");
1264     if (IS_ERR(gps_class))
1265     {
1266         DBGMSG(" Error: create cgxdrv class failed\r\n");
1267     }
1268
1269         //bxd
1270         gps_class->suspend = CGX_PMSuspend;
1271         gps_class->resume = CGX_PMResume;
1272
1273     /* register in /dev */
1274     gps_dev = device_create(gps_class, NULL, devno, NULL, "cgxdrv");
1275     if (IS_ERR(gps_dev))
1276     {
1277         DBGMSG(" Error: device_create failed\r\n");
1278         class_destroy(gps_class);
1279     }
1280
1281         DBGMSG1(" Driver Ready... Major DevId: %d", cgxdrv_major );
1282     DBGMSG1(" Driver Byte order %d", CGX_DRIVER_NATIVE_BYTE_ORDER);
1283
1284         goto out;
1285
1286 out2:
1287         /*
1288          * XXX-PK-XXX: FIXME: Add CgxDriverConstruct Cleanup
1289          * For example: free IRQs, destroy workqueues, etc.
1290          */
1291 out1:
1292         unregister_chrdev_region( devno, 1 );
1293 out:
1294         return rv;
1295 }
1296
1297
1298 //======================================================================
1299 // CGX_Deinit - Driver de-initialization function
1300 //
1301 static void      __exit  CGX_Deinit(void)
1302 {
1303     printk(KERN_ERR "[CGX|%s] in\r\n", __FUNCTION__);
1304
1305         // Free the driver state buffer.
1306         if (DrvContext.GpsIntr_irq != 0)
1307     {
1308             free_irq(DrvContext.GpsIntr_irq, NULL);
1309         printk(KERN_ERR "free_irq GpsIntr_irq");
1310     }
1311
1312     if (DrvContext.DataReady_irq != 0)
1313     {
1314             free_irq(DrvContext.DataReady_irq, NULL);
1315         printk(KERN_ERR "free_irq DataReady_irq");
1316     }
1317
1318         if (girq_wq) {
1319                 flush_workqueue(girq_wq);
1320                 destroy_workqueue(girq_wq);
1321         printk(KERN_ERR "destroy_workqueue girq_wq");
1322         }
1323         if (drdy_wq) {
1324                 flush_workqueue(drdy_wq);
1325                 destroy_workqueue(drdy_wq);
1326         printk(KERN_ERR "destroy_workqueue drdy_wq");
1327         }
1328
1329         #ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
1330                 if (drdy_completion_wq) {
1331             printk(KERN_ERR "CGX_Deinit (1)");
1332                         //flush_workqueue(drdy_completion_wq);  //commented for debug, because this function blocks !
1333                         //destroy_workqueue(drdy_completion_wq);
1334             printk(KERN_ERR "CGX_Deinit (2)");
1335         }
1336         #endif
1337 #if 0
1338         DrvContext.state.request.terminate = TRUE;
1339         if(DrvContext.chunk.ptr) {
1340                 BOOL boo = FreePhysMem(DrvContext.chunk.ptr);
1341         }
1342 #endif
1343     printk(KERN_ERR "CGX_Deinit (3)");
1344
1345     //free_irq(TEMPLATE_CPU_DMA_IRQ, NULL);
1346
1347 #ifndef CGCORE_ACCESS_VIA_SPI
1348         sprd_put_rf2351_ops(&gps_rf_ops);
1349 #endif
1350         CgxDriverFreeInternalBuff(&DrvContext, 0);
1351
1352         cdev_del(&DrvContext.cdev);
1353
1354     device_destroy(gps_class, MKDEV(cgxdrv_major, 0));
1355     class_destroy(gps_class);
1356
1357         unregister_chrdev_region(MKDEV(cgxdrv_major, 0), 1);
1358 #ifdef CGCORE_ACCESS_VIA_SPI
1359         gpsspidev_exit();
1360 #endif
1361     printk(KERN_ERR "CGX_Deinit out");
1362 }
1363
1364
1365 late_initcall(CGX_Init);
1366 module_exit(CGX_Deinit);
1367
1368
1369 MODULE_LICENSE("GPL and additional rights");
1370 MODULE_AUTHOR("Pablo 'merKur' Kohan <pablo@ximpo.com> - for CellGuide Ltd.");
1371 MODULE_DESCRIPTION("CellGuide GPSense CGX3XXX/CGX5XXX GPS CoProcessor driver");
1372
1373 /** \endcond */