summaryrefslogtreecommitdiff
path: root/drivers/misc/gpsip
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/misc/gpsip
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/misc/gpsip')
-rw-r--r--drivers/misc/gpsip/Kconfig23
-rw-r--r--drivers/misc/gpsip/Makefile2
-rw-r--r--drivers/misc/gpsip/VirtualCom/Makefile53
-rw-r--r--drivers/misc/gpsip/VirtualCom/README.txt9
-rw-r--r--drivers/misc/gpsip/VirtualCom/bld.sh28
-rw-r--r--drivers/misc/gpsip/VirtualCom/virt_uart.c666
-rw-r--r--drivers/misc/gpsip/cgdriver/CgBuildNumber.h7
-rw-r--r--drivers/misc/gpsip/cgdriver/CgCpu.c180
-rw-r--r--drivers/misc/gpsip/cgdriver/CgCpu.h1644
-rw-r--r--drivers/misc/gpsip/cgdriver/CgCpuLinux.c229
-rw-r--r--drivers/misc/gpsip/cgdriver/CgCpuOs.h176
-rw-r--r--drivers/misc/gpsip/cgdriver/CgReturnCodes.h172
-rw-r--r--drivers/misc/gpsip/cgdriver/CgTypes.h227
-rw-r--r--drivers/misc/gpsip/cgdriver/CgVersion.h72
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverApi.h436
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverCore.c819
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverCore.h255
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.c441
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.h66
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverLinux.c1373
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverOs.h206
-rw-r--r--drivers/misc/gpsip/cgdriver/CgxDriverPlatform.h138
-rw-r--r--drivers/misc/gpsip/cgdriver/Makefile98
-rw-r--r--drivers/misc/gpsip/cgdriver/gps_dma.c302
-rw-r--r--drivers/misc/gpsip/cgdriver/gps_dma.h89
-rw-r--r--drivers/misc/gpsip/cgdriver/gps_gpio.c201
-rw-r--r--drivers/misc/gpsip/cgdriver/gpsspi.c459
-rw-r--r--drivers/misc/gpsip/cgdriver/platform.c770
-rw-r--r--drivers/misc/gpsip/cgdriver/platform.h250
29 files changed, 9391 insertions, 0 deletions
diff --git a/drivers/misc/gpsip/Kconfig b/drivers/misc/gpsip/Kconfig
new file mode 100644
index 00000000..8e631144
--- /dev/null
+++ b/drivers/misc/gpsip/Kconfig
@@ -0,0 +1,23 @@
+config CGX
+ bool "Sprd gps"
+ default n
+ help
+ GPS can locate you position
+
+config CGX_DRIVER
+ tristate "Sprd gps driver"
+ depends on CGX
+ help
+ GPS can locate you position
+
+config CGX_VIRTUALCOM
+ tristate "Sprd gps virtual com"
+ depends on CGX
+ help
+ GPS can locate you position
+
+config CGX_GE_GPS
+ tristate "Sprd greeneye gps use spi interface"
+ depends on CGX
+ help
+ GPS can locate you position
diff --git a/drivers/misc/gpsip/Makefile b/drivers/misc/gpsip/Makefile
new file mode 100644
index 00000000..e526efd0
--- /dev/null
+++ b/drivers/misc/gpsip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CGX_DRIVER) += cgdriver/
+obj-$(CONFIG_CGX_VIRTUALCOM) += VirtualCom/
diff --git a/drivers/misc/gpsip/VirtualCom/Makefile b/drivers/misc/gpsip/VirtualCom/Makefile
new file mode 100644
index 00000000..578b7b23
--- /dev/null
+++ b/drivers/misc/gpsip/VirtualCom/Makefile
@@ -0,0 +1,53 @@
+###############################################################################
+# LEGAL NOTICE #
+# #
+# USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND #
+# DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE #
+# WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT #
+# FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE #
+# OR DOCUMENTATION. #
+# NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR #
+# OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF #
+# THE LICENSE TERMS AS STATED. #
+# #
+###############################################################################
+# Version: 1.8.9/3686
+# Build : 13
+# Date : 12/08/2012
+
+
+ANDROID_NDK_ROOT := $(ROOT)/android/ndk
+ANDROID_SDK_ROOT := $(ROOT)/android/sdk
+PATH := $(PREBUILD)/bin:$(PATH)
+
+obj-$(CONFIG_CGX_VIRTUALCOM) := cgvuart.o
+
+# C Object Files:
+cgvuart-c-objs += virt_uart.o
+cgvuart-objs += $(cgvuart-c-objs)
+
+# EXTRA_CFLAGS += -I$(PWD)
+
+
+ifeq ($(KERNELRELEASE),)
+# on first call from remote location we get into this path
+# whilst on second call all is managed by the embedding kernel makefile
+
+cgvuart-cfiles = ${cgvuart-c-objs:.o=.c}
+
+default:: kmod_build
+
+kmod_build:: $(cgvuart-cfiles) $(cgvuart-hdrs)
+ $(MAKE) -C $(CG_KERNEL_DIR) SUBDIRS=$(CURDIR) modules
+
+# distclean:: clean
+
+clean::
+ rm -f *.o *.ko .*.cmd cgvuart.mod.c
+ rm -rf .tmp_versions
+
+tags::
+ $(MAKE) -C $(CG_KERNEL_DIR) SUBDIRS=$(CURDIR) tags
+endif
+
+# ### EOF ###
diff --git a/drivers/misc/gpsip/VirtualCom/README.txt b/drivers/misc/gpsip/VirtualCom/README.txt
new file mode 100644
index 00000000..4598a116
--- /dev/null
+++ b/drivers/misc/gpsip/VirtualCom/README.txt
@@ -0,0 +1,9 @@
+This is what is needed, in order to build the cgvuart driver :
+
+1. edit bld.sh, and change the following exports:
+ a. ROOT holds under it, "/android/ndk/" and "/android/sdk".
+ b. CG_KERNEL_DIR holds under it, the kernel source tree
+ c. Set ARCH=arm
+ d. Set CROSS_COMPILE=<tool chain prefix>
+ An example : $ export CROSS_COMPILE="/home/cellguide/android/froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-"
+2. Run bld.sh
diff --git a/drivers/misc/gpsip/VirtualCom/bld.sh b/drivers/misc/gpsip/VirtualCom/bld.sh
new file mode 100644
index 00000000..7fdf4194
--- /dev/null
+++ b/drivers/misc/gpsip/VirtualCom/bld.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+export ROOT=/home/cellguide
+export CG_KERNEL_DIR=/home/cellguide/android/kernel/Telechips/tcc8900_2010_06_22/kernel
+export ARCH=arm
+export CROSS_COMPILE=/home/cellguide/android/froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+echo
+make -f Makefile $*
diff --git a/drivers/misc/gpsip/VirtualCom/virt_uart.c b/drivers/misc/gpsip/VirtualCom/virt_uart.c
new file mode 100644
index 00000000..780fa454
--- /dev/null
+++ b/drivers/misc/gpsip/VirtualCom/virt_uart.c
@@ -0,0 +1,666 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+#define __VIRT_UART_C__
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/uaccess.h>
+#include <linux/hardirq.h>
+#include <linux/serial.h>
+#include <linux/spinlock.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#define MODULE_NAME "virt_uart"
+#define DRIVER_NAME "virt_uart"
+#define DEVICE_NAME "ttyV"
+
+/* 0 = dynamic major */
+#define XVU_MAJOR 0
+
+/* Number of Virtual UART pairs */
+#define XVU_PAIRS 1
+
+#define XVU_ERR( fmt, arg...) do { printk(KERN_ERR MODULE_NAME " %s:%d [%s]... " fmt, __FILE__, __LINE__, __func__, ## arg ); } while (0)
+
+#if defined(CGTEST) || defined(DEBUG)
+# define XVU_DBG( fmt, arg...) do { printk(KERN_ERR MODULE_NAME " %s:%d [%s]... " fmt, __FILE__, __LINE__, __func__, ## arg ); } while (0)
+#else
+# define XVU_DBG( fmt, arg...) do { } while (0)
+#endif
+
+typedef struct xvu_endpoint_s {
+ int open_count;
+ struct tty_struct *tty;
+ int mcr; /* Modem Control Register */
+ int msr; /* Modem Status Register */
+ wait_queue_head_t msr_wait;
+ spinlock_t sercnt_lock;
+ struct serial_icounter_struct ser_cnt;
+} xvu_endpoint_t;
+
+typedef struct xvu_dev_s {
+ struct semaphore sem;
+ xvu_endpoint_t endpoint[XVU_PAIRS * 2];
+} xvu_dev_t;
+
+
+static struct tty_driver *xvu_ttydriver = NULL;
+static xvu_dev_t xvu_dev;
+static struct tty_port xvu_port[2];
+
+
+#define __XVU_GetPeerIdx(idx) ( (idx) ^ 0x01 )
+
+//bxd
+#define init_MUTEX(sem) sema_init(sem, 1)
+
+/*
+ * __XVU_SetMSR
+ *
+ * This sets the MSR (Modem Status Register), upon its peer's MCR (Modem Control
+ * Register).
+ * It also updates counters accordingly, and awakes potential TIOCMIWAITers.
+ * **** It should be called with the xvu_dev.sem held ! ****
+ */
+static void __XVU_SetMSR( unsigned int idx )
+{
+ unsigned int peermcr = 0;
+ unsigned int oldmsr = 0;
+ unsigned int msr = 0;
+ unsigned long flags = 0;
+
+ peermcr = xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].mcr;
+ msr = oldmsr = xvu_dev.endpoint[idx].msr;
+
+ XVU_DBG( "msr[%d] = 0x%08x\n", idx, msr );
+
+ /* Peer is closed, set msr to 0 */
+ if ( !xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].open_count) {
+ XVU_DBG( "Peer(%d) is closed... Setting msr as 0\n", __XVU_GetPeerIdx(idx) );
+ msr = 0;
+ goto out;
+ }
+
+ /*
+ * Peer is open.
+ * Update MSR upon peer's MCR
+ */
+ if ( peermcr & TIOCM_DTR )
+ msr |= (TIOCM_DSR | TIOCM_CAR);
+ else
+ msr &= ~(TIOCM_DSR | TIOCM_CAR);
+
+ if ( peermcr & TIOCM_RTS )
+ msr |= (TIOCM_CTS);
+ else
+ msr &= ~(TIOCM_CTS);
+
+out:
+ xvu_dev.endpoint[idx].msr = msr;
+
+ /* Mask transitions (unchanged bits will be 0) */
+ msr ^= oldmsr;
+ if (msr) {
+ XVU_DBG( "Transitioning...\n" );
+ /* Update counters for TIOCGICOUNT */
+ spin_lock_irqsave(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+ if ( msr & TIOCM_DSR ) xvu_dev.endpoint[idx].ser_cnt.dsr++;
+ if ( msr & TIOCM_CAR ) xvu_dev.endpoint[idx].ser_cnt.dcd++;
+ if ( msr & TIOCM_CTS ) xvu_dev.endpoint[idx].ser_cnt.cts++;
+ spin_unlock_irqrestore(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+
+ /* MSR changed. Awake TIOCMIWAITers */
+ wake_up_interruptible(&xvu_dev.endpoint[idx].msr_wait);
+ }
+}
+
+
+/*
+ * __XVU_SetMCR
+ *
+ * This sets the MCR (Modem Control Register), and updates its peer's MSR (Modem
+ * Status Register).
+ * **** It should be called with the xvu_dev.sem held ! ****
+ */
+static void __XVU_SetMCR( unsigned int idx, unsigned int val )
+{
+ /* Set MSR */
+ xvu_dev.endpoint[idx].mcr = val;
+
+ XVU_DBG( "Setting MCR[%d]=0x%08x\n", idx, val );
+
+ /* Update peer's MSR */
+ __XVU_SetMSR( __XVU_GetPeerIdx(idx) );
+}
+
+static int XVU_write(struct tty_struct *tty, const unsigned char *buffer,
+ int count)
+{
+ int idx = 0;
+ struct tty_struct *peer = NULL;
+ int rv = -EINVAL;
+ unsigned long flags = 0;
+
+ if (down_interruptible(&xvu_dev.sem))
+ return -ERESTARTSYS;
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ goto out;
+ }
+
+ if (buffer == NULL) {
+ XVU_ERR( "Invalid (NULL) buffer\n");
+ goto out;
+ }
+
+ if (count <= 0 ) {
+ XVU_ERR( ": Invalid count = 0\n");
+ goto out;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ goto out;
+ }
+
+
+ /* Is endpoint open ? */
+ if (! xvu_dev.endpoint[idx].open_count ) {
+ XVU_ERR( "Endpoint %d doesn't seem to be open.\n", idx);
+ goto out;
+ }
+
+ /*
+ * Send string to peer
+ * If peer is closed, discard the string...
+ * ...but return count as if we sent it.
+ */
+
+ /* Is peer open ? */
+ if (! xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].open_count ) {
+ /* Discard sent bytes ! */
+ rv = count;
+ goto out;
+ }
+
+ /* Safety ! Shouldn't happen !!! */
+ peer = xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].tty;
+ if (! peer ) {
+ /* Discard sent bytes ! */
+ XVU_ERR( "endpoint[%d].tty is NULL\n", __XVU_GetPeerIdx(idx));
+ rv = count;
+ goto out;
+ }
+
+ rv = tty_buffer_request_room(tty->port, count);
+ if (unlikely(rv == 0)) {
+ XVU_ERR("tty_buffer_request_room rv:%d\n",rv);
+ }
+ rv = tty_insert_flip_string(peer->port, buffer, count);
+ tty_schedule_flip(peer->port);
+
+out:
+ /* Update counters */
+ if (rv > 0) {
+ spin_lock_irqsave(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+ xvu_dev.endpoint[ idx ].ser_cnt.tx += rv;
+ spin_unlock_irqrestore(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+
+ spin_lock_irqsave(&xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].sercnt_lock, flags);
+ xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].ser_cnt.rx += rv;
+ spin_unlock_irqrestore(&xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].sercnt_lock, flags);
+ }
+
+ up(&xvu_dev.sem);
+ return rv;
+}
+
+
+static int XVU_open(struct tty_struct *tty, struct file *filp)
+{
+ int idx = 0;
+ int rv = -EINVAL;
+ int idx2 = 0;
+
+ if (down_interruptible(&xvu_dev.sem))
+ return -ERESTARTSYS;
+
+ if (tty == NULL) {
+ XVU_ERR( ": Invalid (NULL) tty_struct\n");
+ goto out;
+ }
+
+ idx = tty->index;
+ idx2 = (int)(idx/2);
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ goto out;
+ }
+
+ tty->driver_data = (void *)idx;
+
+ /* Safety ! Shouldn't happen !!! */
+ if ( (xvu_dev.endpoint[idx].tty) && (xvu_dev.endpoint[idx].tty != tty) ) {
+ XVU_ERR( "Endpoint[%d].tty=%p != tty=%p\n",
+ idx, xvu_dev.endpoint[idx].tty, tty);
+ }
+
+ xvu_dev.endpoint[idx].tty = tty;
+ xvu_dev.endpoint[idx].open_count++;
+
+ XVU_DBG( "Opening %d(count=%d)... TTY=%p\n", idx, xvu_dev.endpoint[idx].open_count, tty );
+
+ __XVU_SetMCR(idx, TIOCM_DTR | TIOCM_RTS);
+ rv = 0;
+
+out:
+ up(&xvu_dev.sem);
+
+
+ return rv;
+}
+
+
+static void XVU_close(struct tty_struct *tty, struct file *filp)
+{
+ int idx = 0;
+ int idx2 = 0;
+ down(&xvu_dev.sem);
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ goto out;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ goto out;
+ }
+
+ /* Is endpoint open ? */
+ if (! xvu_dev.endpoint[idx].open_count ) {
+ XVU_ERR( "Endpoint %d doesn't seem to be open.\n", idx);
+ goto out;
+ }
+
+ XVU_DBG( "Closing %d\n", idx );
+ xvu_dev.endpoint[idx].open_count--;
+
+ idx2 = (int)(idx/2);
+ if ((xvu_dev.endpoint[idx2].open_count <= 0) && (xvu_dev.endpoint[idx2+1].open_count <= 0)) {
+ /* No more users holding this device */
+ XVU_ERR( "No more users holding this device\n");
+ xvu_dev.endpoint[idx].tty = NULL;
+ wake_up_interruptible(&xvu_dev.endpoint[idx].msr_wait);
+ __XVU_SetMCR(idx, 0);
+ }
+
+out:
+ up(&xvu_dev.sem);
+}
+
+
+static int XVU_write_room(struct tty_struct *tty)
+{
+ int idx = 0;
+ struct tty_struct *peer = NULL;
+ struct tty_buffer *b = NULL;
+ unsigned long flags = 0;
+ int rv = -EINVAL;
+
+ down(&xvu_dev.sem);
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ goto out;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ goto out;
+ }
+
+ /* is endpoint open ? */
+ if (! xvu_dev.endpoint[idx].open_count ) {
+ XVU_ERR( "Endpoint %d doesn't seem to be open.\n", idx);
+ goto out;
+ }
+
+ /* Is peer open ? */
+ if (! xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].open_count ) {
+ /* We'll discard sent bytes anyway, so... lie ! */
+ rv = 255;
+ goto out;
+ }
+
+ /* Safety ! Shouldn't happen !!! */
+ peer = xvu_dev.endpoint[__XVU_GetPeerIdx(idx)].tty;
+ if (! peer ) {
+ /* We'll discard sent bytes anyway, so... lie ! */
+ XVU_ERR( "Endpoint[%d].tty is NULL\n", __XVU_GetPeerIdx(idx));
+ rv = 255;
+ goto out;
+ }
+
+ /*
+ * Calculate how much room is left in the peer buffer
+ */
+ spin_lock_irqsave(&peer->port->buf.lock, flags);
+
+ b = peer->port->buf.tail;
+ if (b != NULL)
+ rv = b->size - b->used;
+ else
+ rv = 0;
+
+ spin_unlock_irqrestore(&peer->port->buf.lock, flags);
+
+out:
+ up(&xvu_dev.sem);
+
+ return rv;
+}
+
+
+/*
+ * Needed to avoid Oops on poll !
+ */
+static int XVU_chars_in_buffer(struct tty_struct *tty)
+{
+ return 0;
+}
+
+
+//static int XVU_tiocmget(struct tty_struct *tty, struct file *filp)
+static int XVU_tiocmget(struct tty_struct *tty)
+{
+ int idx = 0;
+ int rv = -EINVAL;
+
+ if (down_interruptible(&xvu_dev.sem))
+ return -ERESTARTSYS;
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ goto out;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( ": Index %d out of range.\n", idx);
+ goto out;
+ }
+
+ rv = (xvu_dev.endpoint[idx].mcr | xvu_dev.endpoint[idx].msr);
+
+ XVU_DBG( "In tiocmget(%d) returning: 0x%08x\n", idx, rv );
+
+out:
+ up(&xvu_dev.sem);
+
+ return rv;
+}
+
+
+//static int XVU_tiocmset(struct tty_struct *tty, struct file *filp,
+// unsigned int set, unsigned int clear)
+static int XVU_tiocmset(struct tty_struct *tty,
+ unsigned int set, unsigned int clear)
+
+{
+ int idx = 0;
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ return -EINVAL;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ return -EINVAL;
+ }
+
+ /* Only accept RTS and DTR flag changes */
+ set &= (TIOCM_RTS | TIOCM_DTR);
+ clear &= (TIOCM_RTS | TIOCM_DTR);
+
+ XVU_DBG( "In tiocmset(%d) SET=0x%08x CLR=0x%08x\n", idx, set, clear );
+
+ if (down_interruptible(&xvu_dev.sem))
+ return -ERESTARTSYS;
+ __XVU_SetMCR( idx, ( (xvu_dev.endpoint[idx].mcr | set) & (~clear) ) );
+ up(&xvu_dev.sem);
+
+ return 0;
+}
+
+
+static int __XVU_tiocmiwait(struct tty_struct *tty, unsigned long arg)
+{
+ int idx = 0;
+ int rv= -EINVAL;
+ struct serial_icounter_struct cnow = {0};
+ struct serial_icounter_struct cprev = {0};
+ unsigned long flags = 0;
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ return -EINVAL;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+ cnow = xvu_dev.endpoint[idx].ser_cnt;
+
+ XVU_DBG( "In tiocmiwait(%d) waiting: 0x%08lx now={CTS=%d, DCD=%d, RNG=%d, DSR=%d}\n", idx, arg, cnow.cts, cnow.dcd, cnow.rng, cnow.dsr );
+
+ spin_unlock_irqrestore(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+
+ rv = wait_event_interruptible( xvu_dev.endpoint[idx].msr_wait, ({
+ cprev = cnow;
+ spin_lock_irqsave(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+ cnow = xvu_dev.endpoint[idx].ser_cnt;
+ spin_unlock_irqrestore(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+
+ /* Device closed or serial counters changed */
+ (xvu_dev.endpoint[idx].open_count == 0) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ||
+ ((arg & TIOCM_CAR) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr));
+ }));
+
+ XVU_DBG( "In tiocmiwait(%d) done wait: 0x%08lx now={CTS=%d, DCD=%d, RNG=%d, DSR=%d}\n", idx, arg, cnow.cts, cnow.dcd, cnow.rng, cnow.dsr );
+
+ if (rv < 0) {
+ XVU_DBG( "In tiocmiwait(%d) rv=%d, returning: ERESTARTSYS\n", idx, rv );
+ return -ERESTARTSYS;
+ }
+
+ /*
+ * return -EIO if we were awoken by device being closed
+ */
+ if (xvu_dev.endpoint[idx].open_count == 0) {
+ XVU_DBG( "In tiocmiwait(%d) returning: EIO\n", idx );
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+//static int XVU_ioctl(struct tty_struct *tty, struct file *filp,
+// unsigned int cmd, unsigned long arg)
+static int XVU_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg)
+
+{
+ int idx = 0;
+ struct serial_icounter_struct icnt = {0};
+ unsigned long flags = 0;
+
+ if (tty == NULL) {
+ XVU_ERR( "Invalid (NULL) tty_struct\n");
+ return -EINVAL;
+ }
+
+ idx = tty->index;
+
+ if ( (idx<0) || (idx >= XVU_PAIRS*2) || (idx != (int)tty->driver_data) ) {
+ XVU_ERR( "Index %d out of range.\n", idx);
+ return -EINVAL;
+ }
+
+ if (cmd == TIOCMIWAIT)
+ return __XVU_tiocmiwait( tty, arg );
+
+ if (cmd == TIOCGICOUNT) {
+ spin_lock_irqsave(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+ icnt = xvu_dev.endpoint[idx].ser_cnt;
+ spin_unlock_irqrestore(&xvu_dev.endpoint[idx].sercnt_lock, flags);
+
+ if ( copy_to_user( (void __user *)arg, &icnt, sizeof(icnt)) )
+ return -EFAULT;
+ else
+ return 0;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+
+static struct tty_operations serial_ops = {
+ open: XVU_open,
+ close: XVU_close,
+ write: XVU_write,
+ write_room: XVU_write_room,
+ chars_in_buffer: XVU_chars_in_buffer,
+ tiocmget: XVU_tiocmget,
+ tiocmset: XVU_tiocmset,
+ ioctl: XVU_ioctl,
+};
+
+
+/*
+ * Module Initialization and Cleanup
+ */
+static int __init XVU_Init(void)
+{
+ int rv = -EINVAL;
+ int i = 0;
+
+ memset(&xvu_dev, 0, sizeof(xvu_dev));
+ init_MUTEX(&xvu_dev.sem);
+ for (i=0;i<XVU_PAIRS * 2; i++)
+ init_waitqueue_head(&xvu_dev.endpoint[i].msr_wait);
+
+ /* allocate the tty driver with 2 minor devices per pair */
+ xvu_ttydriver = alloc_tty_driver( XVU_PAIRS * 2);
+ if (!xvu_ttydriver)
+ return -ENOMEM;
+
+ tty_port_init(&xvu_port[0]);
+ tty_port_init(&xvu_port[1]);
+
+ /* initialize the tty driver */
+ xvu_ttydriver->owner = THIS_MODULE;
+ xvu_ttydriver->driver_name = DRIVER_NAME;
+ xvu_ttydriver->name = DEVICE_NAME;
+ xvu_ttydriver->major = XVU_MAJOR;
+ xvu_ttydriver->minor_start = 0;
+ xvu_ttydriver->type = TTY_DRIVER_TYPE_SERIAL;
+ xvu_ttydriver->subtype = SERIAL_TYPE_NORMAL;
+ xvu_ttydriver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
+ xvu_ttydriver->init_termios = tty_std_termios;
+ xvu_ttydriver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty_set_operations(xvu_ttydriver, &serial_ops);
+ tty_port_link_device(&xvu_port[0], xvu_ttydriver, 0);
+ tty_port_link_device(&xvu_port[1], xvu_ttydriver, 1);
+
+ /* register the tty driver */
+ rv = tty_register_driver(xvu_ttydriver);
+ if (rv) {
+ printk(KERN_ERR MODULE_NAME ": Failed to register Virtual UART tty driver");
+ put_tty_driver(xvu_ttydriver);
+ return rv;
+ }
+
+ down(&xvu_dev.sem);
+ for (i=0;i<XVU_PAIRS * 2; i++)
+ {
+ spin_lock_init(&xvu_dev.endpoint[i].sercnt_lock);
+ __XVU_SetMSR(i);
+ }
+ up(&xvu_dev.sem);
+
+ printk(KERN_INFO MODULE_NAME ": Virtual UART Device Ready... Major DevId: %d\n", xvu_ttydriver->major );
+ printk(KERN_INFO MODULE_NAME ": Created %d Virtual UARTs. /dev/ttyV0 -> /dev/ttyV%d\n", XVU_PAIRS*2, XVU_PAIRS*2 -1 );
+ return 0;
+}
+
+
+static void __exit XVU_Deinit(void)
+{
+ int idx = 0;
+
+ down(&xvu_dev.sem);
+
+ /* Report unclosed pending endpoints (in case of forced unload) */
+ for (idx = 0; idx < XVU_PAIRS * 2; idx++)
+ if ( xvu_dev.endpoint[idx].open_count )
+ XVU_ERR( "Endpoint[%d].open_count=%d != 0\n",
+ idx, xvu_dev.endpoint[idx].open_count );
+
+ if (xvu_ttydriver)
+ tty_unregister_driver(xvu_ttydriver);
+
+ put_tty_driver(xvu_ttydriver);
+
+ up(&xvu_dev.sem);
+
+ printk(KERN_INFO MODULE_NAME ": Virtual UART Device Unloaded...\n" );
+}
+
+module_init(XVU_Init);
+module_exit(XVU_Deinit);
+
+MODULE_AUTHOR("Pablo 'merKur' Kohan <pablo@ximpo.com>");
+MODULE_DESCRIPTION("Virtual UART-pair");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/gpsip/cgdriver/CgBuildNumber.h b/drivers/misc/gpsip/cgdriver/CgBuildNumber.h
new file mode 100644
index 00000000..ae99f989
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgBuildNumber.h
@@ -0,0 +1,7 @@
+/* this file is automatically updated on build - DO NOT CHANGE! */
+
+#define CG_BUILD_NUMBER "13"
+#define CG_BUILD_DATE "12/08/2012"
+#define CG_BUILD_TIME "18:56:47"
+#define CG_BUILD_VERSION "1.8.9/3686"
+#define CG_BUILD_ORIGINATOR "Koby"
diff --git a/drivers/misc/gpsip/cgdriver/CgCpu.c b/drivers/misc/gpsip/cgdriver/CgCpu.c
new file mode 100644
index 00000000..955ba980
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgCpu.c
@@ -0,0 +1,180 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CellGuide Common code
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include "CgxDriverCore.h"
+#include "CgCpu.h"
+// Swap helper functions
+TCgByteSwapType CgGetByteSwapTypeU32(TCgByteOrder aFrom, TCgByteOrder aTo);
+void * CgGetSwapFunctionU32(TCgByteSwapType type);
+
+
+static const U32 fullMask[32] = {
+ 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
+ 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
+ 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
+ 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
+ 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
+ 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
+ 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
+ 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF };
+
+U32 CgGetU32Mask(U32 bitsInU32)
+{
+ return fullMask[bitsInU32];
+}
+
+TCgReturnCode CgSetRegisterBits(volatile U32 *aReg, TCgBitField aBitFieldDef, U32 aValue)
+{
+
+ U32 value = aValue & fullMask[aBitFieldDef.length-1];
+ U32 mask = (fullMask[aBitFieldDef.length-1]) & ~value;
+
+ // clear
+ *aReg &= ~(mask << aBitFieldDef.start);
+ // set
+ *aReg |= (value << aBitFieldDef.start);
+ return ECgOk;
+}
+
+
+TCgReturnCode CgGetRegisterBits(volatile U32 aReg, TCgBitField aBitFieldDef, U32 *apValue)
+{
+
+ *apValue = ((aReg) >> aBitFieldDef.start) & fullMask[aBitFieldDef.length-1];
+
+ return ECgOk;
+}
+
+
+TCgByteSwapType CgGetByteSwapTypeU32(TCgByteOrder aFrom, TCgByteOrder aTo)
+{
+ switch (aFrom){
+ case ECG_BYTE_ORDER_1234 :
+ switch( aTo ){
+ case ECG_BYTE_ORDER_1234 : return ECG_SWAP_NONE;
+ case ECG_BYTE_ORDER_2143 : return ECG_SWAP_BYTES;
+ case ECG_BYTE_ORDER_3412 : return ECG_SWAP_WORDS;
+ case ECG_BYTE_ORDER_4321 : return ECG_SWAP_BYTES_AND_WORDS;
+ }
+ break;
+ case ECG_BYTE_ORDER_2143 :
+ switch( aTo ){
+ case ECG_BYTE_ORDER_1234 : return ECG_SWAP_BYTES;
+ case ECG_BYTE_ORDER_2143 : return ECG_SWAP_NONE;
+ case ECG_BYTE_ORDER_3412 : return ECG_SWAP_BYTES_AND_WORDS;
+ case ECG_BYTE_ORDER_4321 : return ECG_SWAP_WORDS;
+ }
+ break;
+ case ECG_BYTE_ORDER_3412 :
+ switch( aTo ) {
+ case ECG_BYTE_ORDER_1234 : return ECG_SWAP_WORDS;
+ case ECG_BYTE_ORDER_2143 : return ECG_SWAP_BYTES_AND_WORDS;
+ case ECG_BYTE_ORDER_3412 : return ECG_SWAP_NONE;
+ case ECG_BYTE_ORDER_4321 : return ECG_SWAP_BYTES;
+ }
+ break;
+ case ECG_BYTE_ORDER_4321 :
+ switch( aTo ) {
+ case ECG_BYTE_ORDER_1234 : return ECG_SWAP_BYTES_AND_WORDS;
+ case ECG_BYTE_ORDER_2143 : return ECG_SWAP_WORDS;
+ case ECG_BYTE_ORDER_3412 : return ECG_SWAP_BYTES;
+ case ECG_BYTE_ORDER_4321 : return ECG_SWAP_NONE;
+ }
+ break;
+ default :
+ return ECG_SWAP_NONE;
+ break;
+ }
+
+ return ECG_SWAP_NONE;
+}
+
+
+
+TCgReturnCode CgSwapBytesInBlock(void * aSource,void * aDest, long aSizeInBytes, TCgByteOrder aFrom, TCgByteOrder aTo)
+{
+ TCgReturnCode rc = ECgOk;
+
+ long index = 0, sizeInDword = 0;
+ u32* source = NULL, * dest = NULL;
+ TCgByteSwapType swapType = CgGetByteSwapTypeU32(aFrom, aTo);
+
+ sizeInDword = aSizeInBytes / 4;
+ source = (u32*)aSource;
+ dest = (u32*)aDest;
+
+ switch (swapType) {
+ case ECG_SWAP_NONE :
+ break;
+
+ case ECG_SWAP_BYTES :
+ for ( ; index < sizeInDword; index ++ )
+ dest[index] = CgSwapBytesU32(source[index]);
+ break;
+
+ case ECG_SWAP_WORDS :
+ for ( ; index < sizeInDword; index ++ )
+ dest[index] = CgSwapWordsU32(source[index]);
+ break;
+
+ case ECG_SWAP_BYTES_AND_WORDS :
+ for ( ; index < sizeInDword; index ++ )
+ dest[index] = CgSwapBytesAndWordsU32(source[index]);
+ break;
+ }
+
+
+ return rc;
+}
+
+TCgReturnCode CgCpuDelay(unsigned long aCount)
+{
+ volatile unsigned long cnt = 0;
+ volatile unsigned long z =2 ;
+ for(cnt = 0; cnt<aCount; cnt++) {
+ z *=2;
+ }
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuRFControlWriteByte(unsigned char aValue)
+{
+ printk(" CgCpuControlWriteByte.\n");
+ if(aValue == 1)
+ CgxDriverRFPowerUp();
+ else if(aValue == 0)
+ CgxDriverRFPowerDown();
+ else
+ printk(" invalid arg.\n");
+ return ECgOk;
+}
+
+#ifdef CG_STORE_ERROR_LINE
+ BOOL cgRetCode_store_error_line(const char * aFileName, long lineNumber, TCgReturnCode aRc) {
+ return TRUE;
+ }
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgCpu.h b/drivers/misc/gpsip/cgdriver/CgCpu.h
new file mode 100644
index 00000000..de064b00
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgCpu.h
@@ -0,0 +1,1644 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CPU API
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+ CellGuide's API to access low-level CPU resources
+
+ The API is used by CellGuide drivers and applications that require access to low-level CPU resources
+ like DMA, SPI.
+
+ CPU depended code is divided to the following API groups:
+ \li \ref cg_cpu_clk
+ \li \ref cg_cpu_dma
+ \li \ref cg_cpu_gpio
+ \li \ref cg_cpu_spi
+ \li \ref cg_cpu_interrupt
+ \li \ref cg_cpu_rtc
+ \li \ref cg_cpu_miscellanies
+*/
+
+#ifndef CG_CPU_H
+#define CG_CPU_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif /*__cplusplus*/
+
+// ===========================================================================
+
+#include "CgTypes.h"
+#include "CgReturnCodes.h"
+#include "CgCpuOs.h"
+
+// ===========================================================================
+
+/** helper macro to calculate minimum of 2 numbers */
+#ifndef MIN
+ #define MIN(__a__, __b__) ((__a__) < (__b__) ? (__a__) : (__b__))
+#endif
+
+/** helper macro to align memory */
+#ifndef ALLIGN
+ #define ALLIGN(__var__,__base__) ((__var__)%(__base__)) ? __var__ = (__base__) * ((U32)((__var__) / (__base__)) + 1) : (__var__)
+#endif
+
+/** helper macro to find the ceiling of a number */
+#ifndef DIV_CEIL
+ #define DIV_CEIL(__counter__,__devider__) ( ((__counter__) + (__devider__) -1) / (__devider__) )
+#endif
+
+/** Undefined addresss means the address needs to be filled during porting **/
+#define CG_UNDEFINED_ADDRESS (0xFFFFFFFF)
+
+/** helper macro to get the 'controller' part of a channel code */
+#define CG_CONTROLLER(ch) (ch & 0xFFFF0000)
+
+/** helper macro to get the 'channel' part of a channel code */
+#define CG_CHANNEL(ch) (ch & 0x0000FFFF)
+
+/** helper macro to check NULL pointer in argument */
+#define ASSERT_NOT_NULL(p) if (p == NULL) return ECgNullPointer;
+
+/** helper macro to calculate register index from it's offset */
+#define REGIDX(offset) (offset/4)
+
+
+/** Bit field definition
+ This structure is used to define a sub-register bit field, with arbitrary size.
+ */
+typedef struct {
+ U32 start; /**< start bit (0 based) 0 == LSB */
+ U32 length; /**< length of bit field (1-32) */
+ U32 defaultValue; /**< default value */
+} TCgBitField;
+
+
+#define CG_CPU_DEVICE_SPI (1)
+
+#define CG_CPU_SPI_MODE_DMA (0) /**< Use DMA to handle SPI communication */
+#define CG_CPU_SPI_MODE_MANUAL (1) /**< Use polling to handle SPI communication */
+
+/** \name Controllers logical codes
+\{
+*/
+
+
+/**
+DMA Controller logical unit code
+\note Do not change; this value is used internally in the driver
+\ingroup cg_cpu_dma
+*/
+#define CG_CPU_CONTROLLER_DMA (0x00020000)
+
+/**
+SPI Controller logical unit code
+\note Do not change; this value is used internally in the driver
+\ingroup cg_cpu_spi
+*/
+#define CG_CPU_CONTROLLER_SPI (0x00030000)
+
+/**
+GPIO Controller logical unit code
+\note Do not change; this value is used internally in the driver
+\ingroup cg_cpu_gpio
+*/
+#define CG_CPU_CONTROLLER_GPIO (0x00040000)
+
+
+
+/** \} Controllers logical codes*/
+
+/** Virtual GPIO groups definitions
+ These values are used to define CellGuide 'virtual' GPIO codes, later converted to specific
+ CPU GPIO register and pin.
+ */
+
+
+/** Maximum number of GPIOs in a group.
+ the number is artificial, and should be the largest GPIO group there is.
+*/
+#define CG_CPU_GPIO_GROUP_SIZE (128)
+
+#define CG_CPU_GPIO_GROUP_INDEX_A (1) /**< GPIO group A index */
+#define CG_CPU_GPIO_GROUP_INDEX_B (CG_CPU_GPIO_GROUP_INDEX_A+1) /**< GPIO group B index */
+#define CG_CPU_GPIO_GROUP_INDEX_C (CG_CPU_GPIO_GROUP_INDEX_B+1) /**< GPIO group C index */
+#define CG_CPU_GPIO_GROUP_INDEX_D (CG_CPU_GPIO_GROUP_INDEX_C+1) /**< GPIO group A index */
+#define CG_CPU_GPIO_GROUP_INDEX_E (CG_CPU_GPIO_GROUP_INDEX_D+1) /**< GPIO group A index */
+#define CG_CPU_GPIO_GROUP_INDEX_F (CG_CPU_GPIO_GROUP_INDEX_E+1) /**< GPIO group A index */
+#define CG_CPU_GPIO_GROUP_INDEX_G (CG_CPU_GPIO_GROUP_INDEX_F+1) /**< GPIO group G index */
+#define CG_CPU_GPIO_GROUP_INDEX_H (CG_CPU_GPIO_GROUP_INDEX_G+1) /**< GPIO group H index */
+#define CG_CPU_GPIO_GROUP_INDEX_I (CG_CPU_GPIO_GROUP_INDEX_H+1) /**< GPIO group I index */
+#define CG_CPU_GPIO_GROUP_INDEX_J (CG_CPU_GPIO_GROUP_INDEX_I+1) /**< GPIO group J index */
+#define CG_CPU_GPIO_GROUP_INDEX_K (CG_CPU_GPIO_GROUP_INDEX_J+1) /**< GPIO group K index */
+#define CG_CPU_GPIO_GROUP_INDEX_L (CG_CPU_GPIO_GROUP_INDEX_K+1) /**< GPIO group L index */
+#define CG_CPU_GPIO_GROUP_INDEX_M (CG_CPU_GPIO_GROUP_INDEX_L+1) /**< GPIO group M index */
+#define CG_CPU_GPIO_GROUP_INDEX_N (CG_CPU_GPIO_GROUP_INDEX_M+1) /**< GPIO group N index */
+#define CG_CPU_GPIO_GROUP_INDEX_O (CG_CPU_GPIO_GROUP_INDEX_N+1) /**< GPIO group O index */
+#define CG_CPU_GPIO_GROUP_INDEX_P (CG_CPU_GPIO_GROUP_INDEX_O+1) /**< GPIO group P index */
+#define CG_CPU_GPIO_GROUP_INDEX_Q (CG_CPU_GPIO_GROUP_INDEX_P+1) /**< GPIO group Q index */
+#define CG_CPU_GPIO_GROUP_INDEX_R (CG_CPU_GPIO_GROUP_INDEX_Q+1) /**< GPIO group R index */
+#define CG_CPU_GPIO_GROUP_INDEX_S (CG_CPU_GPIO_GROUP_INDEX_R+1) /**< GPIO group S index */
+#define CG_CPU_GPIO_GROUP_INDEX_T (CG_CPU_GPIO_GROUP_INDEX_S+1) /**< GPIO group T index */
+#define CG_CPU_GPIO_GROUP_INDEX_U (CG_CPU_GPIO_GROUP_INDEX_T+1) /**< GPIO group U index */
+#define CG_CPU_GPIO_GROUP_INDEX_V (CG_CPU_GPIO_GROUP_INDEX_U+1) /**< GPIO group V index */
+#define CG_CPU_GPIO_GROUP_INDEX_W (CG_CPU_GPIO_GROUP_INDEX_V+1) /**< GPIO group W index */
+#define CG_CPU_GPIO_GROUP_INDEX_X (CG_CPU_GPIO_GROUP_INDEX_W+1) /**< GPIO group X index */
+#define CG_CPU_GPIO_GROUP_INDEX_Y (CG_CPU_GPIO_GROUP_INDEX_X+1) /**< GPIO group Y index */
+#define CG_CPU_GPIO_GROUP_INDEX_Z (CG_CPU_GPIO_GROUP_INDEX_Y+1) /**< GPIO group Z index */
+#define CG_CPU_GPIO_GROUP_INDEX___ (CG_CPU_GPIO_GROUP_INDEX_Z+1)
+
+
+#define CG_CPU_GPIO_GROUP_A (CG_CPU_GPIO_GROUP_INDEX_A * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group A */
+#define CG_CPU_GPIO_GROUP_B (CG_CPU_GPIO_GROUP_INDEX_B * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group B */
+#define CG_CPU_GPIO_GROUP_C (CG_CPU_GPIO_GROUP_INDEX_C * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group C */
+#define CG_CPU_GPIO_GROUP_D (CG_CPU_GPIO_GROUP_INDEX_D * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group D */
+#define CG_CPU_GPIO_GROUP_E (CG_CPU_GPIO_GROUP_INDEX_E * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group E */
+#define CG_CPU_GPIO_GROUP_F (CG_CPU_GPIO_GROUP_INDEX_F * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group F */
+#define CG_CPU_GPIO_GROUP_G (CG_CPU_GPIO_GROUP_INDEX_G * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group G */
+#define CG_CPU_GPIO_GROUP_H (CG_CPU_GPIO_GROUP_INDEX_H * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group H */
+#define CG_CPU_GPIO_GROUP_I (CG_CPU_GPIO_GROUP_INDEX_I * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group I */
+#define CG_CPU_GPIO_GROUP_J (CG_CPU_GPIO_GROUP_INDEX_J * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group J */
+#define CG_CPU_GPIO_GROUP_K (CG_CPU_GPIO_GROUP_INDEX_K * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group K */
+#define CG_CPU_GPIO_GROUP_L (CG_CPU_GPIO_GROUP_INDEX_L * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group L */
+#define CG_CPU_GPIO_GROUP_M (CG_CPU_GPIO_GROUP_INDEX_M * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group M */
+#define CG_CPU_GPIO_GROUP_N (CG_CPU_GPIO_GROUP_INDEX_N * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group N */
+#define CG_CPU_GPIO_GROUP_O (CG_CPU_GPIO_GROUP_INDEX_O * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group O */
+#define CG_CPU_GPIO_GROUP_P (CG_CPU_GPIO_GROUP_INDEX_P * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group P */
+#define CG_CPU_GPIO_GROUP_Q (CG_CPU_GPIO_GROUP_INDEX_Q * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group Q */
+#define CG_CPU_GPIO_GROUP_R (CG_CPU_GPIO_GROUP_INDEX_R * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group R */
+#define CG_CPU_GPIO_GROUP_S (CG_CPU_GPIO_GROUP_INDEX_S * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group S */
+#define CG_CPU_GPIO_GROUP_T (CG_CPU_GPIO_GROUP_INDEX_T * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group T */
+#define CG_CPU_GPIO_GROUP_U (CG_CPU_GPIO_GROUP_INDEX_U * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group U */
+#define CG_CPU_GPIO_GROUP_V (CG_CPU_GPIO_GROUP_INDEX_V * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group V */
+#define CG_CPU_GPIO_GROUP_W (CG_CPU_GPIO_GROUP_INDEX_W * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group W */
+#define CG_CPU_GPIO_GROUP_X (CG_CPU_GPIO_GROUP_INDEX_X * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group X */
+#define CG_CPU_GPIO_GROUP_Y (CG_CPU_GPIO_GROUP_INDEX_Y * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group Y */
+#define CG_CPU_GPIO_GROUP_Z (CG_CPU_GPIO_GROUP_INDEX_Z * CG_CPU_GPIO_GROUP_SIZE) /**< 1st GPIO code in group Z */
+
+
+
+#define REG32(r) *((volatile U32*)(r))
+
+#define REG_GET1(aReg, aPin) \
+ ((aReg >> aPin) & 0x0001)
+
+#define REG_GET2(aReg, aPin) \
+ ((aReg >> (aPin/2)) & 0x0003)
+
+#define REG_GET4(aReg, aPin) \
+ ((aReg >> (aPin/4)) & 0x000F)
+
+#define REG_GET8(aReg, aPin) \
+ ((aReg >> (aPin/8)) & 0x00FF)
+
+
+#define REG_SET(aReg, aOffset, aMask, aVal) {\
+ U32 regval = ((aVal) << ((aOffset))); \
+ U32 mask = ~((U32)aMask << ((aOffset))); \
+ if ((aReg & ~mask) != regval) {\
+ aReg &= (mask); \
+ aReg |= regval; \
+ }\
+ }
+
+#define REG_SET1(aReg, aPin, aVal) {\
+ U32 regval = ((aVal) << ((aPin))); \
+ U32 mask = ~((U32)1 << ((aPin))); \
+ if(aVal == 0) aReg &= (mask); \
+ else aReg |= regval; \
+ }
+
+
+#define REG_SET2(aReg, aPin, aVal) {\
+ U32 regval = ((aVal) << ((aPin)*2)); \
+ U32 mask = ~((U32)3 << ((aPin)*2)); \
+ if ((aReg & ~mask) != regval) {\
+ aReg &= (mask); \
+ aReg |= regval; \
+ }\
+ }
+
+#define REG_SET4(aReg, aPin, aVal) {\
+ U32 regval = ((aVal) << ((aPin)*4)); \
+ U32 mask = ~((U32)0xF << ((aPin)*4)); \
+ if ((aReg & ~mask) != regval) {\
+ aReg &= (mask); \
+ aReg |= regval; \
+ }\
+ }
+
+
+#define REG_SET8(aReg, aPin, aVal) {\
+ U32 regval = ((aVal) << ((aPin)*8)); \
+ U32 mask = ~((U32)0xFF << ((aPin)*8)); \
+ if ((aReg & ~mask) != regval) {\
+ aReg &= (mask); \
+ aReg |= regval; \
+ }\
+}
+
+
+/*********************************************************** CLOCK *************************/
+/** \defgroup cg_cpu_clk Clock control
+ Define the API to access the CPU clock configuration. This API is used to enable/disable generated clocks
+ to required hardware units like SPI controller, UART controller etc.
+*/
+
+
+
+
+/**
+ \ingroup cg_cpu_clk
+ Create access to 'clock' registers.
+
+ \if OS_WCE
+ in windows CE, usually use VirtualAlloc/VirtualCopy to generate an access to the DMA registers.
+ \endif
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuClockCreate(void);
+
+
+/**
+ \ingroup cg_cpu_clk
+ Destroy access to 'clock' registers
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuClockDestroy(void);
+
+
+/**
+ \ingroup cg_cpu_clk
+ Enable the clock to specific CPU unit
+ Logical unit codes are defined per CPU. each unit may have sub-units.
+
+ \attention Requires porting
+
+ \param[in] aUnit Logical unit code to enable
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuClockEnable(U32 aUnit);
+
+
+/**
+ \ingroup cg_cpu_clk
+ Disable the clock to specific CPU unit.
+ Logical unit codes are defined per CPU. Each unit may have sub-units.
+
+ \attention Requires porting
+
+ \param[in] aUnit Logical unit code to disable
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuClockDisable(U32 aUnit);
+
+
+/*********************************************************** DMA ***************************/
+
+/**
+ \section DMA_CH_CODE DMA channel code
+ code = DMA Controller code + channel number
+
+ example: CG_CPU_DMA_CONTROLLER_0 + 4 ==> DMA controller 1, channel 4
+*/
+#define CG_CPU_DMA_CONTROLLER_0 (0x00000000)
+#define CG_CPU_DMA_CONTROLLER_1 (0x00010000)
+#define CG_CPU_DMA_CONTROLLER_2 (0x00020000)
+#define CG_CPU_DMA_CONTROLLER_3 (0x00030000)
+#define CG_CPU_DMA_CONTROLLER_4 (0x00040000)
+
+#define CG_DMA_CONTROLLER(ch) ((ch & 0xFFFF0000) >> 16)
+#define CG_DMA_CHANNEL(ch) (ch & 0x0000FFFF)
+#define CG_DMA_IS_VALID(ch)
+/** DMA multi block mode
+ Defines the method of executing consecutive DMA transfers.
+ There are 3 different possible methods :
+ LLI - means that the DMA needs to be configured only once, and no extra tx commands should be issued
+ PENDING - means that after receiving the first GPS data interrupt, the DMA should issue the next task, so it is prepared for it.
+ NONE - means that the DMA should prepared for the next task, only after receiving the DMA interrupt for tx-done.
+*/
+
+#define CG_DRIVER_DMA_MULTI_BLOCK_MODE_NONE 0
+#define CG_DRIVER_DMA_MULTI_BLOCK_MODE_PENDING 1
+#define CG_DRIVER_DMA_MULTI_BLOCK_MODE_LLI 2
+
+typedef struct {
+ U32 address;
+ U32 length;
+} TCgCpuDmaTask;
+
+
+/** \defgroup cg_cpu_dma DMA control
+ Define the API to access Direct Memory Access unit for specific CPU.
+*/
+
+/**
+ \ingroup cg_cpu_dma
+ Create access to DMA controller.
+ Depending on OS, CPU and platform implementation, this might require remapping physical
+ address space into virtual address space. However, on some systems the virtual address is
+ statically allocated, so this function should be left empty (for example, for Linux driver).
+
+ In the CellGuide provided implementation, if \ref CG_DRIVER_DMA_BASE_VA is defined in platform.h, then
+ a static virtual address should be used, otherwise, the physical address (CG_DRIVER_DMA_BASE_PA)
+ is mapped to a virtual address.
+
+ The function assigns gpDMA with the DMA controller virtual address.
+
+ \if OS_WCE
+ \note in windows CE, usually use VirtualAlloc/VirtualCopy to generate an access to the DMA registers.
+ if a consist storage is needed, it should be global.
+ \endif
+
+ \attention DMA channel number is a 'logical' number, a combination of the controller and channel, and
+ should be parsed before used directly with hardware registers
+ \note On some implementations, the CGsnap read port address is required for proper DMA setup,
+ and therefore it is passed as an argument. If it is not required, then it should be ignored,
+ but not removed from the function prototype.
+
+ \param[in] dmaChannel : The DMA channel to create
+ \param[in] ipDataSourceAddress : The address of the IP, from which the DMA should read data
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaCreate(U32 dmaChannel, U32 ipDataSourceAddress);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Destroy DMA access
+
+ \param[in] aDmaChannel Logical channel number
+ \param[in] aIpDataSourceAddress Address
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaDestroy(U32 aDmaChannel, U32 aIpDataSourceAddress);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Check if the DMA channel is ready for next operation.
+
+ \param[in] aDmaChannel Logical channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+ \retval ECgBusy if not ready
+*/
+TCgReturnCode CgCpuDmaIsReady(U32 aDmaChannel);
+
+
+
+/**
+ \ingroup cg_cpu_dma
+ Get the DMA channel current bytes count
+
+ \param[in] aDmaChannel Channel number
+ \param[out] apCount Bytes count
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+ \retval ECgBusy When channel is not ready
+*/
+TCgReturnCode CgCpuDmaCurCount(U32 aDmaChannel, U32 *apCount);
+
+/**
+ \ingroup cg_cpu_dma
+ Get the DMA channel requested bytes count
+
+ \param[in] aDmaChannel Logical channel number
+ \param[out] apCount Bytes count
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+ \retval ECgBusy When channel is not ready
+*/
+TCgReturnCode CgCpuDmaRequestedCount(U32 aDmaChannel, U32 *apCount);
+
+/**
+ \ingroup cg_cpu_dma
+ Wait for the DMA channel to finish its current transfer
+
+ \param[in] aDmaChannel Logical channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+ \retval ECgBusy When channel is not ready
+*/TCgReturnCode CgCpuDmaWaitFinish(U32 aDmaChannel);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Stop DMA channel
+
+ \param[in] aDmaChannel Logical channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+*/
+TCgReturnCode CgCpuDmaStop(U32 aDmaChannel);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Start the specified DMA channel.
+ The channel initialization (setting source, destination, etc) is done in another function.
+
+ \param[in] aDmaChannelCode DMA channel code.
+ \ref DMA_CH_CODE
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+ \retval ECgBadArgument On invalid channel
+*/
+TCgReturnCode CgCpuDmaStart(U32 aDmaChannelCode);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to write data to SPI
+
+ \param pSource Source memory address to write from
+ \param aLength Number of bytes to write
+ \param aWriteDmaChannel DMA channel to use
+ \param aDeviceChannel SPI channel to use
+
+ \note The function checks that the DMA channel selected is the right one for the SPI channel.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupToDevice(U32 pSource, U32 aLength, U32 aWriteDmaChannel, int aDeviceChannel);
+
+
+
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to read data from SPI
+
+ \param pTarget Source memory address to write to
+ \param aLength Number of bytes to transfer
+ \param aBlockLength Number of bytes in a block
+ \param aReadDmaChannel DMA channel to use for read
+ \param aWriteDmaChannel DMA channel to use for write
+ \param aDeviceChannel SPI channel to use
+
+ \note if SPI has 'auto output' generator, there is no need to use the 'write' channel.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupFromDevice(U32 pTarget, U32 aLength, U32 aBlockLength, U32 aReadDmaChannel, U32 aWriteDmaChannel, int aDeviceChannel);
+
+
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to read data from CGsnap
+
+ \param apDmaTask DMA tasks list
+ \param aDmaTaskCount Total number of DMA tasks
+ \param aDmaChannelCode DMA channel to use for read (\ref DMA_CH_CODE)
+ \param aDeviceCode Device code
+
+ \note if SPI has 'auto output' generator, there is no need to use the 'write' channel.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupFromDeviceFirstTask(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDmaChannelCode, U32 aDeviceCode);
+
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to read data from SPI
+
+ \param apDmaTask DMA tasks list
+ \param aDmaTaskCount Total number of DMA tasks
+ \param aActiveTaskIndex Active DMA task number
+ \param aDmaChannel DMA channel to use for read
+ \param aDeviceCode Device code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupFromDeviceNextTask(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aActiveTaskIndex, U32 aDmaChannel, U32 aDeviceCode);
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to read data from GPS device.
+ This handles the initial transfer setup, and is called by the application prior to CgCpuDmaStart.
+ Configure DMA to read data from CGsnap.
+ - DMA source
+ - Device is CGsnap IP
+ - Address is 'aDeviceAddress'
+ - Non increment
+ - Use handshake
+ - Burst transfer (burst = 16 bytes)
+ - Word (32bit) transfer mode
+ - Enable interrupt at end of transfer
+
+ If the FMA supports LLI (Linked List Interface), then a proper DMA tasks list should be generated from the generic
+ tasks list.
+
+ \param apDmaTask DMA tasks list
+ Since the destination buffer maybe smaller than the transfer size, it is required to split the DMA
+ transfer into several DMA tasks. The destination of each task will take into consideration the buffer size.
+ The application sets the buffer size on init.
+ The application decides on transfer size, transfer task size and task destination address, for every transfer.
+
+ For example, if the transfer size is 1500KB, and the buffer size is 500KB, and the task size is 100KB,
+ then there will be 15 transfer tasks, each of 100KB, and the destination addresses in each task will be 0, 100KB, 200KB,
+ 300KB, 400KB, 0KB, 100KB, etc.
+
+ In case the DMAC supports LLI, all required tasks shall be set in the DMAC.
+ Otherwise, the tasks are stored temporarily, and will be used by CgCpuDmaSetupFromGpsNextTask.
+
+ \param apDmaTask DMA tasks list (pairs of addresses and lengths)
+ \param aDmaTaskCount Total number of DMA tasks
+ \param aDmaChannel DMA channel to use for read (\ref DMA_CH_CODE)
+ \param aDeviceAddress Device address
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupFromGps(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDmaChannel, U32 aDeviceAddress);
+
+
+
+
+/**
+ \ingroup cg_cpu_dma
+ Configure DMA to read next DMA task from GPS device.
+ This function is only required when the DMA controller does not support LLI
+ This function is only required when the DMA controller does not support LLI
+ This sets up the DMA to perform the 2nd and above transfer tasks, of the same transfer.
+
+ In case the DMAC doesn't support LLI, this function is called by the the DMA interrupt handler, to set-up the
+ next transfer task.
+ Otherwise, this function is never called.
+
+
+ \param apDmaTask DMA tasks list (the same
+ \param aDmaTaskCount Total number of DMA tasks
+ \param aActiveTaskIndex Active DMA task number
+ \param aDmaChannel DMA channel to use for read
+ \param aDeviceAddress Device address
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDmaSetupFromGpsNextTask(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aActiveTaskIndex, U32 aDmaChannel, U32 aDeviceAddress);
+
+/*********************************************************** GPIO **************************/
+/** \defgroup cg_cpu_gpio GPIO control
+ Configure, set and read GPIO
+
+
+ CellGuide GPIO code is an abstract number, combination of group constant and pin number.
+ The number is translated to specific CPU values by specific implementation.
+*/
+
+
+/** GPIO pin configuration modes */
+typedef enum {
+ ECG_CPU_GPIO_INPUT, /**< GPIO to act as input */
+ ECG_CPU_GPIO_OUTPUT, /**< GPIO to act as output */
+ ECG_CPU_GPIO_SPECIAL, /**< GPIO to act as special function */
+ ECG_CPU_GPIO_FALLING_INT, /**< GPIO to act as falling edge interrupt*/
+ ECG_CPU_GPIO_SPECIAL2, /**< GPIO to act as special function */
+ ECG_CPU_GPIO_SPECIAL3, /**< GPIO to act as special function */
+ ECG_CPU_GPIO_MODE___
+} TCgCpuGpioMode;
+
+/** GPIO pin configuration modes */
+typedef enum {
+ ECG_CPU_GPIO_PULL_NONE, /**< GPIO with no pull */
+ ECG_CPU_GPIO_PULL_DOWN, /**< GPIO with pull down */
+ ECG_CPU_GPIO_PULL_UP, /**< GPIO with pull up */
+ ECG_CPU_GPIO_PULL___
+} TCgCpuGpioPull;
+
+/**
+ \ingroup cg_cpu_gpio
+ Create access to GPIO controller.
+ Depending on OS, CPU and platform implementation, this might require remapping physical
+ address space into virtual address space. However, on some systems the virtual address is
+ statically allocated, so this function should be left empty (for example, for Linux driver).
+
+ In the 'standard' implementation, if CG_DRIVER_GPIO_BASE_VA is defined in platform.h, then
+ a static virtual address should be used, otherwise, the physical address (CG_DRIVER_GPIO_BASE_PA)
+ is mapped to a virtual address.
+
+ The function assigns gpGpio with the GPIO controller virtual address.
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioCreate(void);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Destroy access to GPIO controller.
+ The implementation depends on the method used for allocation (see CgCpuGpioCreate)
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioDestroy(void);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO to 'output' mode and set it to '1' value
+
+ \param[in] aPinCode GPIO pin code
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioSet(U32 aPinCode);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO to 'output' mode and set it to '0' value
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPinCode GPIO pin code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioReset(U32 aPinCode);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO to 'input' mode, read the value and return it
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPinCode GPIO pin code
+ \param[out] aPinValue current value
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioGet(U32 aPinCode, int *aPinValue);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Return IRQ code for the specific GPIO pin
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPin GPIO pin code
+ \param[out] aCode IRQ code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioIntCode(U32 aPin, U32 *aCode);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO mode
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPinCode GPIO pin code
+ \param[in] aPinMode Requested mode
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioModeSet(U32 aPinCode, TCgCpuGpioMode aPinMode);
+
+/**
+ \ingroup cg_cpu_gpio
+
+ Set a specific GPIO strength
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \attention Not all CPUs support internal drive level. If the CPU does not support this feature, this function should be left empty.
+
+ \param[in] aPinCode GPIO pin code
+ \param[in] aStrength Requested strength
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioStrength(U32 aPinCode, U32 aStrength);
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO pull up/down
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \attention Not all CPUs support internal pull, if the CPU does not support this feature, this function should be left empty.
+
+ \param[in] aPinCode GPIO pin code
+ \param[in] aPull Requested
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioPull(U32 aPinCode, TCgCpuGpioPull aPull);
+
+/**
+ \ingroup cg_cpu_gpio
+ Set a specific GPIO direction
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPinCode GPIO pin code
+ \param[in] aPinMode Requested mode
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioDirection(U32 aPinCode, TCgCpuGpioMode aPinMode);
+
+
+/**
+ \ingroup cg_cpu_gpio
+ Clear interrupt bit
+
+ \note Pin code is CellGuide internal code for each GPIO, which is a combination of the
+ GPIO group offset and the number inside the group.
+
+ \param[in] aPinCode GPIO pin code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuGpioIntClear(U32 aPinCode);
+
+/*********************************************************** SPI ***************************/
+/** \defgroup cg_cpu_spi SPI control
+ SPI programming
+*/
+
+
+
+
+/**
+ \ingroup cg_cpu_spi
+ Delay for specific time
+
+ \param aCount
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuDelay(U32 aCount);
+
+
+typedef enum {
+ ECG_CPU_SPI_INPUT_DMA,
+ ECG_CPU_SPI_INPUT_POLLING,
+ ECG_CPU_SPI_OUTPUT_DMA,
+ ECG_CPU_SPI_OUTPUT_POLLING,
+ ECG_CPU_SPI_INIT,
+ ECG_CPU_SPI_SLAVE_INPUT_DMA,
+ ECG_CPU_SPI_SLEEP,
+ ECG_CPU_SPI_MODE___
+} TCgCpuSpiMode;
+
+
+
+/**
+ \ingroup cg_cpu_spi
+ Create access to SPI
+
+ \param[in] aChannelCode SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiCreate(U32 aChannelCode);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Destroy access to SPI
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiDestroy(void);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Enable SPI controller for specific channel
+
+ \param[in] aDeviceChannel SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiEnable(int aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Disable SPI controller for specific channel
+
+ \param[in] aDeviceChannel SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiDisable(int aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Check if SPI channel number is valid for the specific system
+
+ \param[in] aDeviceChannel SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiIsValid(int aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Setup SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aPrescale SPI clock divider
+ \param[in] aMode SPI mode
+ \param[in] aLengthBytes Number of bytes
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiConfig(U32 aDeviceChannel, U32 aPrescale, TCgCpuSpiMode aMode, U32 aLengthBytes);
+
+/**
+ \ingroup cg_cpu_spi
+ Setup SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aLengthBytes Number of bytes
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiSlaveConfig(U32 aDeviceChannel, U32 aLengthBytes);
+
+/**
+ \ingroup cg_cpu_spi
+ Setup SPI channel GPIO
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aPrescale SPI clock divider
+ \param[in] aMode SPI mode
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiSetup(U32 aDeviceChannel, U32 aPrescale, TCgCpuSpiMode aMode);
+
+/**
+ \ingroup cg_cpu_spi
+ Return number of words waiting in receive FIFO
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[out] pCount number of words (word width is according to config)
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiReadCount(U32 aDeviceChannel, U32 *pCount);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Loop until SPI write is finished.
+
+ \param[in] aDeviceChannel SPI channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiTxFinishWait(U32 aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Rx FIFO is empty
+
+ \param[in] aDeviceChannel SPI channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+BOOL CgCpuSpiRxFifoEmpty(U32 aDeviceChannel);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Clear SPI receive FIFO
+
+ \param[in] aDeviceChannel SPI channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiClearFifo(U32 aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Loop until SPI read is finished.
+
+ \param[in] aDeviceChannel SPI channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiRxFinishWait(U32 aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Read one byte from SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[out] aByte Data read from SPI
+
+ \return Value read from SPI
+*/
+TCgReturnCode CgCpuSpiReadByte(U32 aDeviceChannel, volatile unsigned char *aByte);
+
+/**
+ \ingroup cg_cpu_spi
+ Read one Word from SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[out] aValue Data read from SPI
+
+ \return Value read from SPI
+*/
+TCgReturnCode CgCpuSpiReadU16(U32 aDeviceChannel, volatile U16 *aValue);
+
+/**
+ \ingroup cg_cpu_spi
+ Read one DWord from SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[out] aValue Data read from SPI
+
+ \return Value read from SPI
+*/
+TCgReturnCode CgCpuSpiReadU32(U32 aDeviceChannel, volatile U32 *aValue);
+
+/**
+ \ingroup cg_cpu_spi
+ Read one byte from SPI channel (read 2nd FIFO byte)
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[out] aByte Data read from SPI
+
+ \return Value read from SPI
+*/
+TCgReturnCode CgCpuSpiReadByte2(U32 aDeviceChannel, volatile unsigned char *aByte);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Write one byte to SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aValue Value to write
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiWriteByte(U32 aDeviceChannel, unsigned char aValue);
+
+/**
+ \ingroup cg_cpu_spi
+ Write one Word to SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aValue Value to write
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiWriteU16(U32 aDeviceChannel, U16 aValue);
+
+/**
+ \ingroup cg_cpu_spi
+ Write one DWord to SPI channel
+
+ \param[in] aDeviceChannel SPI channel number
+ \param[in] aValue Value to write
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiWriteU32(U32 aDeviceChannel, U32 aValue);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Return the GPIO code for selected SPI channel MOSI
+
+ \param[in] aDeviceChannel channel number
+ \param[out] aGpioCode gpio code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiMosi(U32 aDeviceChannel, U32 *aGpioCode);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Return the GPIO number for selected SPI channel MISO
+
+ \param[in] aDeviceChannel channel number
+ \param[out] aGpio gpio code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiMiso(U32 aDeviceChannel, U32 *aGpio);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Return the GPIO number for selected SPI channel CLK
+
+ \param[in] aDeviceChannel channel number
+ \param[out] aGpio gpio code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiClk(U32 aDeviceChannel, U32 *aGpio);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Return the GPIO number for selected SPI channel CS (Chip Select)
+
+ \param[in] aDeviceChannel channel number
+ \param[out] aGpio gpio code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiCs(U32 aDeviceChannel, U32 *aGpio);
+
+
+/**
+ \ingroup cg_cpu_spi
+ Start DMA transaction
+
+ \param[in] aDeviceChannel SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiDmaStart(int aDeviceChannel);
+
+/**
+ \ingroup cg_cpu_spi
+ Stop DMA transaction
+
+ \param[in] aDeviceChannel SPI Channel number
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuSpiDmaStop(int aDeviceChannel);
+
+
+/*********************************************************** INTR **************************/
+/** \defgroup cg_cpu_interrupt Interrupt control
+ Access to interrupt controller
+*/
+
+/**
+ \ingroup cg_cpu_interrupt
+ Create access to INTC controller.
+ Depending on OS, CPU and platform implementation, this might require remapping physical
+ address space into virtual address space. However, on some systems the virtual address is
+ statically allocated, so this function should be left empty (for example, for Linux driver).
+
+ In the 'standard' implementation, if CG_DRIVER_INT_BASE_VA is defined in platform.h, then
+ a static virtual address should be used, otherwise, the physical address (CG_DRIVER_INT_BASE_PA)
+ is mapped to a virtual address.
+
+ The function assigns pINT with the INT controller virtual address.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIntrCreate(void);
+
+/**
+ \ingroup cg_cpu_interrupt
+ Destroy access to INTC
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIntrDestroy(void);
+
+
+/**
+ \ingroup cg_cpu_interrupt
+ Register IRQ interrupt as OS interrupt
+
+ \param[in] aIRQ requested IRQ interrupt code
+ \param[in] apOSIntCode requested software interrupt code
+ \param[out] apOSIntCode registered OS interrupt code
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIntrRequestOsInterrupt(U32 aIRQ, U32 *apOSIntCode);
+/**
+ \ingroup cg_cpu_interrupt
+ Initialize interrupt
+
+ \param[in] aRequestCode requested interrupt code (os specific)
+ \param[in] apEvent event to tie with interrupt
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIntrAttachEvent(U32 aRequestCode, void *apEvent);
+
+/**
+ \ingroup cg_cpu_interrupt
+ Disable registered interrupt
+
+ \param[in] aInterruptCode interrupt code (os specific)
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIntrDisable(U32 aInterruptCode);
+
+
+/**
+ \ingroup cg_cpu_interrupt
+ Signals to the kernel that interrupt processing has been completed
+
+ \param[in] aInterruptCode interrupt code (os specific)
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+
+TCgReturnCode CgCpuIntrDone(U32 aInterruptCode);
+
+
+/** Interrupt Service Thread information structure */
+typedef struct {
+ void *hThread; /**< Handle to thread object */
+ U32 intCode; /**< Interrupt code */
+ void *event; /**< Handle to Interrupt event */
+ S32 priority; /**< Thread priority */
+} TCgCpuIST;
+
+
+/**
+ \ingroup cg_cpu_interrupt
+ If apSharedISRInfo == NULL ===> Create and start interrupt service thread
+ Else ===> Initialize an event, and connect it to the EXISTING ISR
+
+ \param[in] apIstInfo Thread info structure
+ \param[in] aFunc Main function for the thread
+ \param[in] aPriority Requested thread priority
+ \param[in] aIntCode Required interrupt code
+ \param[in] aIrqCode Required IRQ code (may be 0)
+ \param[in] aParam IST data structure pointer
+ \param[in] aEventName Event name to use for interrupt/IST communication
+ only need to supply name if the event is created by BSP.
+ for systems where the event is internally tied to specific GPI interrupt,
+ NULL can be set here
+ \param[in] apSharedISRInfo if the interrupt is shared, this will contain the info on
+ the shared interrupt
+ \param[in] apSharedISRLibrary if the interrupt is shared, this will indicate what library
+ holds the shared interrupt handler
+ \param[in] apSharedISR if the interrupt is shared, this will indicate the name of the
+ interrupt service routine
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuISTStart(TCgCpuIST *apIstInfo, void *aFunc, S32 aPriority, U32 aIntCode, U32 aIrqCode,
+ void *aParam, const char *aEventName, void * apSharedISRInfo,
+ const void * apSharedISRLibrary, const void * apSharedISR);
+
+
+/**
+ \ingroup cg_cpu_interrupt
+ Stop interrupt service thread
+
+ \param[in] apIstInfo Thread info structure
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuISTStop(TCgCpuIST *apIstInfo);
+
+
+
+/*********************************************************** RTC ***************************/
+/** \defgroup cg_cpu_rtc RTC control
+ Access to RTC
+*/
+
+/**
+ \ingroup cg_cpu_rtc
+ Create access to RTC controller by mapping it to virtual memory.
+
+ \note On some operating systems (Linux) and platforms, this step is static, i.e.,
+ the virtual address is pre defined.
+ CellGuide standard implementation of this function uses CG_DRIVER_RTC_BASE_VA
+ and CG_DRIVER_RTC_BASE_PA defines to select the proper method.
+
+ \if OS_WCE
+ in windows CE, usually use VirtualAlloc/VirtualCopy to generate an access to the DMA registers.
+ if a consist storage is needed, it should be global.
+ \endif
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuRtcCreate(void);
+
+
+
+/**
+ \ingroup cg_cpu_rtc
+ Destroy access to RTC controller by un-mapping virtual memory.
+
+ \note CellGuide standard implementation of this function uses CG_DRIVER_RTC_BASE_VA
+ and CG_DRIVER_RTC_BASE_PA defines to select the proper method.
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuRtcDestroy(void);
+
+
+/**
+ \ingroup cg_cpu_rtc
+ RTC time structure
+*/
+typedef struct {
+ U32 year; /**< Year (1970-2100) */
+ U32 month; /**< Month in year (0-11) */
+ U32 day; /**< Day in month (0-30) */
+ U32 hour; /**< Hour in day (0-23) */
+ U32 minute; /**< Minute in Hour (0-59) */
+ U32 second; /**< Second in minute (0-59) */
+ U32 dayInWeek; /**< Day in week (0-6) */
+ U32 tick; /**< internal tick counter (units are CPU specific) */
+} TCgCpuRtcTime;
+
+/**
+ \ingroup cg_cpu_rtc
+
+ Read current time from RTC unit
+
+ \\attention Implementation is required
+
+ \param[out] apTime Pointer to time structure
+
+ \return System wide return code (see CgReturnCodes.h)
+
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuRtcRead(TCgCpuRtcTime *apTime);
+
+/*********************************************************** RF control *************************/
+
+/** \defgroup cg_cpu_rf RF functions*/
+
+/**
+ \ingroup cg_cpu_rf
+
+ Read one byte from RF control via specific protocol
+ \param[out] aValue Pointer to received byte
+
+ \return system error code
+*/
+TCgReturnCode CgCpuRFControlReadbyte(volatile unsigned char *aValue);
+
+/**
+ \ingroup cg_cpu_rf
+
+ Write one byte to RF control via specific protocol
+ \param[in] aValue Byte to send
+
+ \return system error code
+*/
+TCgReturnCode CgCpuRFControlWriteByte(unsigned char aValue);
+
+/*********************************************************** Miscellanies *************************/
+/** \defgroup cg_cpu_miscellanies Miscellanies functions*/
+
+/**
+ \ingroup cg_cpu_miscellanies
+ Get last error code for this unit
+
+ \return system error code
+*/
+U32 CgCpuLastErrorCode(void);
+
+
+
+/**
+ \ingroup cg_cpu_miscellanies
+ Clear CPU cache
+
+ \param[in] pSource Source memory address
+ \param[in] aDmaChannel DMA channel
+
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuClearCache(U32 pSource, U32 aDmaChannel);
+
+
+
+/**
+ \ingroup cg_cpu_miscellanies
+ Set bits in bit-field register
+
+ \param[in] aReg pointer to register
+ \param[in] aBitFieldDef bit field definition
+ \param[in] aValue value to set
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgSetRegisterBits(volatile U32 *aReg, TCgBitField aBitFieldDef, U32 aValue);
+
+U32 CgGetU32Mask(U32 bitsInU32);
+
+
+/**
+ \ingroup cg_cpu_miscellanies
+ Get bits from bit-field register
+
+ \param[in] aReg register
+ \param[in] aBitFieldDef bit field definition
+ \param[in] apValue pointer to returned value
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgGetRegisterBits(volatile U32 aReg, TCgBitField aBitFieldDef, U32 *apValue);
+
+/**
+ \ingroup cg_cpu_miscellanies
+ Global virtual memory allocation.
+ This function is used on some platforms, where a global initialization of virtual memory is required.
+ It is called as one of the first initialization steps in CgxDriverConstruct.
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuAllocateVa(void);
+
+/**
+ Reset a CPU sub-unit
+ \param[in] aUnitIndex unit id (see specific CPU documentation)
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuReset(U32 aUnitIndex);
+
+/**
+ Set the CGsnap IP Master reset to 'reset' state (device is not active)
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIPMasterResetOn(void);
+
+/**
+ Set the CGsnap IP Master reset to 'clear' state (device is active)
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgCpuIPMasterResetClear(void);
+
+/**
+ Get CPU revision code.
+ \note Used mainly for debug.
+
+ \param[out] apRevisionCode CPU revision code
+
+ \return CPU revision information as null terminated text.
+*/
+TCgReturnCode CgCpuRevision(char *apRevisionCode);
+
+
+/**
+ byte and word swap
+
+ \param[in] aSource Pointer to source buffer
+ \param[out] aDest Pointer to destination buffer
+ \param[in] aSizeInBytes Size of memory, in bytes
+ \param[in] aFrom Source byte order
+ \param[in] aTo Destination byte order
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk On success
+*/
+TCgReturnCode CgSwapBytesInBlock(void * aSource,void * aDest, long aSizeInBytes, TCgByteOrder aFrom, TCgByteOrder aTo);
+
+
+#if defined(CGTEST) || defined(DEBUG)
+ #define TRACE_ON
+#endif
+#define TRACE_ON
+
+/**
+ Debug facility - to show error messages
+*/
+#ifdef TRACE_ON
+ TCgReturnCode CgxCpuMsg(const char *aFuncName, const char *aFileName, U32 aLineNum, char *aFormat, ...);
+ TCgReturnCode CgxCpuPrint(char *aText);
+ #define DBG_FUNC_NAME(name) const char *__funcname__ = name;
+ #define DBGMSG(format) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format);
+ #define DBGMSG1(format,a) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a);
+ #define DBGMSG2(format,a,b) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b);
+ #define DBGMSG3(format,a,b,c) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c);
+ #define DBGMSG4(format,a,b,c,d) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d);
+ #define DBGMSG5(format,a,b,c,d,e) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d,e);
+ #define DBGMSG6(format,a,b,c,d,e,f) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d,e,f);
+ #define DBGMSG7(format,a,b,c,d,e,f,g) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d,e,f,g);
+ #define DBGMSG8(format,a,b,c,d,e,f,g,h) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d,e,f,g,h);
+ #define DBGMSG9(format,a,b,c,d,e,f,g,h,i) CgxCpuMsg(__funcname__, __FILE__, __LINE__, format, a,b,c,d,e,f,g,h,i);
+ #define DBGDONE {DBGMSG("Done");}
+ #define DBGSTAT(title,s) {DbgStat##s(title);}
+
+#else
+ #define DBG_FUNC_NAME(name)
+ #define DBGMSG(format) do {} while(0)
+ #define DBGMSG1(format,a) do {} while(0)
+ #define DBGMSG2(format,a,b) do {} while(0)
+ #define DBGMSG3(format,a,b,c) do {} while(0)
+ #define DBGMSG4(format,a,b,c,d) do {} while(0)
+ #define DBGMSG5(format,a,b,c,d,e) do {} while(0)
+ #define DBGMSG6(format,a,b,c,d,e,f) do {} while(0)
+ #define DBGMSG7(format,a,b,c,d,e,f,g) do {} while(0)
+ #define DBGMSG8(format,a,b,c,d,e,f,g,h) do {} while(0)
+ #define DBGMSG9(format,a,b,c,d,e,f,g,h,i) do {} while(0)
+ #define DBGDONE do {} while(0)
+ #define DBGSTAT(title,s) do {} while(0)
+#endif
+
+#define CgSwapBytesU32( aSource )\
+ (((0xFF00FF00 & aSource) >> 8) | ((0x00FF00FF & aSource) << 8))
+
+
+#define CgSwapWordsU32( aSource )\
+ (((0xFFFF0000 & aSource) >> 16) | ((0x0000FFFF & aSource) << 16))
+
+
+#define CgSwapBytesAndWordsU32( aSource )\
+ ( CgSwapWordsU32(CgSwapBytesU32(aSource)) )
+
+#ifdef TRACE_ON
+ #define DBGERR(rc) if (!OK(rc)) { DBGMSG3("Error : (%ld) [%s:%d]", rc, __FILE__, __LINE__); }
+#else
+ #define DBGERR(rc)do {} while(0)
+#endif
+
+
+#ifdef TRACE_ON
+ void DbgStatSPI(const char *aTitle);
+ void DbgStatDMA(const char *aTitle);
+ void DumpGpioState(U32 aGpio);
+#else
+ #define DbgStatSPI(x) do {} while(0)
+ #define DbgStatDMA(x) do {} while(0)
+ #define DumpGpioState(x) do {} while(0)
+#endif
+
+
+// ===========================================================================
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgCpuLinux.c b/drivers/misc/gpsip/cgdriver/CgCpuLinux.c
new file mode 100644
index 00000000..7dc9f6b7
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgCpuLinux.c
@@ -0,0 +1,229 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \cond OS_LINUX
+*/
+
+
+/**
+ \file
+ \brief Linux implementation of OS depended CellGuide CPU API
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+
+
+*/
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/cdev.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/dma-mapping.h>
+#include <linux/wait.h>
+
+#include <linux/sched.h>
+#include <linux/time.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/cacheflush.h>
+
+#include "CgCpuOs.h"
+#include "CgCpu.h"
+#include "platform.h"
+
+
+
+
+
+
+TCgReturnCode CgCpuIntrDone(U32 aInterruptCode)
+{
+ TCgReturnCode rc = ECgOk;
+ //InterruptDone(aInterruptCode);
+ return rc;
+}
+
+
+
+TCgReturnCode CgCpuVirtualAllocate(volatile void **pObject, unsigned long aBaseAddr, unsigned long aSize)
+{
+ ASSERT_NOT_NULL(pObject);
+
+ *pObject = ioremap_nocache(aBaseAddr, aSize);
+
+ return (*pObject != NULL) ? ECgOk : ECgErrMemory;
+}
+
+
+TCgReturnCode CgCpuVirtualFree(volatile void **pObject)
+{
+ ASSERT_NOT_NULL(pObject);
+
+ iounmap((void *)*pObject);
+ *pObject = NULL;
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuPhysicalAllocate(void **pObject, U32 *pAddress, U32 aSize)
+{
+ DBG_FUNC_NAME("CgCpuPhysicalAllocate")
+ TCgReturnCode rc = ECgOk;
+ ASSERT_NOT_NULL(pObject);
+ //DBGMSG1("Trying to allocate %d bytes", aSize);
+
+ //*pObject = dma_alloc_writecombine(0, aSize + 32, (dma_addr_t *)pAddress, GFP_KERNEL);
+
+ if(*pObject == NULL) {
+ DBGMSG("Error! Failed allocating buffer");
+ rc = ECgErrMemory;
+ }
+ else {
+ DBGMSG2("buffer allocated: ptr=0x%08X, addr=0x%08X", *pObject, *pAddress);
+// memset((void *)*pObject, 0, aSize);
+ }
+
+ *pObject = (unsigned char *)((((unsigned long)*pObject + 32 - 1) / 32) * 32);
+ *pAddress = ((*pAddress + 32 - 1) / 32) * 32;
+
+ return rc;
+}
+
+TCgReturnCode CgCpuPhysicalFree(void **pObject, U32 *pAddress, unsigned long aSize)
+{
+ DBG_FUNC_NAME("CgCpuPhysicalFree")
+ TCgReturnCode rc = ECgOk;
+ ASSERT_NOT_NULL(pObject);
+ DBGMSG1("pObject=0x%08X", *pObject);
+
+ if (*pAddress != 0)
+ // dma_free_writecombine(0, aSize + 32, *pObject, *pAddress);
+
+ *pObject = NULL;
+
+ return rc;
+}
+
+
+
+
+TCgReturnCode CgxCpuReadMemory(U32 aBaseAddr, U32 aOffset, U32 *apValue)
+{
+ DBG_FUNC_NAME("CgxCpuReadMemory")
+
+ DBGMSG1("read addd ress %x",aBaseAddr);
+
+
+ *apValue = sci_glb_read((aBaseAddr + aOffset),-1UL);
+ return ECgOk;
+}
+
+TCgReturnCode CgxCpuWriteMemory(U32 aBaseAddr, U32 aOffset, U32 aValue)
+{
+ DBG_FUNC_NAME("CgxCpuWriteMemory")
+
+ DBGMSG1("addd ress %x",aBaseAddr);
+
+ sci_glb_write((aBaseAddr + aOffset), aValue, -1UL);
+
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuKernelModeEnter(void)
+{
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuKernelModeExit(void)
+{
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuCacheSync(void)
+{
+ //DBG_FUNC_NAME("CgCpuCacheSync")
+#ifndef ACP_PORT
+ flush_cache_all();
+#else
+ DBGMSG("enable ACP");
+#endif
+
+ return ECgOk;
+}
+
+
+
+#ifdef TRACE_ON
+#define MAX_LINE_LENGTH 256
+
+
+TCgReturnCode CgxCpuPrint(char *aText)
+{
+ printk(KERN_EMERG "%s", aText);
+
+ return ECgOk;
+}
+
+TCgReturnCode CgxCpuMsg(const char *aFuncName, const char *aFileName, U32 aLineNum, char *aFormat, ...)
+{
+#if 0
+ va_list args;
+ char buf[MAX_LINE_LENGTH]= {0};
+ int n = 0;
+ U32 curTickMSec = 0;
+ va_start(args, aFormat); // prepare the arguments
+ n = vsnprintf(buf, MAX_LINE_LENGTH, aFormat, args);
+ va_end(args); // clean the stack
+
+ // Get current tick
+ CgxCpuTick(&curTickMSec);
+
+ if (n > 0)
+ printk(KERN_EMERG ">>> %d.%03d %s[%d]: %s\n", curTickMSec / 1000, curTickMSec % 1000, aFuncName, (int)aLineNum, buf);
+ #endif
+ return ECgOk;
+}
+#endif
+
+TCgReturnCode CgxCpuSleep(U32 milliSeconds)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout (milliSeconds);
+ return ECgOk;
+}
+#ifndef CG_HAS_CPU_TICK
+ TCgReturnCode CgxCpuTick(U32 * apTickMSec)
+ {
+ struct timespec t = current_kernel_time();
+ *apTickMSec = t.tv_sec * 1000 + t.tv_nsec / 1000000;
+ return ECgOk;
+ }
+#endif
+
+/** \endcond */
diff --git a/drivers/misc/gpsip/cgdriver/CgCpuOs.h b/drivers/misc/gpsip/cgdriver/CgCpuOs.h
new file mode 100644
index 00000000..ab201d96
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgCpuOs.h
@@ -0,0 +1,176 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+/**
+ \file
+ \brief Os depended services requires by CgCpu
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+#ifndef CG_CPU_OS_H
+#define CG_CPU_OS_H
+
+#ifdef __cplusplus
+ extern "C"
+ {
+#endif
+
+// ===========================================================================
+
+#include "CgReturnCodes.h"
+
+
+// ===========================================================================
+
+
+
+/**
+ \ingroup cg_cpu_os
+ Map physical address space to virtual one
+
+ \param[out] pObject Pointer to virtual address for physical memory region
+ \param[in] aBaseAddr Base address (physical)
+ \param[in] aSize Number of bytes
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuVirtualAllocate(volatile void **pObject, unsigned long aBaseAddr, unsigned long aSize);
+
+
+/**
+ \ingroup cg_cpu_os
+ Un-map physical address space to virtual one
+
+ \param pObject Pointer to virtual address for physical memory region
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuVirtualFree(volatile void **pObject);
+
+/**
+ \ingroup cg_cpu_os
+ Allocate physical memory
+
+ \param[out] pObject Pointer to virtual address of allocated memory
+ \param[in] pAddress Address of allocated memory (physical)
+ \param[in] aSize Number of bytes
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuPhysicalAllocate(void **pObject, U32 *pAddress, U32 aSize);
+
+/**
+ \ingroup cg_cpu_os
+ Free physical memory
+
+ \param[out] pObject Pointer to virtual address of allocated memory
+ \param[out] pAddress physical address
+ \param[in] aSize size in bytes
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuPhysicalFree(void **pObject, U32 *pAddress, unsigned long aSize);
+
+
+/**
+ \ingroup cg_cpu_os
+ Enter Kernel mode
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuKernelModeEnter(void);
+
+/**
+ \ingroup cg_cpu_os
+ Exit Kernel mode
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+TCgReturnCode CgCpuKernelModeExit(void);
+
+/**
+ \ingroup cg_cpu_os
+ Cache sync
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk Success
+*/
+//TCgReturnCode strinsCgCpuCacheSync(void);
+TCgReturnCode CgCpuCacheSync(void);
+
+/**
+ Read value from host memory location
+ Used to read CGsnap memory mapped registers and other memories, as required.
+
+ \param[in] aBaseAddr Base address (Virtual Memory)
+ \param[in] aOffset Offset from base address
+ \param[out] apValue Read value
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxCpuReadMemory(U32 aBaseAddr, U32 aOffset, U32 *apValue);
+
+/**
+ Write value to host memory location
+ Used to write CGsnap memory mapped registers and other memories, as required.
+
+ \param[in] aBaseAddr Base address (Virtual Memory)
+ \param[in] aOffset Offset from base address
+ \param[in] aValue Value to write
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxCpuWriteMemory(U32 aBaseAddr, U32 aOffset, U32 aValue);
+
+
+/**
+ Sleep for the specified time.
+
+ \param[in] milliSeconds time in miliseconds
+
+ \return System wide return code (see CgReturnCodes.h)
+*/
+TCgReturnCode CgxCpuSleep(U32 milliSeconds);
+
+
+/**
+ Return the CPU tick counter (mostly in mSec)
+ \note tick counter units are different for each CPU
+
+ \return System wide return code (see CgReturnCodes.h)
+*/
+TCgReturnCode CgxCpuTick(U32 * apTickMSec);
+
+
+// ===========================================================================
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgReturnCodes.h b/drivers/misc/gpsip/cgdriver/CgReturnCodes.h
new file mode 100644
index 00000000..470e9ca0
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgReturnCodes.h
@@ -0,0 +1,172 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+/**
+ \file
+ \brief Cell-Guide common return codes
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+ This file define the infrastructure and common error codes for cell-guide projects
+ */
+#ifndef CG_RETURN_CODES_H
+#define CG_RETURN_CODES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "CgTypes.h" /**< CellGuide Types */
+
+#define CG_RETURN_CODE_SUB_RANGE (0x400)
+#define RANGE_MASK ~(CG_RETURN_CODE_SUB_RANGE-1)
+
+#define ECgCommonErrorBase (0)
+#define ECgPrivateErrorBase (-1 * CG_RETURN_CODE_SUB_RANGE)
+#define ECgPrivateMsgBase (+1 * CG_RETURN_CODE_SUB_RANGE)
+
+
+/* System-wide positives */
+
+/** OK status */
+#define ECgOk (0)
+#define ECgProgressNotification ( ECgCommonErrorBase + 1 )
+
+/* System-wide errors */
+#define ECgBadArgument ( ECgCommonErrorBase - 1 )
+#define ECgNotSupported ( ECgCommonErrorBase - 2 )
+#define ECgGeneralFailure ( ECgCommonErrorBase - 3 )
+#define ECgInitFailure ( ECgCommonErrorBase - 4 )
+#define ECgErrMemory ( ECgCommonErrorBase - 5 )
+#define ECgErrGeneral ( ECgCommonErrorBase - 6 )
+#define ECgErrNotInitialized ( ECgCommonErrorBase - 7 )
+#define ECgOutOfBounds ( ECgCommonErrorBase - 8 )
+#define ECgDataNotFound ( ECgCommonErrorBase - 9 )
+#define ECgPermissionDenied ( ECgCommonErrorBase - 10 )
+#define ECgNullPointer ( ECgCommonErrorBase - 11 )
+#define ECgFileOpen ( ECgCommonErrorBase - 12 )
+#define ECgFileRead ( ECgCommonErrorBase - 13 )
+#define ECgFileChecksum ( ECgCommonErrorBase - 14 )
+#define ECgTimeout ( ECgCommonErrorBase - 15 )
+#define ECgTimeNotValid ( ECgCommonErrorBase - 16 )
+#define ECgEndOfFile ( ECgCommonErrorBase - 17 )
+#define ECgInvalidCharacter ( ECgCommonErrorBase - 18 )
+#define ECgFatalError ( ECgCommonErrorBase - 19 )
+#define ECgBadConfiguration ( ECgCommonErrorBase - 20 )
+#define ECgReadOnlyProperty ( ECgCommonErrorBase - 21 )
+#define ECgExitModeFlag ( ECgCommonErrorBase - 22 )
+#define ECgFatalInternalError ( ECgCommonErrorBase - 23 )
+
+
+#define ECgPropertiesMissingLevel ( ECgCommonErrorBase - 24 )
+#define ECgPropertiesMissingGetMethod ( ECgCommonErrorBase - 25 )
+
+#define ECgNotAllowed ( ECgCommonErrorBase - 26 )
+
+#define ECgDataNotValid ( ECgCommonErrorBase - 27 )
+#define ECgDataNotEqual ( ECgCommonErrorBase - 28 )
+
+#define ECgDataNotAvailable ( ECgCommonErrorBase - 30 )
+#define ECgFileNotFound ( ECgCommonErrorBase - 31 )
+#define ECgPathNotFound ( ECgCommonErrorBase - 32 )
+#define ECgNoMoreFiles ( ECgCommonErrorBase - 33 )
+#define ECgNoMoreSlots ( ECgCommonErrorBase - 34 )
+#define ECgInvalidData ( ECgCommonErrorBase - 35 )
+#define ECgPathExists ( ECgCommonErrorBase - 36 )
+#define ECgNotEnoughData ( ECgCommonErrorBase - 37 )
+#define ECgBusy ( ECgCommonErrorBase - 38 )
+#define ECgAnyErrCode ( ECgCommonErrorBase - 39 )
+
+#define ECgNetworkNotInitialized ( ECgCommonErrorBase - 40 )
+#define ECgNetworkSubsysFailed ( ECgCommonErrorBase - 41 )
+#define ECgNetworkPortInUse ( ECgCommonErrorBase - 42 )
+#define ECgNetworkInvalidAddress ( ECgCommonErrorBase - 43 )
+#define ECgNetworkPortAlreadyInUse ( ECgCommonErrorBase - 44 )
+#define ECgNetworkTooManyConnections ( ECgCommonErrorBase - 45 )
+#define ECgInvalidFileName ( ECgCommonErrorBase - 46 )
+#define ECgDeviceOpenFail ( ECgCommonErrorBase - 47 )
+#define ECgDataOverrun ( ECgCommonErrorBase - 48 )
+#define ECgNetworkInvalidPort ( ECgCommonErrorBase - 49 )
+#define ECgNetworkSocketNotConnected ( ECgCommonErrorBase - 50 )
+
+#define ECgResume ( ECgCommonErrorBase - 61 )
+#define ECgPowerOff ( ECgCommonErrorBase - 62 )
+
+#define ECgGreater ( ECgCommonErrorBase - 100 )
+#define ECgSmaller ( ECgCommonErrorBase - 101 )
+
+#define ECgTerminate ( ECgCommonErrorBase - 102 )
+#define ECgNotOwner ( ECgCommonErrorBase - 103 )
+#define ECgCanceled ( ECgCommonErrorBase - 104 )
+
+#define ECgIoPending ( ECgCommonErrorBase - 105 )
+#define ECgSingularMatrix ( ECgCommonErrorBase - 106 )
+
+#define ECgIntegerOverFlow ( ECgCommonErrorBase - 107 )
+#define EcgInSufficientWorkPadSize ( ECgCommonErrorBase - 108 )
+#define ECgSatelliteOverflow ( ECgCommonErrorBase - 109 )
+#define ECgLastItem ( ECgCommonErrorBase - 110 )
+
+
+typedef S32 TCgReturnCode;
+
+
+//#if (CG_USE_MAX_LOG_LEVEL >= CGLOG_FATAL)
+//#ifdef CG_LOG_H // CG_LOG_H_USED indicates CgLog.h is included in the compilation
+#ifndef CGXDRIVER_EXPORTS
+ #ifdef CGTEST
+ #define CG_STORE_ERROR_LINE
+ #elif defined DEBUG
+ #define CG_STORE_ERROR_LINE
+ #elif defined _DEBUG
+ #define CG_STORE_ERROR_LINE
+ #endif
+#endif
+
+#ifdef CG_STORE_ERROR_LINE
+ #undef CG_STORE_ERROR_LINE
+#endif
+
+//#endif
+//#endif
+
+BOOL cgRetCode_store_error_line(const char * aFileName, long lineNumber, TCgReturnCode rc);
+BOOL cglog_wrn_file_and_line(const char * aFileName, long aLineNumber, long rc);
+
+#ifdef CG_STORE_ERROR_LINE
+ #define OK(rc) (rc >= ECgOk ? TRUE : cgRetCode_store_error_line(__FILE__,__LINE__,rc))
+ #define FAIL(rc) (rc < ECgOk ? !cgRetCode_store_error_line(__FILE__,__LINE__,rc) : FALSE)
+ //#define OK(rc) (rc >= ECgOk ? TRUE : cglog_wrn_file_and_line(__FILE__,__LINE__,rc))
+ //#define FAIL(rc) (rc < ECgOk ? !cglog_wrn_file_and_line(__FILE__,__LINE__,rc) : FALSE)
+#else
+ #define OK(rc) (rc >= ECgOk)
+ #define FAIL(rc) (rc < ECgOk)
+#endif
+
+#define SELECT_FIRST_ERROR2(rc1,rc2) (rc1 == ECgOk) ? rc2 : rc1
+#define SELECT_FIRST_ERROR3(rc1,rc2,rc3) SELECT_FIRST_ERROR2((SELECT_FIRST_ERROR2(rc1,rc2)),rc3)
+#define SELECT_FIRST_ERROR4(rc1,rc2,rc3,rc4) SELECT_FIRST_ERROR2((SELECT_FIRST_ERROR3(rc1,rc2,rc3)),rc4)
+#define SELECT_FIRST_ERROR5(rc1,rc2,rc3,rc4,rc5)SELECT_FIRST_ERROR2((SELECT_FIRST_ERROR4(rc1,rc2,rc3,rc4)),rc5)
+
+// 0 indicates no error. index starts at 1.
+#define INDEX_FIRST_ERROR2(rc1,rc2) ((rc1 == ECgOk) ? ((rc2 == ECgOk) ? 0 : 2) : 1)
+#define INDEX_FIRST_ERROR3(rc1,rc2,rc3) ((rc3 == ECgOk) ? INDEX_FIRST_ERROR2(rc1,rc2) : 3)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CG_RETURN_CODES_H
diff --git a/drivers/misc/gpsip/cgdriver/CgTypes.h b/drivers/misc/gpsip/cgdriver/CgTypes.h
new file mode 100644
index 00000000..0e4d1332
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgTypes.h
@@ -0,0 +1,227 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+/**
+ \file
+ \brief CellGuide global types
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+*/
+#ifndef _CG_TYPES_H
+#define _CG_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /*__cplusplus*/
+
+/** Unsigned 8 bit data */
+typedef unsigned char U8;
+/** Unsigned 16 bit data */
+typedef unsigned short U16;
+/** Unsigned 32 bit data*/
+typedef unsigned long U32;
+/** Signed 8 bit data */
+typedef signed char S8;
+/** Signed 16 bit data */
+typedef signed short S16;
+/** Signed 32 bit data */
+typedef signed long S32;
+/** 8-bit text data */
+typedef char T8;
+/** 16-bit text data */
+typedef U16 T16;
+
+#define CG_MAX_S32 (0x7FFFFFFF)
+#define CG_MAX_S16 (0x7FFF)
+
+#if !(defined (__BORLANDC__)) && !(defined (_MSC_VER)) && !(defined(TCC7801))
+/** Boolean, TRUE/FALSE */
+ #define BOOL U8
+#endif /* !(defined (__BORLANDC__) && defined (_MSC_VER)) */
+
+#if !(defined (__BORLANDC__)) && !(defined (_MSC_VER)) && !(defined (APPROACH5C))
+ /** void */
+ typedef void VOID;
+#endif /* !(defined (__BORLANDC__) && defined (_MSC_VER)) */
+
+
+#ifdef __BORLANDC__
+ typedef int BOOL;
+#endif
+
+#ifdef _MSC_VER
+ typedef int BOOL;
+#endif
+
+
+#ifdef TCC7801
+ typedef int BOOL;
+#endif
+
+
+#if defined (_MSC_VER)
+ //#define U64_ZERO 0
+ // typedef unsigned __int64 U64_32; /* unsigned 64 bit data */ // TODO Noam - made problems in hardware files...
+ #define U64_ZERO {0,0}
+ typedef struct {
+ U32 low;
+ U32 high;
+ } U64_32;
+ typedef __int64 S64; /* signed 64 bit data */
+ typedef __int64 SINT64; /* signed 64 bit data */
+ typedef unsigned __int64 U64; /* signed 64 bit data */
+#elif defined (__LINUX__)
+ #define U64_ZERO {0,0}
+ typedef struct {
+ U32 low;
+ U32 high;
+ } U64_32;
+ typedef signed long long int S64; /* signed 64 bit data */
+ typedef signed long long int SINT64; /* signed 64 bit data */
+ typedef unsigned long long int U64; /* signed 64 bit data */
+#elif /*defined (__BORLANDC__) || */defined(EN_64BIT_INTEGER)
+ #define U64_ZERO 0
+ typedef unsigned long long U64; /* unsigned 64 bit data */
+ typedef long long S64; /* signed 64 bit data */
+ typedef long long SINT64; /* signed 64 bit data */
+#else
+ // All that are not WCE not Linux (ADS1_2 for instance)
+ #define U64_ZERO {0,0}
+/** a structure for 64-bit integer */
+ typedef struct {
+ U32 low;
+ U32 high;
+ } U64_32;
+ typedef unsigned long long U64; /* unsigned 64 bit data */
+/** a structure for 64-bit signed integer */
+ typedef struct {
+ S32 low;
+ S32 high;
+ } S64;
+ typedef long long SINT64; /* signed 64 bit data */
+#endif
+
+/** Single-precision floating point */
+typedef float FLOAT;
+/** Double-precision floating point */
+typedef double DOUBLE;
+
+typedef S16 DATA;
+typedef S32 LDATA;
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+#ifndef TRUE
+ #define TRUE 1
+#endif
+#ifndef FALSE
+ #define FALSE 0
+#endif
+
+#if (defined(__TARGET_ARCH_4T) ||defined (__CW32__) || defined (__GCC32__) || defined (__UCSO__) || defined (__LINUX__) ||\
+ defined (__SYMBIAN__) ||defined (__NUCLEUS__) || defined (__BORLANDC__) || defined (_MSC_VER) || defined(MP_211) || defined(APPROACH5C)) ||\
+ defined (__ARMEL__ )
+#ifndef LITTLE_ENDIAN
+ #define LITTLE_ENDIAN
+#endif
+#else
+ #define BIG_ENDIAN
+#endif /* */
+
+/** file types for ADM (Assistance Data Manager)*/
+typedef enum
+{
+ ECgAgpsBinaryFile = 0,
+ ECgAgpsRawBinaryFile,
+ ECgAgpsAsciiFile,
+ ECgAgpsAlmanacSemFile,
+ ECgAgpsAlmanacYumaFile
+} TCgFileType;
+
+
+/* This type will be added if it is not exists in our target compiler */
+typedef enum {
+ cgFALSE = 0 ,
+ cgTRUE = 0x7FFF
+} cgBool ;
+
+typedef U16 USHORT;
+typedef U8 UCHAR;
+typedef U32 ULONG;
+
+// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+// TEMPORARY CODE - NOAM
+//@@
+/*************************************************************************************************
+ Type: TCgAgpsIonosphere
+ Description: Ionosphere data
+*************************************************************************************************/
+
+//@@
+/*************************************************************************************************
+ Type: TCgAgpsPosition
+ Description: Geographical position
+*************************************************************************************************/
+// TODO NG 22/6/2010 should be replaced with TCgCoordinatesLLA (from CgCoordinates.h)
+typedef struct SCgAgpsPosition
+{
+ DOUBLE latitude; /** geographical latitude */
+ DOUBLE longitude; /** geographical longitude */
+ DOUBLE altitude; /** geographical altitude */
+} TCgAgpsPosition;
+
+#define ALTITUDE_NOT_VALID (0xFFFF)
+typedef struct
+{
+ S16 altitude; /** height (from database) [meters] */
+ U16 err; /** Height expected error [meters] */
+}TCgHeightData;
+
+#ifdef __GCC32__
+ #define __STRUCT_PACKED__ __attribute__ ((packed))
+#else
+ #define __STRUCT_PACKED__
+#endif
+
+
+typedef enum {
+ ECG_BYTE_ORDER_1234 = 0x0,
+ ECG_BYTE_ORDER_2143 = 0x1,
+ ECG_BYTE_ORDER_3412 = 0x2,
+ ECG_BYTE_ORDER_4321 = 0x3
+} TCgByteOrder;
+
+typedef enum {
+ ECG_SWAP_NONE,
+ ECG_SWAP_BYTES,
+ ECG_SWAP_WORDS,
+ ECG_SWAP_BYTES_AND_WORDS
+}TCgByteSwapType;
+
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_CG_AGPS_GENERAL_TYPES_H*/
diff --git a/drivers/misc/gpsip/cgdriver/CgVersion.h b/drivers/misc/gpsip/cgdriver/CgVersion.h
new file mode 100644
index 00000000..fba143d7
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgVersion.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+/**
+ \file CgVersion.h
+ \brief
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+ Defines
+*/
+#ifndef CG_VERSION_H
+#define CG_VERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /*__cplusplus*/
+
+#include "CgTypes.h" /**< CellGuide Types */
+
+#ifdef CGTEST
+ #define CG_BUILD_MODE "TEST"
+#elif defined(DEBUG) || defined (_DEBUG)
+ #define CG_BUILD_MODE "DEBUG"
+#else
+ #define CG_BUILD_MODE "RELEASE"
+#endif
+
+
+/**
+ * VERSION type to pass VERSION types of information using one union
+*/
+typedef struct SCgVersion{
+ const char *buildVersion;
+ const char *buildOriginator;
+ const char *buildName;
+ const char *buildNumber;
+ const char *buildDate;
+ const char *buildTime;
+ const char *buildMode;
+} TCgVersion;
+
+
+
+const char *CgVersionBuildNumber(const TCgVersion *apVersion);
+const char *CgVersionBuildDate(const TCgVersion *apVersion);
+const char *CgVersionBuildTime(const TCgVersion *apVersion);
+
+
+
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverApi.h b/drivers/misc/gpsip/cgdriver/CgxDriverApi.h
new file mode 100644
index 00000000..352ae68b
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverApi.h
@@ -0,0 +1,436 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CGsnap driver API
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+ This file defines the application interface to interact with the CGsnap device driver.
+
+*/
+
+#ifndef _CGX_DRIVER_API_H__
+#define _CGX_DRIVER_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+#include "CgTypes.h"
+#include "CgReturnCodes.h"
+#include "CgCpu.h"
+
+
+
+/** IOCTL codes:*/
+#define CGX_IOCTL_INIT 0x0001 /**< Initialize driver */
+#define CGX_IOCTL_STOP 0x0002 /**< Driver stop and de-initialize */
+#define CGX_IOCTL_WRITE 0x0003 /**< ACLYS only: Write data */
+#define CGX_IOCTL_PREPARE_RECEIVE 0x0004 /**< Prepare for massive data (snap) transfer */
+#define CGX_IOCTL_RESET 0x0005 /**< Reset device */
+#define CGX_IOCTL_POWER_UP 0x0006 /**< Power up device */
+#define CGX_IOCTL_STATUS 0x0007 /**< Get driver status */
+#define CGX_IOCTL_GPIO_SET 0x0008 /**< Set Host GPIO */
+#define CGX_IOCTL_GPIO_GET 0x0009 /**< Get Host GPIO */
+#define CGX_IOCTL_GPIO_MODE_SET 0x000A /**< Set Host GPIO mode */
+
+#define CGX_IOCTL_GET_VERSION 0x001A /**< Get driver version */
+#define CGX_IOCTL_CLEAR_OVERRUN 0x001B /**< ACLYS only */
+#define CGX_IOCTL_WAIT_RCV 0x001C /**< Wait for massive transfer to finish */
+#define CGX_IOCTL_CANCEL_RECEIVE 0x001D /**< Cancel massive transfer */
+#define CGX_IOCTL_ALLOC_BUFF 0x001E /**< Allocate kernel work memory buffer */
+#define CGX_IOCTL_FREE_BUFF 0x001F /**< Free kernel work memory buffer */
+#define CGX_IOCTL_READ_REG 0x0020 /**< CGsnap only: Read device register */
+#define CGX_IOCTL_WRITE_REG 0x0021 /**< CGsnap only: Write device register */
+#define CGX_IOCTL_POWER_DOWN 0x0022 /**< Power down device */
+#define CGX_IOCTL_COUNTER_RESET 0x0023 /**< Reset counters */
+#define CGX_IOCTL_READ_MEM 0x0024 /**< Read memory address */
+#define CGX_IOCTL_RECORD_START 0x0015 /**< Setup and start raw data recording */
+#define CGX_IOCTL_RECORD_WAIT 0x0016 /**< Wait for recording block */
+#define CGX_IOCTL_RECORD_STOP 0x0017 /**< Stop raw data recording */
+#define CGX_IOCTL_READ_RTC 0x0028
+#define CGX_IOCTL_CPU_REVISION 0x0029 /**< Detect CPU revision */
+#define CGX_IOCTL_RESUME_CLEAR 0x002A /**< clear resume mode */
+
+#define CGX_IOCTL_TCXO_ENABLE 0x0030 /**< TCXO Enable/Disable control */
+
+#define CGX_IOCTL_POWER_OFF 0x0040 /**< Cut power completely from the device */
+#define CGX_IOCTL_POWER_ON 0x0041 /**< Restore power fully to the device */
+
+#define CGX_IOCTL_RF_WRITE_CONTROL 0x0050 /**< Write to RF control channel */
+
+#define CGX_IOCTL_DMA_TEST 0x0100 /**< DMA test */
+
+
+
+
+
+/** Driver transfer control structure */
+
+typedef struct {
+ U32 physAddr; /**< Physical address */
+ U8 *virtAddr; /**< Virtual address, in the application process' address space */
+ U32 length; /**< Length, in bytes */
+ U8 * driverContextVirtBufferAddr; /**< virtual address, of buffer used between the DMA and the driver */
+ /**< in the driver process' context */
+} TCgxDriverPhysicalMemory;
+
+#ifndef MAX_NUM_OF_BLOCKS_IN_SINGLE_DMA_XFER
+ /**
+ Define the maximum number of blocks in a single DMA transfer
+ **/
+ #define MAX_NUM_OF_BLOCKS_IN_SINGLE_DMA_XFER 64 // For now, same as MAX_DMA_TRANSFER_TASKS
+#endif
+
+/** Driver state structure */
+typedef struct {
+ struct {
+ BOOL terminate; /**< Termination flag (for IST) */
+ BOOL wait; /**< Wait for transfer complete flag */
+ BOOL overrun; /**< Overrun indication */
+ BOOL resume; /**< Resume indication */
+ } flags; /**< Flags */
+ struct {
+ struct {
+ U32 all; /**< Total interrupts counter */
+ U32 snapStart; /**< Snap start interrupts counter */
+ U32 overrun; /**< Overrun interrupts counter */
+ } interrupt; /**< Interrupts counters*/
+ } counters; /**< Counters */
+ struct {
+ U32 bufferPhys; /**< physical memory address of receive buffer */
+ U8 *originalBuffer; /**< pointer to original received data buffer (as passed by caller) */
+ TCgByteOrder byteOrder; /**< required byte order for active transfer*/
+ BOOL done; /**< active transfer done flag*/
+ struct {
+ U32 required; /**< total number of bytes required for active transfer*/
+ U32 received; /**< number of bytes received in active transfer*/
+ } bytes;
+ struct {
+ U32 required; /**< total number of blocks to receive */
+ U32 received; /**< number of blocks already received */
+ } blocks;
+ struct {
+ U32 required; /**< total number of DMA tasks */
+ U32 received; /**< number of DMA tasks processed */
+ U32 active; /**< active task index */
+ } chunks;
+ struct {
+ BOOL request; /**< Abort transfer flag */
+ U32 onByte; /**< if cancel is requested, indicate the cancel position*/
+ U32 onChunk;
+ } cancel;
+ U32 bufferOffset[MAX_NUM_OF_BLOCKS_IN_SINGLE_DMA_XFER]; /**< Internal buffer addresses (for DMA) */
+ U32 blockSize; /**< Current transfer block size */
+ U32 lastBlockSize; /**< Current transfer last block size (might be smaller or larger)*/
+ } transfer;
+ TCgxDriverPhysicalMemory buffer; /**< Snap buffer information*/
+ TCgReturnCode constructionRc;/**< What return code was returned from the driver construction*/
+} TCgxDriverState;
+
+
+
+
+/** Driver control structure, passed from application on IOCTL call*/
+typedef union
+{
+ struct {
+ U32 alignedLength; /**< Number of bytes to write (aligned to hardware requirements) */
+ U32 blockLength; /**< Block length (zero for single block snap) */
+ TCgByteOrder byteOrder; /**< Required byte order */
+ unsigned char *buf; /**< pointer to memory allocated for the data */
+ U32 bufPhys; /**< CGsnap only: */
+ U32 timeoutMS; /**< Timeout in mili-seconds */
+ } read; /**< Read data */
+
+ struct {
+ U32 timeoutMS; /**< Timeout in milli-seconds */
+ U32 blockNumber; /**< Block number to wait for */
+ } wait;
+
+ struct {
+ unsigned char *pSource; /**< Source address to write from */
+ U32 length; /**< Number of bytes to write */
+ } write; /**< ACLYS only: Write data to ACLYS */
+
+ struct {
+ U32 code; /**< GPIO code (CellGuide conventions)*/
+ U32 out; /**< GPIO value for output (write) operation*/
+ TCgCpuGpioMode mode; /**< GPIO mode to set */
+ } GPIO; /**< Manual Read/Write GPIO */
+
+ struct {
+ U32 offset; /**< register offset from CGsnap base address */
+ } readReg; /**< CGsnap only: Read CGsnap register */
+
+ struct {
+ U32 offset; /**< Register offset from CGsnap base address */
+ U32 value; /**< Value to write */
+ } writeReg; /**< CGsnap only: Write CGsnap register */
+
+ struct {
+ U32 onByteCount; /**< Position to cancel the transfer
+ 0 = Transfer will be canceled as soon as possible
+ n = Transfer will be canceled as soon as possible After n bytes have been received
+ */
+ } cancel; /**< Cancel transfer request */
+ struct {
+ U32 resetLevel; /**< Reset level:
+ 0 = Normal-Reset
+ 1 = Semi-Reset
+ */
+ } reset; /**< Reset transfer request */
+
+ struct {
+ U32 length; /**< Number of bytes to allocate */
+ U32 processId; /**< ID of process that requested the buffer allocation */
+ } alloc; /**< Allocate In-Kernel Transfer Buffer */
+
+ struct {
+ BOOL enable; /**< enable power to TCXO */
+ } tcxoControl; /**< Control TCXO power */
+
+} TCgDriverControl;
+
+
+
+
+/** Driver results structure, returned from driver on IOCTL call finish*/
+typedef struct
+{
+ TCgReturnCode rc; /**< Last operation detailed return code*/
+ struct {
+ void *bufferPhysAddr; /**< Pointer to buffer start */
+ void *bufferAppVirtAddr; /**< Pointer to buffer start virtual address, in application's process' context*/
+ U32 size; /**< Number of bytes*/
+ } buffer; /**< Retrieve incoming data buffer details */
+
+ struct {
+ U32 code; /**< GPIO code (CellGuide conventions)*/
+ U32 val; /**< GPIO value for output (write) operation*/
+ } GPIO; /**< Result for GPIO Read request*/
+
+ struct {
+ char buildVersion[32]; /**< Build version ("1.8") */
+ char buildNumber[32]; /**< Build number ("1747") */
+ char buildDate[32]; /**< Build date ("10/04/2007")*/
+ char buildTime[32]; /**< Build time ("03:49")*/
+ char buildMode[32]; /**< Build mode ("RELEASE", "DEBUG", "TEST")*/
+ char buildName[32]; /**< Driver platform name*/
+ } version; /**< Retrieve driver version info*/
+
+ struct {
+ U32 offset; /**< Register offset from CGsnap base address */
+ U32 value; /**< REgister value */
+ } readReg; /**< CGsnap only: Result for CGsnap register read request*/
+
+ struct {
+ char revisionCode[32]; /**< CPU revision code */
+ } cpuRevision; /**< Detect CPU revision */
+
+ struct {
+ U32 year;
+ U32 month;
+ U32 day;
+ U32 hour;
+ U32 minute;
+ U32 second;
+ U32 dayInWeek;
+ U32 tick;
+ } readRtc;
+
+ TCgxDriverState state; /**< Driver internal state information (for debug) */
+} TCgDriverStatus;
+
+
+
+/*for 64 bit system struct*/
+
+typedef struct {
+ unsigned int physAddr; /**< Physical address */
+ unsigned int virtAddr; /**< Virtual address, in the application process' address space */
+ unsigned int length; /**< Length, in bytes */
+ unsigned int driverContextVirtBufferAddr; /**< virtual address, of buffer used between the DMA and the driver */
+ /**< in the driver process' context */
+} TCgxDriverPhysicalMemory_32bit;
+
+
+/** Driver state structure */
+typedef struct {
+ struct {
+ BOOL terminate; /**< Termination flag (for IST) */
+ BOOL wait; /**< Wait for transfer complete flag */
+ BOOL overrun; /**< Overrun indication */
+ BOOL resume; /**< Resume indication */
+ } flags; /**< Flags */
+ struct {
+ struct {
+ unsigned int all; /**< Total interrupts counter */
+ unsigned int snapStart; /**< Snap start interrupts counter */
+ unsigned int overrun; /**< Overrun interrupts counter */
+ } interrupt; /**< Interrupts counters*/
+ } counters; /**< Counters */
+ struct {
+ unsigned int bufferPhys; /**< physical memory address of receive buffer */
+ unsigned int originalBuffer; /**< pointer to original received data buffer (as passed by caller) */
+ TCgByteOrder byteOrder; /**< required byte order for active transfer*/
+ BOOL done; /**< active transfer done flag*/
+ struct {
+ unsigned int required; /**< total number of bytes required for active transfer*/
+ unsigned int received; /**< number of bytes received in active transfer*/
+ } bytes;
+ struct {
+ unsigned int required; /**< total number of blocks to receive */
+ unsigned int received; /**< number of blocks already received */
+ } blocks;
+ struct {
+ unsigned int required; /**< total number of DMA tasks */
+ unsigned int received; /**< number of DMA tasks processed */
+ unsigned int active; /**< active task index */
+ } chunks;
+ struct {
+ BOOL request; /**< Abort transfer flag */
+ unsigned int onByte; /**< if cancel is requested, indicate the cancel position*/
+ unsigned int onChunk;
+ } cancel;
+ unsigned int bufferOffset[MAX_NUM_OF_BLOCKS_IN_SINGLE_DMA_XFER]; /**< Internal buffer addresses (for DMA) */
+ unsigned int blockSize; /**< Current transfer block size */
+ unsigned int lastBlockSize; /**< Current transfer last block size (might be smaller or larger)*/
+ } transfer;
+ TCgxDriverPhysicalMemory_32bit buffer; /**< Snap buffer information*/
+ signed int constructionRc;/**< What return code was returned from the driver construction*/
+} TCgxDriverState_32bit;
+
+
+/** Driver results structure, returned from driver on IOCTL call finish*/
+typedef struct
+{
+ signed int rc; /**< Last operation detailed return code*/
+ struct {
+ unsigned int bufferPhysAddr; /**< Pointer to buffer start */
+ unsigned int bufferAppVirtAddr; /**< Pointer to buffer start virtual address, in application's process' context*/
+ unsigned int size; /**< Number of bytes*/
+ } buffer; /**< Retrieve incoming data buffer details */
+
+ struct {
+ unsigned int code; /**< GPIO code (CellGuide conventions)*/
+ unsigned int val; /**< GPIO value for output (write) operation*/
+ } GPIO; /**< Result for GPIO Read request*/
+
+ struct {
+ char buildVersion[32]; /**< Build version ("1.8") */
+ char buildNumber[32]; /**< Build number ("1747") */
+ char buildDate[32]; /**< Build date ("10/04/2007")*/
+ char buildTime[32]; /**< Build time ("03:49")*/
+ char buildMode[32]; /**< Build mode ("RELEASE", "DEBUG", "TEST")*/
+ char buildName[32]; /**< Driver platform name*/
+ } version; /**< Retrieve driver version info*/
+
+ struct {
+ unsigned int offset; /**< Register offset from CGsnap base address */
+ unsigned int value; /**< REgister value */
+ } readReg; /**< CGsnap only: Result for CGsnap register read request*/
+
+ struct {
+ char revisionCode[32]; /**< CPU revision code */
+ } cpuRevision; /**< Detect CPU revision */
+
+ struct {
+ unsigned int year;
+ unsigned int month;
+ unsigned int day;
+ unsigned int hour;
+ unsigned int minute;
+ unsigned int second;
+ unsigned int dayInWeek;
+ unsigned int tick;
+ } readRtc;
+
+ TCgxDriverState_32bit state; /**< Driver internal state information (for debug) */
+} TCgDriverStatus_32bit;
+
+
+/** Driver control structure, passed from application on IOCTL call*/
+typedef union
+{
+ struct {
+ unsigned int alignedLength; /**< Number of bytes to write (aligned to hardware requirements) */
+ unsigned int blockLength; /**< Block length (zero for single block snap) */
+ TCgByteOrder byteOrder; /**< Required byte order */
+ unsigned int buf; /**< pointer to memory allocated for the data */
+ unsigned int bufPhys; /**< CGsnap only: */
+ unsigned int timeoutMS; /**< Timeout in mili-seconds */
+ } read; /**< Read data */
+
+ struct {
+ unsigned int timeoutMS; /**< Timeout in milli-seconds */
+ unsigned int blockNumber; /**< Block number to wait for */
+ } wait;
+
+ struct {
+ unsigned int pSource; /**< Source address to write from */
+ unsigned int length; /**< Number of bytes to write */
+ } write; /**< ACLYS only: Write data to ACLYS */
+
+ struct {
+ unsigned int code; /**< GPIO code (CellGuide conventions)*/
+ unsigned int out; /**< GPIO value for output (write) operation*/
+ TCgCpuGpioMode mode; /**< GPIO mode to set */
+ } GPIO; /**< Manual Read/Write GPIO */
+
+ struct {
+ unsigned int offset; /**< register offset from CGsnap base address */
+ } readReg; /**< CGsnap only: Read CGsnap register */
+
+ struct {
+ unsigned int offset; /**< Register offset from CGsnap base address */
+ unsigned int value; /**< Value to write */
+ } writeReg; /**< CGsnap only: Write CGsnap register */
+
+ struct {
+ unsigned int onByteCount; /**< Position to cancel the transfer
+ 0 = Transfer will be canceled as soon as possible
+ n = Transfer will be canceled as soon as possible After n bytes have been received
+ */
+ } cancel; /**< Cancel transfer request */
+ struct {
+ unsigned int resetLevel; /**< Reset level:
+ 0 = Normal-Reset
+ 1 = Semi-Reset
+ */
+ } reset; /**< Reset transfer request */
+
+ struct {
+ unsigned int length; /**< Number of bytes to allocate */
+ unsigned int processId; /**< ID of process that requested the buffer allocation */
+ } alloc; /**< Allocate In-Kernel Transfer Buffer */
+
+ struct {
+ BOOL enable; /**< enable power to TCXO */
+ } tcxoControl; /**< Control TCXO power */
+
+} TCgDriverControl_32bit;
+
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif //__cplusplus
+
+
+#endif // _CGXDRIVERAPI_H__
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverCore.c b/drivers/misc/gpsip/cgdriver/CgxDriverCore.c
new file mode 100644
index 00000000..d1045624
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverCore.c
@@ -0,0 +1,819 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CellGuide CGsnap driver core logic (OS & CPU independed)
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+
+#include <linux/delay.h>
+
+#include "CgxDriverCore.h"
+#include "CgCpu.h"
+#include "CgCpuOs.h"
+#include "platform.h"
+#include "CgxDriverPlatform.h"
+#include "CgxDriverOs.h"
+#include "CgBuildNumber.h"
+#include "CgVersion.h"
+#include "CgxDriverCoreCommon.h"
+
+
+/**
+ Driver version structure
+ \note this structure is filled automatically on build time, by CellGuide build machine
+*/
+const TCgVersion gCgDriverVersion = {
+ CG_BUILD_VERSION, /**< Software Version number (Text)*/
+ CG_BUILD_ORIGINATOR, /**< Build Originator name (Text)*/
+ CGX_PLATFORM_NAME, /**< Platform Name (Text), as specified in platform.h file */
+ CG_BUILD_NUMBER, /**< Unique Build Number (Text) - automatically assigned by build machine*/
+ CG_BUILD_DATE, /**< Build Date (Text)*/
+ CG_BUILD_TIME, /**< Build Time (Text)*/
+ CG_BUILD_MODE /**< Build Mode (Text) - Release/Test/Debug */
+};
+
+extern void gps_chip_power_on(void);
+extern void gps_chip_power_off(void);
+extern void gps_gpio_request(void);
+
+#define CG_MATH_ALIGNMENT(__var__,__base__) __var__ = (__base__) * ((U32)(((__var__) + ((__base__)/2)) / (__base__)))
+
+
+TCgCpuDmaTask gChunksList[MAX_DMA_TRANSFER_TASKS]; /**< DMA tasks list */
+S32 CgxDriverSnapLengthExtraBytes = 0;
+
+extern U32 CGCORE_BASE_ADDR;
+
+/** CGsnap GPO register offset */
+const U32 CGCORE_REG_OFFSET_GPO = 0x00000040;
+
+/** CGsnap version register offset */
+const U32 CGCORE_REG_OFFSET_VERSION = 0x00000044;
+
+/** CGsnap interrupt register offset (KAGPSRawInt)*/
+const U32 CGCORE_REG_RAW_INT = 0x00000080;
+
+/** CGsnap Soft_CMD register offset */
+const U32 CGCORE_REG_OFFSET_SOFT_CMD = 0x000000CC;
+const U32 CGCORE_SOFT_CMD_POWER_DOWN = 0xFDB96420;
+
+/** CGsnap reset register offset */
+
+const U32 CGCORE_REG_OFFSET_CORE_RESETS = 0x000000FC;
+
+#ifndef RF_POWER_UP_VAL
+ #define RF_POWER_UP_VAL (0) // ACLYS requires '0' for PU
+#endif
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+extern void init_spi_block_var(void);
+static unsigned int block_num;
+#endif
+bool flag_power_up = 0;
+TCgReturnCode CgxDriverTcxoControl(u32 aEnable);
+
+#define CGCORE_ENABLE_CORE (0x00000000)
+#define CGCORE_ENABLE_TCXO (0x00000001)
+#define CGCORE_ENABLE_RTC (0x00000002)
+#define CGCORE_ENABLE_BS (0x00000003)
+#define CGCORE_RF_POWER_UP_POL (0x00000004) // RF Power up polarity. "Power UP" GPO[0] value is determined by this bit's value.
+ // (if bit is '1', during power up, the IP will output '1', and during power down,
+ // it will output '0'. When this bit is '0', the output is reversed)
+
+const U32 CGCORE_CORE_RESETS_ENABLE = ((1<<CGCORE_ENABLE_CORE) | (1<<CGCORE_ENABLE_TCXO) | ( RF_POWER_UP_VAL * (1<<CGCORE_RF_POWER_UP_POL)));
+ // This is the default 'enable' value, to the core_Resets register.
+ // It needs to be written prior to accessing CGsnap.
+ // ALL CGCORE_ENABLE_XXX are reset to 0, when the MasterReset pin is toggled
+
+#define CGCORE_ENABLE_DMA (5)
+#define CGCORE_ENABLE_GPS (12)
+
+
+#define CGCORE_ENABLE_SCLK ((1<<CGCORE_ENABLE_DMA) | (1<<CGCORE_ENABLE_GPS))
+#define CGCORE_RESET_DELAY (1000) // Used as a delay between '0' and '1', when reseting the CGsnap
+
+TCgReturnCode CGCoreReset(U32 aUnitToReset);
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+//bxd add for slck enable
+TCgReturnCode CGCoreSclkEnable(int enable)
+{
+ TCgReturnCode rc = ECgOk;
+
+ if(1 == enable)
+ {
+ sci_glb_set(CG_DRIVER_SCLK_VA,BIT_12);
+ }
+ else if(0 == enable)
+ {
+ sci_glb_clr(CG_DRIVER_SCLK_VA,BIT_12);
+ }
+ return rc;
+}
+#endif
+
+
+TCgReturnCode CgxDriverDestroy(void *pDriver)
+{
+ DBG_FUNC_NAME("CgxDriverDestroy")
+ TCgReturnCode rc = ECgOk;
+
+ rc = CgCpuDmaDestroy(CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070);
+ if (!OK(rc)) DBGMSG("Failed to destroy DMA");
+ rc = CgCpuGpioDestroy();
+ if (!OK(rc)) DBGMSG("Failed to destroy GPIO");
+ rc = CgCpuIntrDestroy();
+ if (!OK(rc)) DBGMSG("Failed to destroy INTR");
+ rc = CgCpuClockDestroy();
+ if (!OK(rc)) DBGMSG("Failed to destroy CLK");
+ rc = CgxDriverTransferEndDestroy(pDriver);
+ return rc;
+}
+
+
+
+TCgReturnCode CgxDriverConstruct(void *pDriver, TCgxDriverState *pState)
+{
+ //DBG_FUNC_NAME("CgxDriverConstruct")
+ TCgReturnCode rc = ECgOk;
+ rc = CgCpuAllocateVa();
+ memset(gChunksList,0,sizeof(TCgCpuDmaTask)*MAX_DMA_TRANSFER_TASKS);
+
+ gps_gpio_request();
+
+#if 0
+ if (OK(rc)) rc = CgCpuDmaCreate(CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070);
+
+ // set up DMA interrupt handler
+ if (OK(rc)) rc = CgxDriverDmaInterruptPrepare();
+#endif
+
+ if (OK(rc)) rc = CgxDriverDataReadyInterruptHandlerStart(pDriver);
+
+ // set up internal synchronization mechanism
+ if (OK(rc)) rc = CgxDriverTransferEndCreate(pDriver);
+
+
+ // set up GPS interrupt handler
+ if (OK(rc)) rc = CgxDriverGpsInterruptPrepare();
+ if (OK(rc)) rc = CgxDriverGpsInterruptHandlerStart(pDriver);
+#if 0
+ // enable IP (not-reset)
+ if (OK(rc)) rc = CgCpuGpioModeSet(CG_DRIVER_GPIO_GPS_MRSTN, ECG_CPU_GPIO_OUTPUT);
+ if (OK(rc)) rc = CgCpuIPMasterResetOn();
+ if (OK(rc)) rc = CgCpuDelay(CGCORE_RESET_DELAY);
+ if (OK(rc)) rc = CgCpuIPMasterResetClear();
+
+ // set up Sclk register
+ if (OK(rc)) rc = CGCoreSclkEnable(1);
+
+ DBGMSG1("CGCORE_CORE_SCLK_ENABLE = 0x%08X", CGCORE_ENABLE_SCLK);
+
+ // set up core-resets register
+ if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, CGCORE_CORE_RESETS_ENABLE);
+
+ DBGMSG1("CGCORE_CORE_RESETS_ENABLE = 0x%08X", CGCORE_CORE_RESETS_ENABLE);
+
+ // Setup GPIO for RF-Power, and power up RF chip
+ //if (OK(rc)) rc = CgCpuGpioModeSet(CG_DRIVER_GPIO_RF_PD, ECG_CPU_GPIO_OUTPUT);
+ //if (OK(rc)) rc = CgxDriverRFPowerUp();
+
+ if (OK(rc)) rc = CgCpuGpioModeSet(CG_DRIVER_GPIO_TCXO_EN, ECG_CPU_GPIO_OUTPUT);
+ if (OK(rc)) rc = CgxDriverTcxoControl(TRUE);
+#endif
+
+ pState->constructionRc = rc; // For later reference (if needed by application)
+ pState->flags.resume = FALSE;
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ gps_chip_power_off();
+ #endif
+ return rc;
+}
+
+
+
+TCgReturnCode CgxDriverPowerUp(void)
+{
+ TCgReturnCode rc = ECgOk;
+ U32 version = 0;
+
+ // In order to power up the CGsnap, do a dummy access
+ rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_VERSION, &version );
+ return rc;
+}
+
+TCgReturnCode CgxDriverPowerDown(void)
+{
+ TCgReturnCode rc = ECgOk;
+
+ // Write software power-down command to CGsnap
+ rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_SOFT_CMD, CGCORE_SOFT_CMD_POWER_DOWN );
+
+ return rc;
+}
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+unsigned int get_block_num(void )
+{
+ return block_num;
+}
+#endif
+
+#if 0
+//gaole add
+void CgCoreReleaseRes(void)
+{
+ printk("\n gaole: run to CgCoreReleaseRes \n");
+ memset(gChunksList,0,sizeof(TCgCpuDmaTask)*MAX_DMA_TRANSFER_TASKS);
+#ifdef CGCORE_ACCESS_VIA_SPI
+ block_num = 0;
+#endif
+}
+
+void CgGpsReset(void)
+{
+ CGCORE_WRITE_REG( 0x00000038, 0x0);
+
+ CGCORE_WRITE_REG( 0x0000003c, 0x0);
+
+ CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, CGCORE_CORE_RESETS_ENABLE);
+}
+#endif
+/*
+split blocks to chunks
+last chunk might be small
+last chunk generate app event
+start of block aligned to chunk size
+*/
+
+TCgReturnCode CgxDriverPrepareRecieve(
+ TCgxDriverState *pState,
+ unsigned char *apBuf,
+ U32 aBufPhys,
+ U32 aBufSize,
+ unsigned long aLength,
+ unsigned long aBlockLength,
+ TCgByteOrder aByteOrder)
+{
+ DBG_FUNC_NAME("CgxDriverPrepareRecieve")
+ TCgReturnCode rc = ECgOk;
+ U32 blockIndex = 0;
+ U32 chunksInBlock = 0;
+ U32 chunkSize = 0;
+ U32 length = aLength + CgxDriverSnapLengthExtraBytes; // Potential patch
+ U32 numOfBlocksInBuffer = 0;
+
+ memset(gChunksList,0,sizeof(TCgCpuDmaTask)*MAX_DMA_TRANSFER_TASKS);
+
+ DBGMSG1("buffer v-address = 0x%x", apBuf);
+ DBGMSG1("start address value = 0x%x", *((U32*)apBuf) );
+ DBGMSG1("dest address value = 0x%x", *((U32*)apBuf + 128) );
+
+ pState->transfer.blockSize = ((aBlockLength == 0) || (length < aBlockLength)) ? length : aBlockLength;
+ /*bxd modify for not limted to 512k Bytes each block*/
+ chunkSize = pState->transfer.blockSize;
+ //chunkSize = MIN(MAX_DMA_CHUNK_SIZE, pState->transfer.blockSize);
+ chunksInBlock = pState->transfer.blockSize / chunkSize;
+
+
+ DBGMSG3("Requested %d bytes, Block=(%d bytes,%d chunks)", length, pState->transfer.blockSize, chunksInBlock);
+ DBGMSG1("Maximum DMA chunk size is set to %d bytes", chunkSize);
+
+ pState->flags.overrun = FALSE;
+ pState->transfer.cancel.request = FALSE;
+ pState->transfer.cancel.onByte = 0;
+ pState->transfer.cancel.onChunk = 0;
+ pState->transfer.done = 0;
+ pState->transfer.originalBuffer = apBuf;
+ pState->transfer.bufferPhys = pState->buffer.physAddr;
+ pState->transfer.byteOrder = aByteOrder;
+
+ pState->transfer.bytes.required = length;
+ pState->transfer.bytes.received = 0;
+
+ pState->transfer.blocks.required = (length + pState->transfer.blockSize - 1) / pState->transfer.blockSize;
+#ifdef CGCORE_ACCESS_VIA_SPI
+ block_num = pState->transfer.blocks.required;
+#endif
+ DBGMSG1("%d blocks required", pState->transfer.blocks.required);
+ pState->transfer.lastBlockSize = length - (pState->transfer.blocks.required - 1) * pState->transfer.blockSize;
+ DBGMSG1("last block size: %d bytes", pState->transfer.lastBlockSize);
+ pState->transfer.blocks.received = 0;
+
+ pState->transfer.chunks.required = 0;
+ pState->transfer.chunks.received = 0;
+ pState->transfer.chunks.active = 0;
+
+ // split snap to blocks
+ //////////////////////////////////////////////////////////////////////////
+
+ if (pState->transfer.blocks.required * chunksInBlock > MAX_DMA_TRANSFER_TASKS) {
+ DBGMSG2("ERROR! too many chunks! %d > %d", pState->transfer.blocks.required * chunksInBlock, MAX_DMA_TRANSFER_TASKS);
+ return ECgErrMemory;
+ }
+
+ numOfBlocksInBuffer = aBufSize / pState->transfer.blockSize;
+ DBGMSG2("aBufSize = %d, blockSize = %d", aBufSize, pState->transfer.blockSize );
+ for(blockIndex = 0; blockIndex < pState->transfer.blocks.required; blockIndex++)
+ {
+ // Init the snap's blocks' offsets
+ pState->transfer.bufferOffset[blockIndex] = pState->transfer.blockSize * (blockIndex % numOfBlocksInBuffer); // roll-over to start of buffer,
+ // if we reached end of buffer.
+ //DBGMSG2("buffer[%d] = 0x%08X", blockIndex, pState->transfer.bufferPhys + pState->transfer.bufferOffset[blockIndex])
+ }
+
+ // split blocks to chunks
+ //////////////////////////////////////////////////////////////////////////
+
+ for(blockIndex = 0; blockIndex < pState->transfer.blocks.required; blockIndex++) {
+ U32 chunkIndex = 0;
+ U32 more, dest;
+
+ more = (blockIndex == (pState->transfer.blocks.required-1)) ? pState->transfer.lastBlockSize : pState->transfer.blockSize;
+ dest = pState->transfer.bufferPhys + pState->transfer.bufferOffset[blockIndex];
+
+ // DBGMSG4("Block %02d/%02d: % 6d bytes @ 0x%08X", blockIndex + 1, pState->transfer.blocks.required,
+ for(chunkIndex = 0; chunkIndex < chunksInBlock-1; chunkIndex++) {
+ U32 size = MIN(more, chunkSize);
+ if ((more - size) < chunkSize)
+ break;
+ gChunksList[pState->transfer.chunks.required].address = dest;
+ gChunksList[pState->transfer.chunks.required].length = size;
+ more -= size;
+ // DBGMSG5("chunk %02d/%02d in block: length %d bytes @ 0x%08X (%d more)", chunkIndex + 1, chunksInBlock,
+ dest += size;
+ pState->transfer.chunks.required++;
+ }
+ // last chunk
+ gChunksList[pState->transfer.chunks.required].address = dest;
+ gChunksList[pState->transfer.chunks.required].length = more;
+ DBGMSG3("last chunk out of %02d in block: % 6d bytes @ 0x%08X", chunksInBlock, more, dest);
+ pState->transfer.chunks.required++;
+ }
+
+ DBGMSG1("%d chunks required", pState->transfer.chunks.required);
+
+ if (length > pState->transfer.blockSize * pState->transfer.blocks.required) {
+ // there are leftovers
+ U32 more = length - pState->transfer.blockSize * pState->transfer.blocks.required;
+ U32 dest = pState->transfer.bufferPhys + pState->transfer.bufferOffset[pState->transfer.blocks.required];
+ DBGMSG4("Extra Block % 2d/% 2d: % 6d bytes @ 0x%08X", pState->transfer.blocks.required, pState->transfer.blocks.required, more, dest);
+ for (; (more > 0) && (pState->transfer.chunks.required < MAX_DMA_TRANSFER_TASKS); pState->transfer.chunks.required++) {
+ U32 size = MIN(more, chunkSize);
+ gChunksList[pState->transfer.chunks.required].address = dest;
+ gChunksList[pState->transfer.chunks.required].length = size;
+ more -= size;
+ dest += size;
+ DBGMSG4("chunk % 4d: % 4d bytes @ 0x%08X (%d bytes left)", pState->transfer.chunks.required + 1, size, dest, more);
+ }
+ DBGMSG1("%d chunks required", pState->transfer.chunks.required);
+ }
+
+
+ // setup 1st DMA chunk
+ #ifndef CGCORE_ACCESS_VIA_SPI
+ rc = CgCpuDmaSetupFromGps(gChunksList, pState->transfer.chunks.required, CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070);
+ rc = CgCpuDmaStart(CG_DRIVER_DMA_CHANNEL_READ);
+ #else
+ // rc =CgxCpuSpiReadData();
+ #endif
+
+ return rc;
+}
+
+
+
+TCgReturnCode CgxDriverIsReadCanceled(TCgxDriverState *pState)
+{
+ DBG_FUNC_NAME("CgxDriverIsReadCanceled")
+ TCgReturnCode rc = ECgOk;
+
+
+ // Check if snap was unconditionally canceled
+ if (pState->transfer.cancel.request && (pState->transfer.bytes.received > pState->transfer.cancel.onByte))
+ {
+ CGCoreReset(CGCORE_ENABLE_CORE);
+ CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ return ECgCanceled;
+ }
+
+ // Check if we have reached the cancel point
+ if (pState->transfer.cancel.request) {
+ U32 curDmaCount = 0;
+ U32 requestedDmaCount = 0;
+ rc = CgCpuDmaRequestedCount(CG_DRIVER_DMA_CHANNEL_READ, &requestedDmaCount); // how many bursts requested to receive
+ DBGMSG1("requestedDmaCount = %d", requestedDmaCount);
+
+ rc = CgCpuDmaCurCount(CG_DRIVER_DMA_CHANNEL_READ, &curDmaCount); // how many bursts left to receive
+ DBGMSG1("curDmaCount = %d", curDmaCount);
+
+ DBGMSG2("%d >= %d ? ==> canceled", pState->transfer.bytes.received + (requestedDmaCount - curDmaCount) , pState->transfer.cancel.onByte);
+
+ if (pState->transfer.bytes.received + (requestedDmaCount - curDmaCount) >= pState->transfer.cancel.onByte)
+ {
+ CGCoreReset(CGCORE_ENABLE_CORE);
+ CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ return ECgCanceled;
+ }
+ }
+
+ return ECgOk;
+}
+
+TCgReturnCode CGCoreEnable(U32 aUnitToEnable)
+{
+ DBG_FUNC_NAME("CGCoreEnable")
+ TCgReturnCode rc = ECgOk;
+
+ U32 enableValue = 1;
+ U32 coreResetsReg = 0;
+
+ rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS, &coreResetsReg);
+// DBGMSG1("Read coreResetsReg=0x%08X", coreResetsReg);
+ REG_SET1(coreResetsReg, aUnitToEnable, enableValue);
+ if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, coreResetsReg);
+ DBGMSG1("Write [0x%08X]", coreResetsReg);
+ return rc;
+}
+
+TCgReturnCode CGCoreDisable(U32 aUnitToDisable)
+{
+ DBG_FUNC_NAME("CGCoreDisable")
+ TCgReturnCode rc = ECgOk;
+
+ U32 disableValue = 0;
+ U32 coreResetsReg = 0;
+
+ rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS,&coreResetsReg);
+// DBGMSG1("Read coreResetsReg=0x%08X", coreResetsReg);
+ REG_SET1(coreResetsReg, aUnitToDisable, disableValue);
+ if (OK(rc)) rc = CGCORE_WRITE_REG(CGCORE_REG_OFFSET_CORE_RESETS,coreResetsReg);
+ DBGMSG1("Write [0x%08X]", coreResetsReg);
+ return ECgOk;
+}
+
+TCgReturnCode CGCoreReset(U32 aUnitToReset)
+{
+ DBG_FUNC_NAME("CGCoreReset")
+ TCgReturnCode rc = ECgOk;
+ U32 coreResetsReg = 0;
+ U32 coreResetsRegOld = 0;
+
+ ////////////////// Core Disable //////////////
+ rc = CGCORE_READ_REG(CGCORE_REG_OFFSET_CORE_RESETS,&coreResetsReg);
+ coreResetsRegOld = coreResetsReg;
+ REG_SET1(coreResetsReg, aUnitToReset, 0);
+ if (OK(rc)) rc = CGCORE_WRITE_REG(CGCORE_REG_OFFSET_CORE_RESETS,coreResetsReg);
+ DBGMSG1("Write [0x%08X]", coreResetsReg);
+
+ if (OK(rc)) rc = CgCpuDelay(CGCORE_RESET_DELAY);
+
+ ////////////////// Core Enable //////////////
+ if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, coreResetsRegOld);
+ DBGMSG1("Write [0x%08X]", coreResetsRegOld);
+
+ return rc;
+}
+
+
+TCgReturnCode CgxDriverExecuteSpecific(
+ void *pDriver,
+ TCgxDriverState *pState,
+ U32 aRequest,
+ TCgDriverControl *pControl,
+ TCgDriverStatus *pResults)
+{
+ DBG_FUNC_NAME("CgxDriverExecuteSpecific")
+ DBGMSG1("aRequest =%x",aRequest);
+ switch (aRequest) {
+ case CGX_IOCTL_INIT:
+ DBGMSG("CGX_IOCTL_INIT");
+ // This is 1st time initialization, meaning the software is restarted, not resumed, so set the state accordingly.
+ DBGMSG1("pState = 0x%x", pState);
+
+ pState->flags.resume = FALSE;
+ DBGMSG("after pState->flags.resume = FALSE;");
+ pResults->rc = CgxDriverInit(pDriver);
+ break;
+
+ case CGX_IOCTL_STOP:
+ pResults->rc = CgxDriverDestroy(pDriver);
+ break;
+
+ case CGX_IOCTL_READ_REG:
+ pState->transfer.cancel.request = FALSE;
+ // Verify register is of the CGX_sat_ram group
+ pResults->readReg.value = 0;
+ DBGMSG1("readReg.offset %x ",pControl->readReg.offset);
+ if ( pControl->readReg.offset >= CGCORE_REG_OFFSET_SAT_RAM && pControl->readReg.offset <= CGCORE_REG_OFFSET_SAT_RAM_LAST )
+ {
+ // Write read command to the APB (9 bits of the register offset, with 0x80000000, as the read command)
+ pResults->rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_APB_COMMAND, (0x000001FF & pControl->readReg.offset) | 0x80000000);
+
+ // Wait 4 system clocks
+ CgCpuDelay(100); // TODO : what is the actual period of this wait. Is it 4 system clocks?
+
+ // Read data from the APB
+ if (OK(pResults->rc))
+ pResults->rc = CGCORE_READ_REG( CGCORE_REG_OFFSET_APB_DATA, &pResults->readReg.value);
+ }
+ else
+ {
+ // It is not part of the CGX_sat_ram. Read register normaly, via the APB
+
+ pResults->rc = CGCORE_READ_REG( pControl->readReg.offset, &pResults->readReg.value);
+ }
+ break;
+
+ case CGX_IOCTL_WRITE_REG:
+ pState->transfer.cancel.request = FALSE;
+ // Write to CGsnap register
+ pResults->rc = CGCORE_WRITE_REG( pControl->writeReg.offset, pControl->writeReg.value);
+ // DBGMSG2("CGX_IOCTL_WRITE_REG *0x%08X = 0x%08X", CGCORE_BASE_ADDR_VA + pControl->writeReg.offset, pControl->writeReg.value);
+ break;
+
+ case CGX_IOCTL_PREPARE_RECEIVE:
+ DBGMSG("CGX_IOCTL_PREPARE_RECEIVE");
+ // Prepare driver for massive data receive (snap)
+ pState->transfer.cancel.request = FALSE;
+ pResults->rc = CgxDriverPrepareRecieve(pState, pControl->read.buf, pControl->read.bufPhys,
+ pState->buffer.length, pControl->read.alignedLength, pControl->read.blockLength,
+ pControl->read.byteOrder);
+ break;
+
+ case CGX_IOCTL_STATUS:
+ pResults->rc = pState->constructionRc;
+ break;
+
+ case CGX_IOCTL_RESUME_CLEAR:
+ DBGMSG("CGX_IOCTL_RESUME_CLEAR!");
+ pState->flags.resume = FALSE;
+ pState->transfer.cancel.request = FALSE;
+ break;
+ case CGX_IOCTL_RESET:
+ DBGMSG1("CGX_IOCTL_RESET level %d", pControl->reset.resetLevel);
+ pState->transfer.cancel.request = FALSE;
+ switch( pControl->reset.resetLevel )
+ {
+ case 0: // Full reset
+ #if 0
+ if (OK(pResults->rc)) pResults->rc = CgCpuIPMasterResetOn();
+ if (OK(pResults->rc)) pResults->rc = CgCpuDelay(CGCORE_RESET_DELAY);
+ if (OK(pResults->rc)) pResults->rc = CgCpuIPMasterResetClear();
+ #endif
+ if (OK(pResults->rc)) pResults->rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_CORE_RESETS, CGCORE_CORE_RESETS_ENABLE);
+ break;
+ case 1: // Semi reset
+ if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_CORE);
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ init_spi_block_var();
+ #endif
+ break;
+ case 2: // CPU reset
+ break;
+ default : // Semi reset, also.
+ if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_CORE);
+ break;
+ }
+ pResults->rc = CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ break;
+
+ case CGX_IOCTL_COUNTER_RESET:
+ DBGMSG("CGX_IOCTL_COUNTER_RESET!");
+ pResults->rc = CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ if (OK(pResults->rc)) pResults->rc = CGCoreReset(CGCORE_ENABLE_TCXO);
+ break;
+
+ case CGX_IOCTL_POWER_DOWN:
+ DBGMSG("CGX_IOCTL_POWER_DOWN!");
+ flag_power_up = 0;
+ pResults->rc = CgxDriverPowerDown();
+ if (OK(pResults->rc)) pResults->rc = CgxDriverRFPowerDown();
+ break;
+
+ case CGX_IOCTL_POWER_UP:
+ flag_power_up = 1;
+ pState->transfer.cancel.request = FALSE;
+ pResults->rc = CgxDriverPowerUp();
+ if (OK(pResults->rc)) pResults->rc = CgxDriverRFPowerUp();
+ break;
+
+ case CGX_IOCTL_POWER_OFF :
+ pResults->rc = CgxDriverPowerOff();
+ break;
+
+ case CGX_IOCTL_POWER_ON :
+ pResults->rc = CgxDriverPowerOn();
+ break;
+
+ case CGX_IOCTL_GPIO_SET:
+ //DBGMSG2("CGX_IOCTL_GPIO_SET 0x%08X = %d", pControl->GPIO.code, pControl->GPIO.out);
+ if (pControl->GPIO.out)
+ pResults->rc = CgCpuGpioSet(pControl->GPIO.code);
+ else
+ pResults->rc = CgCpuGpioReset(pControl->GPIO.code);
+ //rc = CgxDriverDebugGpio((int)pControl->GPIO.code, (int)pControl->GPIO.out);
+ break;
+
+ case CGX_IOCTL_GPIO_GET:
+ //DBGMSG1("CGX_IOCTL_GPIO_GET 0x%08X", pControl->GPIO.code);
+ //pResults->GPIO.in = 0x5a5a;
+ //DBGMSG2("CGX_IOCTL_GPIO_GET before 0x%08X=0x%08X", pControl->GPIO.code, pResults->GPIO.in)
+ pResults->rc = CgCpuGpioGet(pControl->GPIO.code, (int *)&(pResults->GPIO.val));
+ pResults->GPIO.code = pControl->GPIO.code;
+ //DBGMSG2("CGX_IOCTL_GPIO_GET after 0x%08X=0x%08X", pControl->GPIO.code, pResults->GPIO.in)
+ //rc = CgxDriverDebugGpioRead((int)pResults->GPIO.code, (int*)&pResults->GPIO.in);
+ break;
+
+ case CGX_IOCTL_GET_VERSION:
+ memcpy(pResults->version.buildVersion, gCgDriverVersion.buildVersion, sizeof(pResults->version.buildVersion));
+ memcpy(pResults->version.buildMode, gCgDriverVersion.buildMode, sizeof(pResults->version.buildNumber));
+ memcpy(pResults->version.buildNumber, gCgDriverVersion.buildNumber, sizeof(pResults->version.buildNumber));
+ memcpy(pResults->version.buildTime, gCgDriverVersion.buildTime, sizeof(pResults->version.buildTime));
+ memcpy(pResults->version.buildDate, gCgDriverVersion.buildDate, sizeof(pResults->version.buildDate));
+ break;
+
+ case CGX_IOCTL_CANCEL_RECEIVE:
+ DBGMSG1("Request cancel on byte %d", pControl->cancel.onByteCount);
+
+ // set up receive abort flag.
+ // the flag is cleared be prepare receive command
+
+ if (pControl->cancel.onByteCount > (U32)CgxDriverSnapLengthExtraBytes) {
+ pState->transfer.cancel.onByte = pControl->cancel.onByteCount - CgxDriverSnapLengthExtraBytes;
+ CG_MATH_ALIGNMENT((pState->transfer.cancel.onByte), NUMBER_1K);
+ DBGMSG1("cancel on Byte: 0x%08X", pState->transfer.cancel.onByte);
+ }
+ else {
+ pState->transfer.cancel.onByte = 0; // Cancel snap req immediately
+ }
+ pState->transfer.cancel.request = TRUE;
+ DBGMSG1("cancel on Byte: 0x%08X", ((pState->transfer.cancel.onByte / 16) & 0x00FFFFF) | 0x0F000000);
+ CGCORE_WRITE_REG( 0x30, ((pState->transfer.cancel.onByte / 16) & 0x00FFFFF) | 0x0F000000);
+ CGCORE_WRITE_REG( 0x34, 0);
+
+ // check if cancel point passed
+ pResults->rc = CgxDriverIsReadCanceled(pState);
+ if ((pControl->cancel.onByteCount == 0) || // Cancel snap req immediately
+ (!OK(pResults->rc) && pState->flags.wait)) {// release a waiting thread, if any
+ CGCoreReset(CGCORE_ENABLE_CORE);
+ CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ CgxDriverDataReadyInterruptHandler(pDriver, pState);
+ }
+
+ break;
+
+ case CGX_IOCTL_ALLOC_BUFF:
+ DBGMSG1("CGX_IOCTL_ALLOC_BUFF, pControl->alloc.length=%d", pControl->alloc.length);
+
+ // pControl->alloc.length = 1 *1024 * 1024; // 1M
+
+ pResults->rc = CgxDriverAllocInternalBuff(pDriver, pControl->alloc.length,
+ (void**)&(pResults->buffer.bufferPhysAddr), pControl->alloc.processId);
+ DBGMSG1("alloc p =0x%08X", pState->buffer.virtAddr);
+ if (OK(pResults->rc)) {
+ pResults->buffer.size = pControl->alloc.length;
+ pResults->buffer.bufferAppVirtAddr = pState->buffer.virtAddr;
+ }
+ break;
+
+ case CGX_IOCTL_FREE_BUFF:
+ DBGMSG("CGX_IOCTL_FREE_BUFF");
+ pResults->rc = CgxDriverFreeInternalBuff(pDriver, pControl->alloc.processId);
+ break;
+ case CGX_IOCTL_READ_MEM:
+ DBGMSG("CGX_IOCTL_READ_MEM");
+ pState->transfer.cancel.request = FALSE;
+ DBGMSG1("read from 0x%08X", pControl->readReg.offset);
+ pResults->rc = CgxCpuReadMemory(pControl->readReg.offset, 0, &pResults->readReg.value);
+ break;
+
+ case CGX_IOCTL_CPU_REVISION:
+ pResults->rc = CgCpuRevision(pResults->cpuRevision.revisionCode); // TODO - fix CgCpuRevision so it reads from the right address
+ break;
+
+ case CGX_IOCTL_TCXO_ENABLE:
+ DBGMSG("CGX_IOCTL_TCXO_ENABLE");
+ pResults->rc = CgxDriverTcxoControl(pControl->tcxoControl.enable);
+ break;
+
+ case CGX_IOCTL_RF_WRITE_CONTROL:
+ DBGMSG("CGX_IOCTL_RF_WRITE_CONTROL");
+ pResults->rc = CgCpuRFControlWriteByte(pControl->writeReg.value);
+ break;
+
+ default:
+ return ECgGeneralFailure;
+ }
+
+ return ECgOk;
+}
+
+TCgReturnCode CgxDriverPowerOn(void)
+{
+ TCgReturnCode rc = ECgOk;
+
+ gps_chip_power_on();
+
+ // Enable clock to the GPS device
+ msleep(1);
+ rc = CGCoreEnable(CGCORE_ENABLE_TCXO);
+
+ return rc;
+}
+
+TCgReturnCode CgxDriverPowerOff(void)
+{
+ TCgReturnCode rc = ECgOk;
+
+ // Disable clock to the GPS device
+ rc = CGCoreDisable(CGCORE_ENABLE_TCXO);
+ gps_chip_power_off();
+
+ return rc;
+}
+
+TCgReturnCode CgxDriverTcxoControl(u32 aEnable)
+{
+ TCgReturnCode rc = ECgOk;
+
+ if(aEnable)
+ CGCoreEnable(CGCORE_ENABLE_TCXO);
+ else
+ CGCoreDisable(CGCORE_ENABLE_TCXO);
+
+ return rc;
+}
+
+TCgReturnCode CgCGCoreGpioSet(U32 aGpioPin, U32 aVal)
+{
+ TCgReturnCode rc = ECgOk;
+ U32 valToSet = 0;
+
+ if (aGpioPin <= 0 || aGpioPin > 4) rc = ECgBadArgument;
+
+ if (OK(rc)) rc = CGCORE_READ_REG( CGCORE_REG_OFFSET_GPO, &valToSet);
+ REG_SET1(valToSet,aGpioPin,aVal ? 1 : 0);
+ if (OK(rc)) rc = CGCORE_WRITE_REG( CGCORE_REG_OFFSET_GPO, valToSet );
+
+ return rc;
+}
+
+/*
+
+TCgReturnCode CgxDriverRFPowerDown(void)
+{
+ DBG_FUNC_NAME("CgxDriverRFPowerDown")
+ TCgReturnCode rc = ECgOk;
+
+ #if CG_DRIVER_CG_CORE_CONTROLS_RF_PD
+ // Do nothing - Core controls RF power down pin
+ #else
+ #ifdef RF_POWER_UP_VAL
+ rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, RF_POWER_UP_VAL);
+ #else
+ rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, 1);
+ #endif
+ #endif
+
+ return rc;
+}
+
+TCgReturnCode CgxDriverRFPowerUp(void)
+{
+ DBG_FUNC_NAME("CgxDriverRFPowerUp");
+ TCgReturnCode rc = ECgOk;
+
+ #if CG_DRIVER_CG_CORE_CONTROLS_RF_PD
+ // Do nothing - Core controls RF power down pin
+ #else
+ #ifdef RF_POWER_UP_VAL
+ rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, !RF_POWER_UP_VAL);
+ #else
+ rc = CgCpuGpioSet(CG_DRIVER_GPIO_RF_PD, 0);
+ #endif
+ #endif
+
+ return rc;
+}
+
+*/
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverCore.h b/drivers/misc/gpsip/cgdriver/CgxDriverCore.h
new file mode 100644
index 00000000..fdf41bc7
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverCore.h
@@ -0,0 +1,255 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CellGuide CGX5900 driver core prototypes (non-OS depended)
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+#ifndef CGX_DRIVR_CORE_H
+#define CGX_DRIVR_CORE_H
+
+
+#include "CgReturnCodes.h"
+#include "CgxDriverApi.h"
+
+#define CG_CG_CORE_REG_BASE_ADDRESS (0)
+
+/**
+ Stop driver.
+ The function is called as a result of GPSenseEngine CGX_IOCTL_STOP request.
+ Stop the driver current operations, destroy all memory structures and release system resources.
+ this function is the counterpart of CgxDriverConstruct.
+
+ \note Generic function : Not required to be ported
+
+ \param[in] pDriver Global driver structure pointer
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+*/
+TCgReturnCode CgxDriverDestroy(
+ void *pDriver);
+
+
+
+/**
+ Setup driver structure
+
+ \param[in] pDriver Global driver structure pointer
+ \param[in] pState Driver state structure pointer
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverConstruct(
+ void *pDriver,
+ TCgxDriverState *pState);
+
+
+
+
+
+
+/**
+ Execute request
+
+ \param[in] pDriver Global driver structure pointer
+ \param[in] pState Driver state structure pointer
+ \param[in] aRequest
+ \param[in] pControl
+ \param[in] pResults
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverExecute(
+ void *pDriver,
+ TCgxDriverState *pState,
+ U32 aRequest,
+ TCgDriverControl *pControl,
+ TCgDriverStatus *pResults);
+
+/**
+ Execute request, specific to IP/Core
+
+ \param[in] pDriver Global driver structure pointer
+ \param[in] pState Driver state structure pointer
+ \param[in] aRequest
+ \param[in] pControl
+ \param[in] pResults
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverExecuteSpecific(
+ void *pDriver,
+ TCgxDriverState *pState,
+ U32 aRequest,
+ TCgDriverControl *pControl,
+ TCgDriverStatus *pResults);
+
+
+/**
+ Check if request canceled
+
+ \param[in] pState Driver state structure pointer
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverIsReadCanceled(TCgxDriverState *pState);
+
+
+
+/**
+ Handle GPS interrupt
+
+ \param[in] pDriver Global driver structure pointer
+ \param[in] pState Driver state structure pointer
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverGpsInterruptHandler(
+ void *pDriver,
+ TCgxDriverState *pState);
+
+
+
+/**
+ Handle DMA interrupt
+
+ \param[in] pDriver Global driver structure pointer
+ \param[in] pState Driver state structure pointer
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverDataReadyInterruptHandler(
+ void *pDriver,
+ TCgxDriverState *pState);
+
+TCgReturnCode CgxDriverHardwareReset(unsigned long aResetLevel);
+
+/**
+ Move chip to power down mode
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if chip finished power-down
+
+*/
+TCgReturnCode CgxDriverPowerDown(void);
+
+/**
+ Move chip to power up mode
+
+ \return System wide return code (see CgReturnCodes.h)
+ \retval ECgOk if chip finished power-down
+
+*/
+TCgReturnCode CgxDriverPowerUp(void);
+
+/**
+Cut power from the CellGuide device
+
+\return System wide return code (see CgReturnCodes.h)
+\retval ECgOk if chip finished power-down
+
+*/
+TCgReturnCode CgxDriverPowerOn(void);
+
+/**
+Connect power to the CellGuide device
+
+\return System wide return code (see CgReturnCodes.h)
+\retval ECgOk if chip finished power-down
+
+*/
+TCgReturnCode CgxDriverPowerOff(void);
+
+/**
+Move RF chip to power down mode
+
+\return System wide return code (see CgReturnCodes.h)
+\retval ECgOk if RF chip finished power-down
+
+*/
+TCgReturnCode CgxDriverRFPowerDown(void);
+
+/**
+Move RF chip to power down mode
+
+\return System wide return code (see CgReturnCodes.h)
+\retval ECgOk if RF chip finished power-up
+
+*/
+TCgReturnCode CgxDriverRFPowerUp(void);
+
+/**
+ Set output of CGsnap's GPO aGpioPin, to aVal
+
+ \return System wide return code (see CgReturnCodes.h)
+*/
+TCgReturnCode CgCGCoreGpioSet(U32 aGpioPin, U32 aVal);
+
+
+#if 0
+//gaole add
+void CgCoreReleaseRes(void);
+void CgGpsReset(void);
+#endif
+
+
+
+#ifndef MIN
+ #define MIN(__a__, __b__) ((__a__) < (__b__) ? (__a__) : (__b__))
+#endif
+
+//#define CGCORE_ACCESS_VIA_SPI
+extern bool flag_power_up;
+extern void gps_gpio_request(void);
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+extern int gps_spi_sysreg_write_bytes (u32 len, u32 addr, u32 data);
+extern int gps_spi_sysreg_read_bytes (u32 len, u32 addr, u32 * data);
+
+extern int gps_spi_write_bytes( unsigned int len, unsigned int addr,unsigned int data);
+ #define CGCORE_WRITE_REG(addr,val) \
+ gps_spi_write_bytes(1,(U32)addr,val)
+
+
+extern int gps_spi_read_bytes( unsigned int len,unsigned int addr,unsigned int *data);
+ #define CGCORE_READ_REG(addr,val) \
+ gps_spi_read_bytes(1,(U32)addr,(unsigned int *)val)
+
+#else
+ #define CGCORE_WRITE_REG(addr,val) CgxCpuWriteMemory((U32)CG_DRIVER_CGCORE_BASE_VA, (U32)addr, val);
+ #define CGCORE_READ_REG(addr,val) CgxCpuReadMemory((U32)CG_DRIVER_CGCORE_BASE_VA, (U32)addr, val);
+#endif
+
+
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.c b/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.c
new file mode 100644
index 00000000..727b86b4
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.c
@@ -0,0 +1,441 @@
+/******************************************************************************
+* LEGAL NOTICE *
+* *
+* USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+* DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+* WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+* FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+* OR DOCUMENTATION. *
+* NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+* OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+* THE LICENSE TERMS AS STATED. *
+* *
+******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+\file
+\brief CellGuide common driver core logic (OS, CPU and CG_Hardware independent)
+\attention This file should not be modified.
+If you think something is wrong here, please contact CellGuide
+
+*/
+
+
+
+#include "platform.h"
+#include "CgBuildNumber.h"
+#include "CgVersion.h"
+#include "CgCpu.h"
+#include "CgxDriverCore.h"
+#include "CgxDriverCoreCommon.h"
+#include "CgxDriverOs.h"
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+extern void Reset_GPS_RecvAddress(void); //add reset spi rcv address by use space
+extern int data_req_handle (int para, void *param);
+#endif
+extern TCgCpuDmaTask gChunksList[MAX_DMA_TRANSFER_TASKS]; /**< DMA tasks list */
+volatile unsigned int poffset=0;
+/** CGcore base address */
+const U32 CGCORE_BASE_ADDR = CG_DRIVER_CGCORE_BASE_PA; /* Physical */
+
+// Check validity of DMA channel and controller number, for read and write channels
+///////////////////////////////////////////////////////////////////////////////////
+
+//#if (CG_DMA_CONTROLLER(CG_DRIVER_DMA_CHANNEL_READ) > 0)
+#if ( ((CG_DRIVER_DMA_CHANNEL_READ & 0xFFFF0000) >> 16) > 0 )
+#endif
+
+#ifdef CG_DRIVER_DMA_CHANNEL_READ
+ #ifdef CG_DRIVER_DMA_MAX_CONTROLLER
+ #if (CG_DMA_CONTROLLER(CG_DRIVER_DMA_CHANNEL_READ) > CG_DRIVER_DMA_MAX_CONTROLLER)
+ #error DMA controller # is greater than controllers available
+ #endif
+ #else
+ #if ( (CG_DMA_CONTROLLER(CG_DRIVER_DMA_CHANNEL_READ)) > 0)
+ #error DMA controller # is greater than controllers available
+ #endif
+ #endif
+ #ifdef CG_DRIVER_DMA_MAX_CHANNEL
+ #if (CG_DMA_CHANNEL(CG_DRIVER_DMA_CHANNEL_READ) > CG_DRIVER_DMA_MAX_CHANNEL)
+ #error DMA channel # is greater than channels available
+ #endif
+ #else
+ #if (CG_DMA_CHANNEL(CG_DRIVER_DMA_CHANNEL_READ) > 32)
+ #error DMA channel # is greater than channels available
+ #endif
+ #endif
+#endif
+#ifdef CG_DRIVER_DMA_CHANNEL_WRITE
+ #ifdef CG_DRIVER_DMA_MAX_CONTROLLER
+ #if CG_DMA_CONTROLLER(CG_DRIVER_DMA_CHANNEL_WRITE) > CG_DRIVER_DMA_MAX_CONTROLLER
+ #error DMA controller # is greater than controllers available
+ #endif
+ #else
+ #if CG_DMA_CONTROLLER(CG_DRIVER_DMA_CHANNEL_WRITE) > 0
+ #error DMA controller # is greater than controllers available
+ #endif
+ #endif
+ #ifdef CG_DRIVER_DMA_MAX_CHANNEL
+ #if CG_DMA_CHANNEL(CG_DRIVER_DMA_CHANNEL_WRITE) > CG_DRIVER_DMA_MAX_CHANNEL
+ #error DMA channel # is greater than channels available
+ #endif
+ #else
+ #if CG_DMA_CHANNEL(CG_DRIVER_DMA_CHANNEL_WRITE) > 32
+ #error DMA channel # is greater than channels available
+ #endif
+ #endif
+#endif
+
+// Block number starts at 1
+BOOL isBlockCanceled(TCgxDriverState * apState, U32 aBlockNumber)
+{
+ if ( apState->transfer.cancel.request &&
+ aBlockNumber * apState->transfer.blockSize >= apState->transfer.cancel.onByte )
+ return TRUE;
+ return FALSE;
+}
+
+// Block number starts at 1
+BOOL wasBlockReceived(TCgxDriverState * apState, U32 aBlockNumber)
+{
+
+ if ( aBlockNumber <= apState->transfer.blocks.received )
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+extern void trigger_gps_timeout(int timeout);
+#endif
+
+
+TCgReturnCode CgxDriverExecute(
+ void *pDriver,
+ TCgxDriverState *pState,
+ U32 aRequest,
+ TCgDriverControl *pControl,
+ TCgDriverStatus *pResults)
+{
+ DBG_FUNC_NAME("CgxDriverExecute")
+ TCgReturnCode rc = ECgOk;
+
+ if (pControl == NULL) return ECgNullPointer;
+ if (pResults == NULL) return ECgNullPointer;
+ if ((pState->flags.resume == TRUE) && (aRequest != CGX_IOCTL_INIT) && (aRequest != CGX_IOCTL_RESUME_CLEAR))
+ {
+ pResults->rc = ECgResume;
+ pResults->state = *pState;
+ DBGMSG1("Resume Need to clear [%d]", aRequest);
+ return ECgOk;
+ }
+ pResults->rc = ECgOk;
+ switch (aRequest)
+ {
+ case CGX_IOCTL_WAIT_RCV:
+
+ // Check if current block was overrun by the DMA
+ //////////////////////////////////////////////////////////////////////////
+
+ if ( ((S32)pState->transfer.blocks.received - (S32)pControl->wait.blockNumber )
+ > ((S32)pState->buffer.length / (S32)pState->transfer.blockSize) )
+
+ {
+ DBGMSG1("pState->transfer.blocks.received = %d", pState->transfer.blocks.received);
+ DBGMSG1("pControl->wait.blockNumber = %d", pControl->wait.blockNumber);
+ DBGMSG1("pState->buffer.length = %d", pState->buffer.length);
+ DBGMSG1("pState->transfer.blockSize = %d", pState->transfer.blockSize);
+
+ pResults->rc = ECgDataOverrun;
+ }
+
+ DBGMSG3("WAIT_RCV : blocks wait/received/total = %d/%d/%d",
+ pControl->wait.blockNumber + 1, pState->transfer.blocks.received, pState->transfer.blocks.required);
+
+
+
+ // Wait for block, if not canceled or already received
+ //////////////////////////////////////////////////////////////////////////
+
+ if ( !isBlockCanceled(pState, pControl->wait.blockNumber + 1))
+ {
+
+ // Check if block was received - if so, return. If not, wait for it
+ if ( !wasBlockReceived(pState, pControl->wait.blockNumber + 1))
+ {
+ pState->flags.wait = TRUE;
+ pResults->rc = CgxDriverTransferEndWait(pDriver, pControl->wait.timeoutMS);
+ }
+ }
+ else
+ {
+
+ pResults->rc = ECgCanceled;
+ if ( !isBlockCanceled(pState, pControl->wait.blockNumber))
+ {
+ printk("kyle last block\n");
+ if ( !wasBlockReceived(pState, pControl->wait.blockNumber + 1))
+ {
+ pState->flags.wait = TRUE;
+ pResults->rc = CgxDriverTransferEndWait(pDriver,pControl->wait.timeoutMS);
+ }
+ }
+ }
+ pState->flags.wait = FALSE;
+ if (!OK(pResults->rc) && (pResults->rc != ECgCanceled))
+ {
+ DBGMSG2("CGX_IOCTL_WAIT_RCV Failed! %d (t.o=%d ms)", pResults->rc, pControl->wait.timeoutMS);
+ }
+ DBGMSG2("App Buffer 0x%08X, phys:0x%08X", pState->transfer.originalBuffer, pState->transfer.bufferPhys);
+ DBGMSG2("received %d blocks %d chunks", pState->transfer.blocks.received, pState->transfer.chunks.received);
+
+ // Store the requested block's address, for use of the application
+ //////////////////////////////////////////////////////////////////////////
+
+ if( pState->transfer.blocks.received == 0 )
+ {
+ // This is an error - we returned from wait(), but no block was received.
+ pResults->buffer.bufferAppVirtAddr = pState->transfer.originalBuffer;
+ //poffset = 0;
+ if ( OK(pResults->rc) )
+ {
+ pResults->rc = ECgOutOfBounds;
+ DBGMSG1("ECgOutOfBounds [received=%d]", pState->transfer.blocks.received);
+
+ }
+ }
+ else
+ {
+ // Release possible event received, so we won't receive a false event - timeout is 0
+ CgxDriverTransferEndWait(pDriver, 0);
+
+ pResults->buffer.bufferAppVirtAddr = pState->transfer.originalBuffer + pState->transfer.bufferOffset[pControl->wait.blockNumber] ;
+ poffset = pState->transfer.bufferOffset[pControl->wait.blockNumber];
+ }
+
+ CgCpuCacheSync();
+ DBGMSG2("received %d blocks %d chunks", pState->transfer.blocks.received, pState->transfer.chunks.received);
+ DBGMSG3("0x%08X,0x%08X,%d", pState->transfer.bufferOffset[0], pState->transfer.bufferOffset[1],(pState->transfer.blocks.received-1) % 2);
+
+ switch( pResults->rc )
+ {
+ case ECgOk:
+ pResults->buffer.size = (pControl->wait.blockNumber == pState->transfer.blocks.required)
+ ? pState->transfer.lastBlockSize
+ : pState->transfer.blockSize;
+ break;
+ case ECgCanceled:
+ pResults->buffer.size = pState->transfer.cancel.onByte;
+ break;
+ default:
+ break;
+ }
+
+ // Reorder bytes
+ //////////////////////////////////////////////////////////////////////////
+
+ //Bug 2981 (Critical) - requires a frame 00/01/02 after downloading- during CS/WS if (OK(pResults->rc))
+ {
+ DBGMSG2("Byte order %d %d", CGX_DRIVER_NATIVE_BYTE_ORDER, pState->transfer.byteOrder);
+ if ((CGX_DRIVER_NATIVE_BYTE_ORDER != pState->transfer.byteOrder) &&
+ (pState->transfer.chunks.received > 0))
+ {
+ U32 length = gChunksList[pControl->wait.blockNumber].length;
+ if(pState->transfer.blocks.required <= 1)
+ length = pState->transfer.blockSize;
+
+ if ( isBlockCanceled(pState, pControl->wait.blockNumber + 1) )
+ {
+ //U32 requestedDmaCount = 0;
+ //CgCpuDmaRequestedCount(CG_DRIVER_DMA_CHANNEL_READ, &requestedDmaCount);
+ //length = (U32) pState->transfer.cancel.onByte % requestedDmaCount;
+ }
+ DBGMSG4("size %d s_vir 0x%x, 0x%x ,0x%x", length,(U32)pState->buffer.virtAddr,
+ gChunksList[pControl->wait.blockNumber].address,pState->transfer.bufferPhys);
+
+// pState->transfer.byteOrder = 0;
+
+ CgSwapBytesInBlock( (void*)((U32)pState->buffer.virtAddr +
+ (gChunksList[pControl->wait.blockNumber].address - pState->transfer.bufferPhys)),
+ (void*)((U32)pState->buffer.virtAddr +
+ (gChunksList[pControl->wait.blockNumber].address - pState->transfer.bufferPhys)),
+ length,
+ pState->transfer.byteOrder,
+ CGX_DRIVER_NATIVE_BYTE_ORDER );
+
+ }
+ CgCpuCacheSync();
+ }
+
+ DBGMSG2("WAIT_RCV : rc = %p, pResults->rc = %p", pResults->buffer.bufferAppVirtAddr, pResults->buffer.bufferPhysAddr);
+ DBGMSG2("WAIT_RCV : rc = %d, pResults->rc = %d", rc, pResults->rc);
+
+ break;
+
+
+ default:
+ rc = CgxDriverExecuteSpecific(pDriver, pState, aRequest, pControl, pResults);
+ }
+ if (OK(rc))
+ {
+ if ((pState->flags.resume == TRUE) || (pResults->rc == ECgResume)){
+ pResults->rc = ECgResume;
+ DBGMSG("Resume!");
+ }
+ DBGMSG1("End %d", aRequest);
+ pResults->state = *pState;
+ DBGMSG1("the lastest %d", aRequest);
+ switch(pResults->rc)
+ {
+ case ECgCanceled:
+ case ECgResume:
+ break;
+ default:DBGERR(pResults->rc);
+ }
+ }
+ return rc;
+}
+
+// this interrupt occur on end of DMA transaction (entire snap, block or sub-block)
+TCgReturnCode CgxDriverDataReadyInterruptHandler(void *pDriver, TCgxDriverState *pState)
+{
+ DBG_FUNC_NAME("CgxDriverDataReadyInterruptHandler")
+ TCgReturnCode rc = ECgOk;
+
+ pState->transfer.blocks.received++;
+
+ // update chunk counters
+ pState->transfer.chunks.received++;
+ pState->transfer.chunks.active++;
+
+ // update total received bytes count
+ pState->transfer.bytes.received += gChunksList[pState->transfer.chunks.active-1].length;
+
+ DBGMSG2("%d/%d", pState->transfer.chunks.active, pState->transfer.chunks.required);
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ //add by wlh for reset the rev address
+ if(gChunksList[pState->transfer.chunks.received].address == gChunksList[0].address )
+ {
+ Reset_GPS_RecvAddress();
+ }
+ //end by wlh for reset the rev address
+ #endif
+ if (pState->flags.wait) // release a waiting thread, if any
+ rc = CgxDriverTransferEndSignal(pDriver);
+
+ // check if end of snap (last block)
+ if (! isBlockCanceled(pState, pState->transfer.blocks.received + 1) )
+ {
+ // DBGMSG2("chunks.active = %d. chunks.received = %d", pState->transfer.chunks.active, pState->transfer.chunks.received);
+ if (pState->transfer.chunks.active >= pState->transfer.chunks.required)
+ {
+ // DBGMSG("last chunk");
+ pState->transfer.done = 0;
+ }
+ #ifdef CG_DRIVER_DMA_MULTI_BLOCK_MODE
+ #if CG_DRIVER_DMA_MULTI_BLOCK_MODE == CG_DRIVER_DMA_MULTI_BLOCK_MODE_PENDING
+ // not last block, so we need to order another chunk
+ else
+ {
+ // sub-block is used when DMA max size is small --> only need to increment the size
+ rc = CgCpuDmaSetupFromGpsNextTask( gChunksList, pState->transfer.chunks.required, pState->transfer.chunks.active,
+ CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070);
+ }
+ #endif
+ #endif
+ }
+
+
+ DBGMSG("Done");
+ return rc;
+}
+
+TCgReturnCode CgxDriverGpsInterruptHandler(void *pDriver, TCgxDriverState *pState)
+{
+ DBG_FUNC_NAME("CgxDriverGpsInterruptHandler")
+ TCgReturnCode rc = ECgOk;
+ U32 intcode = 0;
+ pState->counters.interrupt.all++;
+
+ // read interrupt source register from CGsnap
+ rc = CGCORE_READ_REG( CGCORE_REG_INT_SRC, &intcode);
+ rc = CGCORE_WRITE_REG( CGCORE_REG_INT_CLR, intcode);
+ printk("%s%s%s%s%s%s%s\n",
+ intcode & CGCORE_INT_RTC ? "RTC " : "",
+ intcode & CGCORE_INT_SNAP_START ? "BEG " : "",
+ intcode & CGCORE_INT_SNAP_END ? "END " : "",
+ intcode & CGCORE_INT_TCXO_EXPIRED ? "TCXO " : "",
+ intcode & CGCORE_INT_OVERRUN ? "OVR " : "",
+ intcode & CGCORE_INT_EOT ? "EOT " : "",
+ intcode & CGCORE_INT_EOM ? "EOM " : ""
+ );
+
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ if (intcode & CGCORE_INT_DMA_REQ)
+ {
+ data_req_handle(0,NULL);
+ }
+ #endif
+
+ if (intcode & CGCORE_INT_SNAP_START) { // Indicates snap was started
+ pState->counters.interrupt.snapStart++;
+ DBGMSG1("%d so far\n", pState->counters.interrupt.snapStart);
+ if (!isBlockCanceled(pState,1) && !pState->transfer.done && pState->transfer.bytes.required > 1)
+ {
+ // 1st DMA transfer task already set-up by PrepareReceive.
+ // some DMAC don't have LLI support, but other mechanism that requires setting next block
+ // each time
+ #ifdef CG_DRIVER_DMA_MULTI_BLOCK_MODE
+ #if CG_DRIVER_DMA_MULTI_BLOCK_MODE == CG_DRIVER_DMA_MULTI_BLOCK_MODE_PENDING
+ rc = CgCpuDmaSetupFromGpsNextTask(gChunksList, pState->transfer.chunks.required, pState->transfer.chunks.active, CG_DRIVER_DMA_CHANNEL_READ, CGCORE_BASE_ADDR + 0x00000070);
+ #endif
+ #endif
+ }
+ else
+ {
+ DBGMSG("problem!\n");
+ // if (pState->transfer.cancel.request)
+ // DBGMSG1("transfer.cancel.request=%d!", pState->transfer.cancel.request);
+ // if (pState->transfer.done)
+ // DBGMSG1("transfer.done=%d!", pState->transfer.done );
+ // if (pState->transfer.bytes.required == 0)
+ // DBGMSG1("transfer.bytes.required=%d!", pState->transfer.bytes.required);
+ }
+ }
+
+ if (intcode & CGCORE_INT_SNAP_END)
+ {
+ if (pState->transfer.cancel.request)
+ {
+ DBGMSG("Snap end due to : cancel\n");
+ rc = CgCpuDmaStop(CG_DRIVER_DMA_CHANNEL_READ);
+ rc = CgxDriverDataReadyInterruptHandler(pDriver, pState);
+ }
+ else
+ {
+ DBGMSG("Snap end due to : normal\n");
+ }
+ }
+
+ if (intcode & CGCORE_INT_OVERRUN) {
+ DBGMSG("Snap overrun\n");
+ pState->flags.overrun = TRUE;
+ pState->counters.interrupt.overrun++;
+ if (pState->flags.wait) // release a waiting thread, if any
+ CgxDriverTransferEndSignal(pDriver);
+ // mark interrupt as handled
+ intcode &= ~CGCORE_INT_OVERRUN;
+ }
+
+ DBGMSG("Done");
+
+ return rc;
+}
+
+
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.h b/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.h
new file mode 100644
index 00000000..c3084a2a
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverCoreCommon.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CellGuide CGX5900 driver core prototypes (non-OS depended)
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+#ifndef CGX_DRIVR_CORE_COMMON_H
+#define CGX_DRIVR_CORE_COMMON_H
+
+
+#include "CgReturnCodes.h"
+#include "CgxDriverApi.h"
+
+// Access to the APB
+#define CGCORE_REG_OFFSET_SAT_RAM (0x100)
+#define CGCORE_REG_OFFSET_SAT_RAM_LAST (0x1FC)
+#define CGCORE_REG_OFFSET_APB_COMMAND (0x090)
+#define CGCORE_REG_OFFSET_APB_DATA (0x094)
+
+// CG Core interrupt codes
+#define CGCORE_INT_RTC (0x00000001) // RTC timer has reached its threshold Interrupt
+#define CGCORE_INT_SNAP_START (0x00000002) // StartSnap occurred Interrupt
+#define CGCORE_INT_SNAP_END (0x00000004) // Snap completed successfully Interrupt
+#define CGCORE_INT_TCXO_EXPIRED (0x00000008) // TCXO timer has reached its threshold Interrupt
+#define CGCORE_INT_OVERRUN (0x00000010) // A buffer overrun occurred interrupt. Hence the last snap is invalid.
+#define CGCORE_INT_EOT (0x00000020) // End of BS tracking period Interrupt
+#define CGCORE_INT_EOM (0x00000040) // End of drift meas measurement period Interrupt
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+#define CGCORE_INT_DMA_REQ (0x00002000)
+#define CGCORE_INT_DMA_OVERRUN (0x00004000)
+#endif
+
+#define CGCORE_REG_INT_RAW (0x80)
+#define CGCORE_REG_INT_SRC (0x84)
+#define CGCORE_REG_INT_EN (0x88)
+#define CGCORE_REG_INT_CLR (0x8C)
+
+
+/**
+ Define the incoming data byte order
+*/
+extern const TCgByteOrder CGX_DRIVER_NATIVE_BYTE_ORDER;
+
+BOOL isBlockCanceled(TCgxDriverState * apState, U32 aBlockNumber);
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverLinux.c b/drivers/misc/gpsip/cgdriver/CgxDriverLinux.c
new file mode 100644
index 00000000..7d9cdc3c
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverLinux.c
@@ -0,0 +1,1373 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+
+/**
+ \cond OS_LINUX
+*/
+
+/**
+ \file
+ \brief Linux specific driver code
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+ Specific code required for the CellGuide GPS driver for Linux.
+*/
+// ===========================================================================
+
+#define __CGXLINUXDRIVER_C__
+#include <asm/io.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/cdev.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#endif
+
+#include "CgTypes.h"
+#include "CgReturnCodes.h"
+#include "CgCpu.h"
+#include "CgxDriverCore.h"
+#include "CgxDriverOs.h"
+#include "CgxDriverPlatform.h"
+
+#include "platform.h"
+#include "CgCpuOs.h"
+
+
+extern U32 CGCORE_REG_OFFSET_CORE_RESETS;
+extern U32 CGCORE_REG_OFFSET_VERSION;
+extern U32 poffset;
+
+
+struct class * gps_class;
+struct device * gps_dev;
+
+
+
+/*paulluo add test*/
+//#define FIX_MEMORY
+#ifdef CGCORE_ACCESS_VIA_SPI
+extern int gpsspidev_init(void);
+extern void gpsspidev_exit(void);
+#endif
+
+
+// ===========================================================================
+
+//
+// Driver instance structure.
+//
+typedef struct {
+ struct cdev cdev;
+ int nNumOpens;
+ int DataReady_irq;
+ int GpsIntr_irq;
+ struct completion xferCompleted; // was rcvSem
+ TCgxDriverPhysicalMemory chunk;
+ TCgxDriverState state;
+ void *xfer_buff_ptr; // Internal buffer pointer
+ unsigned long xfer_buff_len; // Internal buffer len (bytes)
+ int xfer_buff_pg_order; // Internal buffer page order (log2(n))
+ int xfer_buff_mmapped; // Internal buffer is mapped
+ struct fasync_struct *async_queue;
+ wait_queue_head_t resumeq;
+ char pm_resumed;
+} DRVCONTEXT;
+
+// Use a static DriverContext, as only one driver instance is needed
+static DRVCONTEXT DrvContext;
+//bxd add for first alloc mem failed from engine
+static void *init_buff_ptr;
+
+static void GpsIntr_BH(struct work_struct *work);
+DECLARE_WORK( girq_work, GpsIntr_BH );
+static struct workqueue_struct *girq_wq = NULL;
+#define GIRQ_WQ_NAME "GIRQ WorkQueue"
+
+static void DataReady_BH(struct work_struct *work);
+DECLARE_WORK( drdy_work, DataReady_BH );
+static struct workqueue_struct *drdy_wq = NULL;
+#define DRDY_WQ_NAME "DRDY WorkQueue"
+
+// In certain devices, there will not be an irq for DMA ready, but instead, a wait-able, exported sync-object.
+#ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
+
+ static void DataReady_Completion_WorkQueue(struct work_struct *work);
+ DECLARE_WORK( drdy_completion_work, DataReady_Completion_WorkQueue );
+ static struct workqueue_struct *drdy_completion_wq = NULL;
+ #define DRDY_COMPLETION_WQ_NAME "DRDY Completion WorkQueue"
+
+ extern struct completion CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT;
+
+ /*
+ DataReady Interrupt Handlers:
+ DataReady_BH: The Bottom-Half (Handler Thread)
+ DataReady_TH: The Top-Half (ISR)
+ CgxDriverDataReadyInterruptHandlerStart: Register the DataReady ISR
+ */
+ static void DataReady_Completion_WorkQueue(struct work_struct *work)
+ {
+ // DBG_FUNC_NAME("DataReady_BH")
+ // DBGMSG("START");
+ while (1)
+ {
+ wait_for_completion( &CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT );
+ CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
+ }
+
+ // DBGMSG("END");
+ }
+#endif
+
+static int cgxdrv_major = 0; /* 0 = dynamic major */
+#define MODULE_NAME "cgxdrv"
+
+
+/*
+ DataReady Interrupt Handlers:
+ DataReady_BH: The Bottom-Half (Handler Thread)
+ DataReady_TH: The Top-Half (ISR)
+ CgxDriverDataReadyInterruptHandlerStart: Register the DataReady ISR
+ */
+static void DataReady_BH(struct work_struct *work)
+{
+ // DBG_FUNC_NAME("DataReady_BH")
+ // DBGMSG("START");
+ CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
+ //enable_irq( DrvContext.DataReady_irq );
+ // DBGMSG("END");
+}
+
+static irqreturn_t DataReady_TH(int irq, void *dev_id)
+{
+ // DBG_FUNC_NAME("DataReady_TH")
+ // DBGMSG("START");
+ //disable_irq_nosync( irq );
+
+ queue_work(drdy_wq, &drdy_work);
+ // DBGMSG("END");
+
+ return IRQ_HANDLED;
+}
+
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+u32 GetRequestLen(void)
+{
+ TCgxDriverState *pState = &DrvContext.state;
+
+ return pState->transfer.bytes.required;
+}
+
+void DataReady_TH_start(void )
+{
+
+ CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
+
+}
+#endif
+void* Data_Get_DrvContext(void)
+{
+
+ return DrvContext.xfer_buff_ptr;
+}
+
+void CCgCpuDmaHandle(int irq,void* dev_id)
+{
+ CgxDriverDataReadyInterruptHandler(&DrvContext, &DrvContext.state);
+}
+
+
+TCgReturnCode CgxDriverDataReadyInterruptHandlerStart(void *pDriver)
+{
+ DBG_FUNC_NAME("CgxDriverDataReadyInterruptHandlerStart")
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+
+ int rv = 0;
+
+ // First check if there is an irq dedicated to the DataReady event
+ pDriverInfo->DataReady_irq = CgxDriverDataReadyInterruptCode();
+ if( pDriverInfo->DataReady_irq != 0)
+ {
+ drdy_wq = create_singlethread_workqueue(DRDY_WQ_NAME);
+
+ if (drdy_wq == NULL) {
+ DBGMSG("create_singlethread_workqueue(" DRDY_WQ_NAME ") Failed");
+ return ECgInitFailure;
+ }
+
+ rv = request_irq( pDriverInfo->DataReady_irq, DataReady_TH, IRQF_DISABLED, "drdy-bh", NULL );
+ if (rv != 0) {
+ DBGMSG1("request_irq(%d) Failed", pDriverInfo->DataReady_irq );
+ return ECgInitFailure;
+ }
+ DBGMSG1("request_irq(DRDY/%d) OK", pDriverInfo->DataReady_irq );
+ }
+ else
+ {
+ // There is no irq. Lets check if there is an exported sync-object
+ #ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
+ drdy_completion_wq = create_singlethread_workqueue(DRDY_COMPLETION_WQ_NAME);
+ if ( OK(drdy_completion_wq) )
+ queue_work(drdy_completion_wq, &drdy_completion_work);
+ else
+ return ECgInitFailure;
+ #else
+ DBGMSG1("request_irq(DRDY/%d) Skipped", pDriverInfo->DataReady_irq );
+ #endif
+ }
+
+ return ECgOk;
+}
+
+
+
+/*
+ GpsIntr Interrupt Handlers:
+ GpsIntr_BH: The Bottom-Half (Handler Thread)
+ GpsIntr_TH: The Top-Half (ISR)
+ CgxDriverGeneralInterruptHandlerStart: Register the GpsIntr ISR
+ */
+static void GpsIntr_BH(struct work_struct *work)
+{
+ // DBG_FUNC_NAME("GpsIntr_BH")
+ // DBGMSG("START");
+ CgxDriverGpsInterruptHandler(&DrvContext, &DrvContext.state);
+ // DBGMSG("END");
+ enable_irq( DrvContext.GpsIntr_irq );
+}
+
+static irqreturn_t GpsIntr_TH(int irq, void *dev_id)
+{
+ // DBG_FUNC_NAME("GpsIntr_TH")
+ // DBGMSG("START");
+ disable_irq_nosync( irq );
+
+ queue_work(girq_wq, &girq_work);
+
+ // DBGMSG("END");
+ return IRQ_HANDLED;
+}
+
+TCgReturnCode CgxDriverGpsInterruptHandlerStart(void *pDriver)
+{
+ DBG_FUNC_NAME("CgxDriverGpsInterruptHandlerStart")
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+
+ int rv = 0;
+ pDriverInfo->GpsIntr_irq = CgxDriverGpsInterruptCode();
+ if (pDriverInfo->GpsIntr_irq != 0)
+ {
+ girq_wq = create_singlethread_workqueue(GIRQ_WQ_NAME);
+ if (girq_wq == NULL) {
+ DBGMSG("create_singlethread_workqueue(" GIRQ_WQ_NAME ") Failed");
+ return ECgInitFailure;
+ }
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ rv = request_irq( pDriverInfo->GpsIntr_irq, GpsIntr_TH, IRQF_TRIGGER_RISING, "girq-bh", NULL );
+ #else
+ rv = request_irq( pDriverInfo->GpsIntr_irq, GpsIntr_TH, IRQF_DISABLED, "girq-bh", NULL );
+ #endif
+ if (rv != 0) {
+ DBGMSG1("request_irq(%d) Failed", pDriverInfo->GpsIntr_irq );
+ return ECgInitFailure;
+ }
+ DBGMSG1("request_irq(GPS/%d) OK", pDriverInfo->GpsIntr_irq );
+ }
+ else
+ DBGMSG1("request_irq(GPS/%d) Skipped", pDriverInfo->GpsIntr_irq );
+
+ return ECgOk;
+}
+
+
+
+
+
+TCgReturnCode CgxDriverTransferEndCreate(void *pDriver)
+{
+ DBG_FUNC_NAME("CgxDriverTransferEndCreate")
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+
+ DBGMSG( "Entering... Initializing completion semaphore" );
+
+ init_completion( &pDriverInfo->xferCompleted );
+
+ DBGMSG1( "Initialized Semaphore=%u", pDriverInfo->xferCompleted.done );
+
+ return ECgOk;
+}
+
+
+
+TCgReturnCode CgxDriverTransferEndSignal(void *pDriver)
+{
+ //DBG_FUNC_NAME("CgxDriverTransferEndSignal")
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+
+/* DBGMSG( "Entering" );*/
+
+ //DBGMSG1( "Marking completion... Semaphore=%u", pDriverInfo->xferCompleted.done );
+ complete( &pDriverInfo->xferCompleted );
+ //DBGMSG1( "Marked completion... After Semaphore=%u", pDriverInfo->xferCompleted.done );
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgxDriverTransferEndWait(void *pDriver, U32 aTimeoutMS)
+{
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+ TCgReturnCode rc = ECgOk;
+ unsigned long timeout = aTimeoutMS * HZ / 1000;
+ unsigned long rv = 0 ;
+ DBG_FUNC_NAME("CgxDriverTransferEndWait")
+
+ DBGMSG1( "Timeout=%lu", timeout );
+
+
+ for (;;) {
+ if (pDriverInfo->state.flags.resume == 1) {
+ DBGMSG("Resume!");
+ return ECgResume;
+ }
+ //DBGMSG1( "Waiting for completion... Semaphore=%u", pDriverInfo->xferCompleted.done );
+ /*bxd modify because of can't entry susnpend when use wait_for_completion_interruptible_timeout func */
+ //rv = wait_for_completion_interruptible_timeout( &pDriverInfo->xferCompleted, timeout );
+ rv = wait_for_completion_timeout( &pDriverInfo->xferCompleted, timeout );
+ if (rv != -ERESTARTSYS)
+ break;
+ }
+
+ if ((rv == 0) && (timeout > 0))
+ {
+ rc = ECgTimeout;
+ DBGMSG( "Timed-out" );
+ }
+ else
+ {
+ DBGMSG1( "wait_for_completion_interruptible_timeout returned=%d", rv );
+ }
+
+ if (pDriverInfo->state.flags.resume == 1) {
+ DBGMSG("Resume!");
+ rc = ECgResume;
+ }
+
+ return rc;
+}
+
+
+TCgReturnCode CgxDriverTransferEndDestroy(void *pDriver)
+{
+ return ECgOk;
+}
+
+
+//#define FIX_MEMORY
+
+#ifdef FIX_MEMORY
+unsigned char buf_data[6*1024*1024];
+#else
+ void* buf_data;
+#endif
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+void clear_buf_data(void)
+{
+ memset(DrvContext.xfer_buff_ptr,0,DrvContext.xfer_buff_len);
+}
+#endif
+
+TCgReturnCode CgxDriverAllocInternalBuff(void *pDriver, U32 aLength, void **apBuffer, U32 aProcessID)
+{
+ DBG_FUNC_NAME("CgxDriverAllocInternalBuff")
+ DRVCONTEXT *pDriverInfo = (DRVCONTEXT *)pDriver;
+ DBGMSG( "Entering..." );
+
+ /* Already alloc'ed, return error and ask to free 1st */
+ if (DrvContext.xfer_buff_ptr != NULL) {
+ DBGMSG( "Returning ECgNotSupported" );
+ return ECgNotSupported;
+ }
+
+
+ #ifndef FIX_MEMORY
+ DrvContext.xfer_buff_pg_order = get_order(aLength);
+ //bxd add for first alloc mem failed from engine
+ if(init_buff_ptr != NULL)
+ DrvContext.xfer_buff_ptr = init_buff_ptr;
+ else
+ DrvContext.xfer_buff_ptr = (void *)__get_free_pages(GFP_KERNEL, DrvContext.xfer_buff_pg_order);
+ DrvContext.xfer_buff_len = PAGE_SIZE * (1 << DrvContext.xfer_buff_pg_order);
+ buf_data = DrvContext.xfer_buff_ptr;
+ #else
+ DrvContext.xfer_buff_pg_order = get_order(aLength);
+ DrvContext.xfer_buff_ptr =(void*)&buf_data[0];
+ DrvContext.xfer_buff_len = 6*1024*1024;
+
+ #endif
+
+
+ if (DrvContext.xfer_buff_ptr == NULL) {
+ DBGMSG( "Returning ECgErrMemory" );
+ return ECgErrMemory;
+ }
+
+ pDriverInfo->state.buffer.length = DrvContext.xfer_buff_len;
+ pDriverInfo->state.buffer.virtAddr = DrvContext.xfer_buff_ptr;
+ pDriverInfo->state.buffer.physAddr = __pa((void *)DrvContext.xfer_buff_ptr) ;
+ DBGMSG2( "Returning ECgOk - Requested: %lu - Granted: %lu", aLength, DrvContext.xfer_buff_len );
+
+ *apBuffer = (void *)pDriverInfo->state.buffer.physAddr;
+#if defined(CGTEST) || defined(DEBUG)
+ memset(pDriverInfo->state.buffer.virtAddr, 0x43, aLength);
+#endif
+ 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 );
+ return ECgOk;
+}
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+int get_blocksize(void)
+{
+ return DrvContext.state.transfer.blockSize;
+}
+#endif
+
+
+void *CgxDriverGetInternalBuff(void *pSource, U32 length)
+{
+// if (length != DrvContext.xfer_buff_len)
+// return NULL;
+
+ return DrvContext.xfer_buff_ptr;
+}
+
+
+
+TCgReturnCode CgxDriverFreeInternalBuff(void *pDriver, U32 unUsed)
+{
+ /* Already alloc'ed, return error and ask to free 1st */
+ if (DrvContext.xfer_buff_ptr == NULL)
+ return ECgNotSupported;
+
+ /* Buffer is mmap'ed. return error and ask to free 1st */
+ if (DrvContext.xfer_buff_mmapped)
+ return ECgNotAllowed;
+
+#ifndef FIX_MEMORY
+//bxd
+ //free_pages((unsigned long)DrvContext.xfer_buff_ptr, DrvContext.xfer_buff_pg_order);
+#endif
+
+ DrvContext.xfer_buff_ptr = NULL;
+ DrvContext.xfer_buff_len = 0;
+ DrvContext.xfer_buff_pg_order = 0;
+
+ //bxd add for first alloc mem failed from engine
+ //if(init_buff_ptr != NULL)
+ // init_buff_ptr = NULL;
+
+ return ECgOk;
+}
+
+
+
+unsigned long CgxCopyFromUser(void *to, const void *fromuser, unsigned long n)
+{
+ return copy_from_user(to, fromuser, n);
+}
+
+
+
+static void getdata32_to_data64(TCgDriverControl_32bit *In32,TCgDriverControl *In64)
+{
+ In64->read.alignedLength = In32->read.alignedLength;
+ In64->read.blockLength = In32->read.blockLength;
+ In64->read.byteOrder = In32->read.byteOrder;
+ In64->read.buf = Data_Get_DrvContext();
+ In64->read.bufPhys = In32->read.bufPhys;
+ In64->read.timeoutMS = In32->read.timeoutMS;
+ In64->wait.timeoutMS = In32->wait.timeoutMS;
+ In64->wait.blockNumber = In32->wait.blockNumber;
+// In64->write.pSource = &In32->write.pSource;
+ In64->write.length = In32->write.length;
+ In64->GPIO.code = In32->GPIO.code;
+ In64->GPIO.out = In32->GPIO.out;
+ In64->GPIO.mode = In32->GPIO.mode;
+ In64->readReg.offset = In32->readReg.offset;
+ In64->writeReg.offset = In32->writeReg.offset;
+ In64->writeReg.value = In32->writeReg.value;
+ In64->cancel.onByteCount = In32->cancel.onByteCount;
+ In64->reset.resetLevel = In32->reset.resetLevel;
+ In64->alloc.length = In32->alloc.length;
+ In64->alloc.processId = In32->alloc.processId;
+ In64->tcxoControl.enable = In32->tcxoControl.enable;
+
+
+#if 0
+ printk("read.alignedLength: 0x%x\n", In32->read.alignedLength);
+ printk("read.blockLength: 0x%x\n", In32->read.blockLength);
+ printk("read.byteOrder: 0x%x\n", In32->read.byteOrder);
+ printk("read.buf: 0x%x\n", In32->read.buf);
+ printk("read.bufPhys: 0x%x\n", In32->read.bufPhys);
+ printk("read.timeoutMS: 0x%x\n", In32->read.timeoutMS);
+
+ printk("wait.timeoutMS: 0x%x\n", In32->wait.timeoutMS);
+ printk("wait.blockNumber: 0x%x\n", In32->wait.blockNumber);
+ printk("write.pSource: 0x%x\n", In32->write.pSource);
+ printk("write.length: 0x%x\n", In32->write.length);
+ printk("GPIO.code: 0x%x\n", In32->GPIO.code);
+
+ printk("GPIO.out: 0x%x\n", In32->GPIO.out);
+ printk("GPIO.mode: 0x%x\n", In32->GPIO.mode);
+ printk("readReg.offset: 0x%x\n", In32->readReg.offset);
+ printk("writeReg.offset: 0x%x\n", In32->writeReg.offset);
+ printk("writeReg.value: 0x%x\n", In32->writeReg.value);
+ printk("cancel.onByteCount: 0x%x\n", In32->cancel.onByteCount);
+ printk("reset.resetLevel: 0x%x\n", In32->reset.resetLevel);
+ printk("alloc.length: 0x%x\n", In32->alloc.length);
+ printk("alloc.processId: 0x%x\n", In32->alloc.processId);
+ printk("tcxoControl.enable: 0x%x\n", In32->tcxoControl.enable);
+
+
+ printk("read.alignedLength In64: 0x%x\n", In64->read.alignedLength);
+ printk("read.blockLength In64: 0x%x\n", In64->read.blockLength);
+ printk("read.byteOrder In64: 0x%x\n", In64->read.byteOrder);
+ printk("read.buf In64: 0x%x\n", In64->read.buf);
+ printk("read.bufPhys In64: 0x%x\n", In64->read.bufPhys);
+ printk("read.timeoutMS In64: 0x%x\n", In64->read.timeoutMS);
+
+ printk("wait.timeoutMS In64: 0x%x\n", In64->wait.timeoutMS);
+ printk("wait.blockNumber In64: 0x%x\n", In64->wait.blockNumber);
+ printk("write.pSource In64: 0x%x\n", In64->write.pSource);
+ printk("write.length In64: 0x%x\n", In64->write.length);
+ printk("GPIO.code In64: 0x%x\n", In64->GPIO.code);
+
+ printk("GPIO.out In64: 0x%x\n", In64->GPIO.out);
+ printk("GPIO.mode In64: 0x%x\n", In64->GPIO.mode);
+ printk("readReg.offset In64: 0x%x\n", In64->readReg.offset);
+ printk("writeReg.offset In64: 0x%x\n", In64->writeReg.offset);
+ printk("writeReg.value In64: 0x%x\n", In64->writeReg.value);
+ printk("cancel.onByteCount In64: 0x%x\n", In64->cancel.onByteCount);
+ printk("reset.resetLevel In64: 0x%x\n", In64->reset.resetLevel);
+ printk("alloc.length In64: 0x%x\n", In64->alloc.length);
+ printk("alloc.processId In64: 0x%x\n", In64->alloc.processId);
+ printk("tcxoControl.enable In64: 0x%x\n", In64->tcxoControl.enable);
+#endif
+}
+
+
+
+static void putdata64_to_data32(TCgDriverStatus_32bit *Out32,TCgDriverStatus *Out64)
+{
+ Out32->rc = Out64->rc;
+ Out32->buffer.bufferPhysAddr = (unsigned int)Out64->buffer.bufferPhysAddr;
+ Out32->buffer.bufferAppVirtAddr = poffset;
+ Out32->buffer.size = Out64->buffer.size;
+ Out32->GPIO.code = Out64->GPIO.code;
+ Out32->GPIO.val = Out64->GPIO.val;
+ //Out32->version.buildVersion = &Out64->version.buildVersion[0];
+ //Out32->version.buildNumber = &Out64->version.buildNumber[0];
+ //Out32->version.buildDate = &Out64->version.buildDate[0];
+ //Out32->version.buildTime = &Out64->version.buildTime[0];
+ //Out32->version.buildMode = &Out64->version.buildMode[0];
+ //Out32->version.buildName = &Out64->version.buildName[0];
+ Out32->readReg.offset = Out64->readReg.offset;
+ Out32->readReg.value = Out64->readReg.value;
+ //Out32->cpuRevision.revisionCode = &Out64->cpuRevision.revisionCode[0];
+ Out32->readRtc.year = Out64->readRtc.year;
+ Out32->readRtc.month = Out64->readRtc.month;
+ Out32->readRtc.day = Out64->readRtc.day;
+ Out32->readRtc.hour = Out64->readRtc.hour;
+ Out32->readRtc.minute = Out64->readRtc.minute;
+ Out32->readRtc.second = Out64->readRtc.second;
+ Out32->readRtc.dayInWeek = Out64->readRtc.dayInWeek;
+ Out32->readRtc.tick = Out64->readRtc.tick;
+ Out32->state.flags.terminate = Out64->state.flags.terminate;
+ Out32->state.flags.wait = Out64->state.flags.wait;
+ Out32->state.flags.overrun = Out64->state.flags.overrun;
+ Out32->state.flags.resume = Out64->state.flags.resume;
+ Out32->state.counters.interrupt.all = Out64->state.counters.interrupt.all;
+ Out32->state.counters.interrupt.snapStart = Out64->state.counters.interrupt.snapStart;
+ Out32->state.counters.interrupt.overrun = Out64->state.counters.interrupt.overrun;
+ Out32->state.transfer.bufferPhys = Out64->state.transfer.bufferPhys;
+ Out32->state.transfer.originalBuffer = (unsigned int)( Out64->state.transfer.originalBuffer);
+ Out32->state.transfer.byteOrder = Out64->state.transfer.byteOrder;
+ Out32->state.transfer.done = Out64->state.transfer.done;
+ Out32->state.transfer.bytes.required = Out64->state.transfer.bytes.required;
+ Out32->state.transfer.bytes.received = Out64->state.transfer.bytes.received;
+ Out32->state.transfer.blocks.required = Out64->state.transfer.blocks.required;
+ Out32->state.transfer.blocks.received = Out64->state.transfer.blocks.received;
+ Out32->state.transfer.chunks.required = Out64->state.transfer.blocks.received;
+ Out32->state.transfer.chunks.received = Out64->state.transfer.chunks.received;
+ Out32->state.transfer.chunks.active = Out64->state.transfer.chunks.active;
+ Out32->state.transfer.cancel.request = Out64->state.transfer.cancel.request;
+ Out32->state.transfer.cancel.onByte = Out64->state.transfer.cancel.onByte;
+ Out32->state.transfer.cancel.onChunk = Out64->state.transfer.cancel.onChunk;
+ //Out32->state.transfer.bufferOffset = Out64->state.transfer.bufferOffset;
+ Out32->state.transfer.blockSize = Out64->state.transfer.blockSize;
+ Out32->state.transfer.lastBlockSize = Out64->state.transfer.lastBlockSize;
+ Out32->state.buffer.physAddr = Out64->state.buffer.physAddr;
+ Out32->state.buffer.virtAddr = (unsigned int)(Out64->state.buffer.virtAddr);
+ Out32->state.buffer.length = Out64->state.buffer.length;
+ Out32->state.buffer.driverContextVirtBufferAddr = (unsigned int)(Out64->state.buffer.driverContextVirtBufferAddr);
+ Out32->state.constructionRc = Out64->state.constructionRc;
+#if 0
+ printk("Out64.readReg.offset: 0x%x\n", Out64->readReg.offset);
+ printk("Out64.readReg.value: 0x%x\n", Out64->readReg.value);
+ printk("Out32.readReg.offset: 0x%x\n", Out32->readReg.offset);
+ printk("Out32.readReg.value: 0x%x\n", Out32->readReg.value);
+ #endif
+}
+#if 0
+static void printdata32(TCgDriverStatus_32bit *Out32)
+{
+
+ printk(" Out32->rc: 0x%x\n", Out32->rc);
+ printk(" Out32->buffer.bufferPhysAddr: 0x%x\n", Out32->buffer.bufferPhysAddr);
+ printk(" Out32->buffer.bufferAppVirtAddr: 0x%x\n", Out32->buffer.bufferAppVirtAddr);
+ printk(" Out32->buffer.size : 0x%x\n", Out32->buffer.size );
+ printk(" Out32->GPIO.code : 0x%x\n", Out32->GPIO.code );
+ printk(" Out32->GPIO.val: 0x%x\n", Out32->GPIO.val);
+
+ printk(" Out32->version.buildVersion: 0x%x\n", Out32->version.buildVersion);
+ printk(" Out32->version.buildNumber: 0x%x\n", Out32->version.buildNumber);
+ printk(" Out32->version.buildDate : 0x%x\n", Out32->version.buildDate );
+ printk(" Out32->version.buildTime: 0x%x\n", Out32->version.buildTime);
+ printk(" Out32->version.buildMode : 0x%x\n", Out32->version.buildMode );
+ printk(" Out32->version.buildName: 0x%x\n", Out32->version.buildName);
+
+ printk(" Out32->readReg.offset: 0x%x\n", Out32->readReg.offset);
+ printk(" Out32->readReg.value: 0x%x\n", Out32->readReg.value);
+ printk(" Out32->readRtc.year : 0x%x\n", Out32->readRtc.year );
+ printk(" Out32->readRtc.month: 0x%x\n", Out32->readRtc.month);
+ printk(" Out32->readRtc.day: 0x%x\n", Out32->readRtc.day);
+ printk(" Out32->readRtc.hour: 0x%x\n", Out32->readRtc.hour);
+ printk(" Out32->readRtc.minute: 0x%x\n", Out32->readRtc.minute);
+ printk(" Out32->readRtc.second: 0x%x\n", Out32->readRtc.second);
+ printk(" Out32->readRtc.dayInWeek: 0x%x\n", Out32->readRtc.dayInWeek);
+ printk(" Out32->readRtc.tick: 0x%x\n", Out32->readRtc.tick);
+
+
+
+
+ printk(" Out32->state.flags.terminate: 0x%x\n", Out32->state.flags.terminate);
+ printk(" Out32->state.flags.wait: 0x%x\n", Out32->state.flags.wait);
+ printk(" Out32->state.flags.overrun: 0x%x\n", Out32->state.flags.overrun);
+ printk(" Out32->state.flags.resume: 0x%x\n", Out32->state.flags.resume);
+ printk(" Out32->state.counters.interrupt.all: 0x%x\n", Out32->state.counters.interrupt.all);
+ printk(" Out32->state.counters.interrupt.snapStart: 0x%x\n", Out32->state.counters.interrupt.snapStart);
+ printk(" Out32->state.counters.interrupt.overrun: 0x%x\n", Out32->state.counters.interrupt.overrun);
+ printk(" Out32->state.transfer.bufferPhys: 0x%x\n", Out32->state.transfer.bufferPhys);
+ printk(" Out32->state.transfer.originalBuffer: 0x%x\n", Out32->state.transfer.originalBuffer);
+ printk(" Out32->state.transfer.byteOrder: 0x%x\n", Out32->state.transfer.byteOrder);
+ printk(" Out32->state.transfer.done: 0x%x\n", Out32->state.transfer.done);
+ printk(" Out32->state.transfer.bytes.required: 0x%x\n", Out32->state.transfer.bytes.required);
+ printk(" Out32->state.transfer.bytes.received: 0x%x\n", Out32->state.transfer.bytes.received);
+ printk(" Out32->state.transfer.blocks.required: 0x%x\n", Out32->state.transfer.blocks.required);
+ printk(" Out32->state.transfer.blocks.received: 0x%x\n", Out32->state.transfer.blocks.received);
+ printk(" Out32->state.transfer.chunks.required: 0x%x\n", Out32->state.transfer.chunks.required);
+ printk(" Out32->state.transfer.chunks.received: 0x%x\n", Out32->state.transfer.chunks.received);
+ printk(" Out32->state.transfer.chunks.active: 0x%x\n", Out32->state.transfer.chunks.active);
+ printk(" Out32->state.transfer.cancel.request: 0x%x\n", Out32->state.transfer.cancel.request);
+ printk(" Out32->state.transfer.cancel.onByte: 0x%x\n", Out32->state.transfer.cancel.onByte);
+ printk(" Out32->state.transfer.cancel.onChunk : 0x%x\n", Out32->state.transfer.cancel.onChunk );
+ printk(" Out32->state.transfer.bufferOffset: 0x%x\n", Out32->state.transfer.bufferOffset);
+ printk(" Out32->state.transfer.blockSize: 0x%x\n", Out32->state.transfer.blockSize);
+ printk(" Out32->state.transfer.lastBlockSize: 0x%x\n", Out32->state.transfer.lastBlockSize);
+ printk(" Out32->state.buffer.physAddr: 0x%x\n", Out32->state.buffer.physAddr);
+ printk(" Out32->state.buffer.virtAddr: 0x%x\n", Out32->state.buffer.virtAddr);
+
+ printk(" Out32->state.buffer.length: 0x%x\n", Out32->state.buffer.length);
+ printk(" Out32->state.buffer.driverContextVirtBufferAddr: 0x%x\n", Out32->state.buffer.driverContextVirtBufferAddr);
+ printk(" Out32->state.constructionRc: 0x%x\n", Out32->state.constructionRc);
+ printk(" Out32->rc: 0x%x\n", Out32->rc);
+ printk(" Out32->rc: 0x%x\n", Out32->rc);
+
+
+
+
+
+
+
+
+
+
+ //Out32->cpuRevision.revisionCode = &Out64->cpuRevision.revisionCode[0];
+
+}
+#endif
+//======================================================================
+// CGX_IOControl - Called when DeviceIOControl called
+//
+//static int CGX_IOControl(struct inode *inode,struct file *filp,
+static long CGX_IOControl(struct file *filp,
+
+ unsigned int cmd, unsigned long arg)
+{
+ DBG_FUNC_NAME("CGX_IOControl")
+ TCgReturnCode rc = ECgOk;
+ TCgDriverControl In;
+ TCgDriverStatus Out;
+
+ TCgDriverControl_32bit In_32;
+ TCgDriverStatus_32bit Out_32;
+
+//printk("cmd:0x%x,arg:0x%x\n",cmd,arg);
+ /* DBGMSG1( "Entering...[%d]" , cmd); */
+
+
+ // Check we can read the TCgDriverControl from User Space
+ if ( !access_ok( VERIFY_READ, (void __user *)arg, sizeof(TCgDriverControl_32bit) ) ) {
+ DBGMSG( "Returning -EFAULT 1" );
+ return -EFAULT;
+ }
+
+ // Check we can write the TCgDriverStatus to User Space
+ if ( !access_ok( VERIFY_WRITE, (void __user *)arg, sizeof(TCgDriverStatus_32bit) ) ) {
+ DBGMSG( "Returning -EFAULT 2" );
+ return -EFAULT;
+ }
+
+ if ( copy_from_user( &In_32, (void __user *)arg, sizeof(In_32) ) ) {
+ DBGMSG( "Returning -EFAULT 3" );
+ return -EFAULT;
+ }
+
+ getdata32_to_data64(&In_32,&In);
+
+ rc = CgxDriverExecute( &DrvContext, &DrvContext.state, cmd, &In, &Out);
+
+ putdata64_to_data32(&Out_32,&Out);
+
+ if ( copy_to_user( (void __user *)arg, &Out_32, sizeof(Out_32) ) ) {
+ DBGMSG( "Returning -EFAULT 4" );
+ return -EFAULT;
+ }
+
+ DBGMSG1( "Returning %d", (OK(rc)) ? 0 : -ENOTTY );
+ return (OK(rc)) ? 0 : -ENOTTY;
+
+}
+
+
+int CGX_CompleteDrv(void)
+{
+ complete(&DrvContext.xferCompleted);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(CGX_CompleteDrv);
+
+//======================================================================
+// CGX_Fasync - Called when driver closed
+//
+static int CGX_Fasync( int fd, struct file *filp, int mode)
+{
+ return fasync_helper(fd, filp, mode, &DrvContext.async_queue);
+}
+
+unsigned int CgxDriverCheckAllocInternalBuff(void)
+{
+
+ if (DrvContext.xfer_buff_ptr != NULL) {
+ printk( "\n already alloc page \n" );
+ return 0;
+ }
+ return 1;
+}
+
+
+
+//======================================================================
+// CGX_Close - Called when driver closed
+//
+static int CGX_Close( struct inode *inode, struct file *filp)
+{
+/* DBGMSG( "Entering..." ); */
+
+#if 0
+ //gaole add begin
+ int rc = 0;
+
+ CgCoreReleaseRes();
+ if (CgxDriverCheckAllocInternalBuff() == 0)
+ {
+ printk("\n gaole: close check if old page be released \n");
+
+ rc = CgxDriverFreeInternalBuff(NULL, 0);
+
+ if(ECgOk != rc)
+ {
+ printk("\n gaole: close run CgxDriverFreeInternalBuff error,error code is %d \n",rc);
+ }
+
+ }
+
+ rc = CgCpuDmaStop(0);
+ if(ECgOk != rc)
+ {
+ printk("\n gaole: run CgCpuDmaStop error,error code is %d \n",rc);
+
+ }
+ CgGpsReset();
+#endif
+
+ CgCpuDmaDestroy(0,0);
+ // gaole add end
+
+
+ if (DrvContext.nNumOpens)
+ DrvContext.nNumOpens--;
+
+ if ( filp->f_flags & FASYNC) {
+ CGX_Fasync(-1, filp, 0); /* Remove from async queue */
+ }
+
+/* DBGMSG( "Returning 0" ); */
+ return 0;
+}
+
+
+//======================================================================
+// CGX_Read - Called when driver read
+//
+static ssize_t CGX_Read( struct file *filp, char __user *buff, size_t count, loff_t *offp)
+{
+ while (DrvContext.pm_resumed == 0) {
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ //DBGMSG( "Waiting for resume to take place... Going to sleep\n" );
+ if (wait_event_interruptible(DrvContext.resumeq, (DrvContext.pm_resumed != 0)))
+ return -ERESTARTSYS;
+ }
+
+ /*
+ * Copy 1 char sizeof(*(char*)) from DrvContext.pm_resumed to buff
+ */
+ if (put_user(DrvContext.pm_resumed, (char __user *)buff)) {
+ return -EFAULT;
+ }
+
+ DrvContext.pm_resumed = 0;
+ return 1;
+}
+
+
+//======================================================================
+// CGX_Write - Called when driver written
+//
+static ssize_t CGX_Write( struct file *filp, const char __user *buff, size_t count, loff_t *offp)
+{
+ return 0;
+}
+
+
+//======================================================================
+// CGX_Poll - Called when driver select()/poll()
+//
+static unsigned int CGX_Poll(struct file *filp, poll_table *wait)
+{
+ poll_wait(filp, &DrvContext.resumeq, wait);
+
+ if (DrvContext.pm_resumed == 'R')
+ return (POLLIN | POLLRDNORM);
+
+ return 0;
+}
+
+//======================================================================
+// CGX_Seek - Called when SetFilePtr called
+//
+static loff_t CGX_Seek (struct file *filp, loff_t off, int whence)
+{
+ return 0;
+}
+
+
+
+
+
+
+//======================================================================
+// CGX_Open - Called when driver opened
+//
+static int CGX_Open( struct inode *inode, struct file *filp )
+{
+
+ /*
+ * XXX-PK-XXX: Hold lock on DrvContext
+ */
+ CgCpuDmaCreate(0,0);
+
+/* DBGMSG( "Entering..." ); */
+
+ // Count the number of opens.
+ DrvContext.nNumOpens++;
+
+/* DBGMSG( "Returning 0" ); */
+ return 0;
+}
+
+
+/*
+ * CGX_vma_open and CGX_vma_close keep track of how many times
+ * the buffer is mapped, to avoid Freeing it while in use.
+ */
+static void CGX_vma_open(struct vm_area_struct *vma)
+{
+ DBG_FUNC_NAME("CGX_vma_open")
+ DrvContext.xfer_buff_mmapped++;
+ DBGMSG4("vma open [%d]: virt 0x%lx, Offs %lu, Len %lu",
+ DrvContext.xfer_buff_mmapped,
+ vma->vm_start, vma->vm_pgoff << PAGE_SHIFT, vma->vm_end - vma->vm_start );
+}
+
+static void CGX_vma_close(struct vm_area_struct *vma)
+{
+ DBG_FUNC_NAME("CGX_vma_close")
+/* DBGMSG( "Entering..." ); */
+
+ DrvContext.xfer_buff_mmapped--;
+ DBGMSG1("vma close [%d]", DrvContext.xfer_buff_mmapped );
+
+/* DBGMSG( "Exit" ); */
+}
+
+#if LINUX_VERSION_CODE >= 132634
+static int CGX_vma_nopage(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return VM_FAULT_SIGBUS; // Remapping is not allowed !
+}
+#else
+static struct page *CGX_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
+{
+ return NOPAGE_SIGBUS; // Remapping is not allowed !
+}
+#endif
+
+static struct vm_operations_struct cgx_remap_ops = {
+ .open = CGX_vma_open,
+ .close = CGX_vma_close,
+ #if LINUX_VERSION_CODE >= 132634
+ .fault = CGX_vma_nopage,
+ #else
+ .nopage = CGX_vma_nopage,
+ #endif
+};
+
+static int CGX_Mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ DBG_FUNC_NAME("CGX_Mmap")
+ int rv;
+ unsigned long len = (vma->vm_end - vma->vm_start);
+ unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long physical = __pa((void *)DrvContext.xfer_buff_ptr) + off;
+
+ DBGMSG3( "Entering... len=%lu off=%lu DrvContext.xfer_buff_len=%lu", len, off, DrvContext.xfer_buff_len );
+
+ if ( len > (DrvContext.xfer_buff_len - off) ) {
+ DBGMSG( "Returning -EINVAL" );
+ return -EINVAL;
+ }
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+ rv = remap_pfn_range(vma, vma->vm_start,
+ physical >> PAGE_SHIFT, len,
+ (vma->vm_page_prot));
+#else
+
+ rv = remap_pfn_range(vma, vma->vm_start,
+ physical >> PAGE_SHIFT, len,
+ pgprot_noncached(vma->vm_page_prot));
+
+#endif
+
+
+
+ if (rv < 0) {
+ DBGMSG1( "Returning %d", rv );
+ return rv;
+ }
+
+ vma->vm_ops = &cgx_remap_ops;
+ CGX_vma_open(vma);
+/* DBGMSG( "Returning 0" ); */
+ return 0;
+}
+
+
+#if 0
+#warning CGX_AddSysDev is needed only for debugging !
+static int CGX_AddSysDev(struct sys_device *dev)
+{
+ DBGMSG( "Got to CGX_AddSysDev\n" );
+ return 0;
+}
+#endif
+
+
+static int CGX_PMSuspend(struct device *dev, pm_message_t state)
+{
+ #if 0
+ //DBGMSG( "Got to CGX_PMSuspend\n" );
+ printk("%s\n",__func__);
+ //if (DrvContext.nNumOpens > 0)
+ if(flag_power_up == 1)
+ {
+ CgxDriverPowerDown();
+ CgxDriverRFPowerDown();
+ }
+ #endif
+ return 0;
+}
+
+
+static int CGX_PMResume(struct device *dev)
+{
+ #if 0
+ //DBGMSG( "Got to CGX_PMResume\n" );
+ printk("%s\n",__func__);
+ //if (DrvContext.nNumOpens > 0)
+ if(flag_power_up == 1)
+ {
+
+ DrvContext.state.flags.resume = 1;
+ #if 0
+ DrvContext.pm_resumed = 'R';
+
+ /* awake read()ers and poll()ers (select) */
+ wake_up_interruptible(&DrvContext.resumeq);
+
+ /* signal async readers */
+ if (DrvContext.async_queue)
+ kill_fasync(&DrvContext.async_queue, SIGIO, POLL_IN);
+ #endif
+ CgxDriverPowerUp();
+ CgxDriverRFPowerUp();
+ }
+#endif
+ return 0;
+}
+
+
+
+//======================================================================
+// CGX_Init - Driver initialization function
+//
+struct file_operations cgx_fops = {
+ .owner = THIS_MODULE,
+ .llseek = CGX_Seek,
+ .read = CGX_Read,
+ .write = CGX_Write,
+ .poll = CGX_Poll,
+ //bxd
+ //.ioctl = CGX_IOControl,
+ .unlocked_ioctl = CGX_IOControl,
+ #ifdef CONFIG_COMPAT
+ .compat_ioctl = CGX_IOControl,
+ #endif
+ .open = CGX_Open,
+ .fasync = CGX_Fasync,
+ .release = CGX_Close,
+ .mmap = CGX_Mmap,
+};
+
+#ifdef CONFIG_OF
+#ifndef CGCORE_ACCESS_VIA_SPI
+struct gps_2351_addr gps_2351;
+u32 gps_get_core_base(void)
+{
+ return gps_2351.gps_base;
+}
+
+u32 gps_get_ahb_base(void)
+{
+ return gps_2351.ahb_base;
+}
+
+u32 gps_get_irq(void)
+{
+ return gps_2351.irq_num;
+}
+
+u32 gps_get_lna_gpio(void)
+{
+ return gps_2351.lna_gpio;
+}
+
+#ifdef CONFIG_ARCH_SCX30G
+u32 gps_get_pmu_base(void)
+{
+ return gps_2351.pmu_base;
+}
+#endif
+
+static int cgxdrv_gps_source_init(void)
+{
+ int ret;
+
+ struct device_node *np;
+ struct resource res;
+
+ np = of_find_node_by_name(NULL, "gps_2351");
+ if (!np) {
+ printk("Can't get the gps_2351 node!\n");
+ return -ENODEV;
+ }
+ printk(" find the gps_2351 node!\n");
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret < 0) {
+ printk("Can't get the gps reg base!\n");
+ return -EIO;
+ }
+ gps_2351.gps_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
+ printk("gps reg base is 0x%x\n", gps_2351.gps_base);
+
+ ret = of_address_to_resource(np, 1, &res);
+ if (ret < 0) {
+ printk("Can't get the ahbreg base!\n");
+ return -EIO;
+ }
+ gps_2351.ahb_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
+ printk("ahb reg base is 0x%x\n", gps_2351.ahb_base);
+
+ #ifdef CONFIG_ARCH_SCX30G
+ ret = of_address_to_resource(np, 2, &res);
+ if (ret < 0) {
+ printk("Can't get the pmu base!\n");
+ return -EIO;
+ }
+ gps_2351.pmu_base = (unsigned long)ioremap_nocache(res.start, resource_size(&res));
+ printk("pmu_base base is 0x%x\n", gps_2351.pmu_base);
+ #endif
+
+ gps_2351.irq_num = irq_of_parse_and_map(np, 0);
+ if (gps_2351.irq_num == 0) {
+ printk("Can't get the gps irq_num!\n");
+ return -EIO;
+ }
+ printk(" gps_2351.gps_irq_num is %d\n", gps_2351.irq_num);
+
+ gps_2351.lna_gpio = of_get_gpio(np, 0);
+ if(gps_2351.lna_gpio < 0){
+ printk("fail to get gps lna gpio\n");
+ }
+ return ret;
+}
+#endif
+#endif
+static int __init CGX_Init(void)
+{
+ DBG_FUNC_NAME("CGX_Init")
+ int rv;
+ dev_t devno = MKDEV(cgxdrv_major, 0);
+
+/* DBGMSG( "Entering..." ); */
+
+ DBGMSG("Initializing");
+
+ #ifdef CONFIG_OF
+ #ifndef CGCORE_ACCESS_VIA_SPI
+ cgxdrv_gps_source_init();
+ #endif
+ #endif
+
+ //bxd add for first alloc mem failed from engine
+ init_buff_ptr = (void *)__get_free_pages(GFP_KERNEL, 8);
+ if(init_buff_ptr == NULL)
+ printk("init_buff_ptr alloc failed\n");
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+ sprd_get_rf2351_ops(&gps_rf_ops);
+#endif
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+ gpsspidev_init();
+#endif
+
+ /* Init structure */
+ memset (&(DrvContext), 0, sizeof (DRVCONTEXT));
+ init_waitqueue_head(&DrvContext.resumeq);
+
+ /* Register char dev (Major can be provided at load time) */
+ if (cgxdrv_major) {
+ rv = register_chrdev_region(devno, 1, "cgxdrv");
+ printk(KERN_ERR "[CGX|%s] register_chrdev_region \r\n", __FUNCTION__);
+ } else {
+ rv = alloc_chrdev_region(&devno, 0, 1, "cgxdrv");
+ cgxdrv_major = MAJOR(devno);
+ printk(KERN_ERR "[CGX|%s] alloc_chrdev_region, cgxdrv_major=%d \r\n", __FUNCTION__, cgxdrv_major);
+ }
+
+ if (rv < 0) {
+ printk(KERN_ERR MODULE_NAME " Error can't get major %d\r\n", cgxdrv_major);
+ goto out;
+ }
+
+ if ( CgxDriverConstruct(&DrvContext, &DrvContext.state) != ECgOk ) {
+ DBGMSG("CgxDriverConstruct Failed");
+ rv = -ENOMEM;
+ goto out1;
+ }
+
+ // Device is ready... Activate it
+ cdev_init(&DrvContext.cdev, &cgx_fops);
+ DrvContext.cdev.owner = THIS_MODULE;
+ DrvContext.cdev.ops = &cgx_fops;
+ rv = cdev_add (&DrvContext.cdev, devno, 1);
+ if (rv) {
+ // Cleanup
+ DBGMSG1(" Error %d adding cgxdrv device\r\n", rv);
+ goto out2;
+ }
+
+ /* Create the device class. */
+ gps_class = class_create(THIS_MODULE, "cgxdrv_class");
+ if (IS_ERR(gps_class))
+ {
+ DBGMSG(" Error: create cgxdrv class failed\r\n");
+ }
+
+ //bxd
+ gps_class->suspend = CGX_PMSuspend;
+ gps_class->resume = CGX_PMResume;
+
+ /* register in /dev */
+ gps_dev = device_create(gps_class, NULL, devno, NULL, "cgxdrv");
+ if (IS_ERR(gps_dev))
+ {
+ DBGMSG(" Error: device_create failed\r\n");
+ class_destroy(gps_class);
+ }
+
+ DBGMSG1(" Driver Ready... Major DevId: %d", cgxdrv_major );
+ DBGMSG1(" Driver Byte order %d", CGX_DRIVER_NATIVE_BYTE_ORDER);
+
+ goto out;
+
+out2:
+ /*
+ * XXX-PK-XXX: FIXME: Add CgxDriverConstruct Cleanup
+ * For example: free IRQs, destroy workqueues, etc.
+ */
+out1:
+ unregister_chrdev_region( devno, 1 );
+out:
+ return rv;
+}
+
+
+//======================================================================
+// CGX_Deinit - Driver de-initialization function
+//
+static void __exit CGX_Deinit(void)
+{
+ printk(KERN_ERR "[CGX|%s] in\r\n", __FUNCTION__);
+
+ // Free the driver state buffer.
+ if (DrvContext.GpsIntr_irq != 0)
+ {
+ free_irq(DrvContext.GpsIntr_irq, NULL);
+ printk(KERN_ERR "free_irq GpsIntr_irq");
+ }
+
+ if (DrvContext.DataReady_irq != 0)
+ {
+ free_irq(DrvContext.DataReady_irq, NULL);
+ printk(KERN_ERR "free_irq DataReady_irq");
+ }
+
+ if (girq_wq) {
+ flush_workqueue(girq_wq);
+ destroy_workqueue(girq_wq);
+ printk(KERN_ERR "destroy_workqueue girq_wq");
+ }
+ if (drdy_wq) {
+ flush_workqueue(drdy_wq);
+ destroy_workqueue(drdy_wq);
+ printk(KERN_ERR "destroy_workqueue drdy_wq");
+ }
+
+ #ifdef CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT
+ if (drdy_completion_wq) {
+ printk(KERN_ERR "CGX_Deinit (1)");
+ //flush_workqueue(drdy_completion_wq); //commented for debug, because this function blocks !
+ //destroy_workqueue(drdy_completion_wq);
+ printk(KERN_ERR "CGX_Deinit (2)");
+ }
+ #endif
+#if 0
+ DrvContext.state.request.terminate = TRUE;
+ if(DrvContext.chunk.ptr) {
+ BOOL boo = FreePhysMem(DrvContext.chunk.ptr);
+ }
+#endif
+ printk(KERN_ERR "CGX_Deinit (3)");
+
+ //free_irq(TEMPLATE_CPU_DMA_IRQ, NULL);
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+ sprd_put_rf2351_ops(&gps_rf_ops);
+#endif
+ CgxDriverFreeInternalBuff(&DrvContext, 0);
+
+ cdev_del(&DrvContext.cdev);
+
+ device_destroy(gps_class, MKDEV(cgxdrv_major, 0));
+ class_destroy(gps_class);
+
+ unregister_chrdev_region(MKDEV(cgxdrv_major, 0), 1);
+#ifdef CGCORE_ACCESS_VIA_SPI
+ gpsspidev_exit();
+#endif
+ printk(KERN_ERR "CGX_Deinit out");
+}
+
+
+late_initcall(CGX_Init);
+module_exit(CGX_Deinit);
+
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Pablo 'merKur' Kohan <pablo@ximpo.com> - for CellGuide Ltd.");
+MODULE_DESCRIPTION("CellGuide GPSense CGX3XXX/CGX5XXX GPS CoProcessor driver");
+
+/** \endcond */
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverOs.h b/drivers/misc/gpsip/cgdriver/CgxDriverOs.h
new file mode 100644
index 00000000..9f0793ea
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverOs.h
@@ -0,0 +1,206 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief CellGuide CGsnap driver OS depended prototypes
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+ \addtogroup CGX_DRIVER_OS_API
+ \@{
+
+*/
+
+#ifndef CGX_DRIVR_OS_H
+#define CGX_DRIVR_OS_H
+
+#include "CgReturnCodes.h"
+
+
+
+
+
+
+/**
+ Get driver allocated buffer and convert it for application
+
+ \param[in] pSource Map pointer passed from application to the driver space
+ \param[in] aLength Length allocated (bytes)
+
+ \return Mapped pointer
+ \retval NULL on error
+
+*/
+void *CgxDriverGetInternalBuff(void *pSource, U32 aLength);
+
+
+
+/**
+ Allocate a kernel buffer
+
+ \param[in] pDriver Pointer to driver global structure
+ \param[in] aLength Length to allocate (bytes)
+ \param[out] apBuffer allocated buffer address
+ \param[in] aProcessID process id
+
+ \return System wide return code
+*/
+TCgReturnCode CgxDriverAllocInternalBuff(void *pDriver, U32 aLength, void **apBuffer, U32 aProcessID);
+
+
+
+
+/**
+ Free a kernel buffer
+
+ \param[in] pDriver Pointer to drivers global data
+ \param[in] aProcessId process id
+
+ \return System wide return code
+*/
+TCgReturnCode CgxDriverFreeInternalBuff(void *pDriver, U32 aProcessId);
+
+
+
+
+/**
+ Copy Memory from User Space
+
+ \param[in] to Target address (Kernel Space)
+ \param[in] fromuser Source address (User Space)
+ \param[in] n Length to copy
+
+
+ \return Number of bytes NOT copied (0=success)
+
+*/
+unsigned long CgxCopyFromUser(
+ void *to,
+ const void *fromuser,
+ unsigned long n );
+
+
+
+
+
+
+/**
+ Create transfer end signaling object.
+ the object will be used for blocking the application until transfer is finished.
+
+ \param[in] pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverTransferEndCreate(
+ void *pDriver);
+
+
+/**
+ Destroy transfer end signaling object.
+
+ \param[in] pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverTransferEndDestroy(
+ void *pDriver);
+
+
+/**
+ Signal transfer end object
+
+ \param[in] pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverTransferEndSignal(
+ void *pDriver);
+
+
+/**
+ Wait for transfer end object
+ \param pDriver Global driver structure pointer
+ \param aTimeoutMS timeout for the wait, in mili seconds.
+ if the object is not singled after this time, the function will
+ return with ECgTimeout error code.
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+*/
+TCgReturnCode CgxDriverTransferEndWait(
+ void *pDriver,
+ U32 aTimeoutMS);
+
+
+
+
+/**
+ Start data ready interrupt handle
+
+ \param[in] pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverDataReadyInterruptHandlerStart(
+ void *pDriver);
+
+
+
+/**
+ Start general interrupt handler
+
+ \param[in] pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverGpsInterruptHandlerStart(
+ void *pDriver);
+
+
+/**
+ Initialize the driver.
+
+ This function is called as a result of GPSenseEngine specific CGX_IOCTL_INIT request,
+ and is used to initialize the driver and hardware for the first time.
+
+ \param pDriver Global driver structure pointer
+
+ \return System wide return code
+ \retval ECgOk if data ready is 0 (low active)
+
+*/
+TCgReturnCode CgxDriverInit(
+ void *pDriver);
+
+
+
+
+#endif
+/**
+ \@}
+*/
diff --git a/drivers/misc/gpsip/cgdriver/CgxDriverPlatform.h b/drivers/misc/gpsip/cgdriver/CgxDriverPlatform.h
new file mode 100644
index 00000000..ec38ab1f
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/CgxDriverPlatform.h
@@ -0,0 +1,138 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief Driver platform depended API
+ \attention This file should not be modified.
+ If you think something is wrong here, please contact CellGuide
+
+*/
+
+#ifndef _CGX_DRIVER_PLATFORM_H__
+#define _CGX_DRIVER_PLATFORM_H__
+
+#include "CgReturnCodes.h"
+#include "CgxDriverApi.h"
+
+/**
+ Define the incoming data byte order
+*/
+extern const TCgByteOrder CGX_DRIVER_NATIVE_BYTE_ORDER;
+
+/**
+ Return the interrupt code for DMA interrupt
+ \if OS_LINUX
+ On Linux, request_irq uses this value to register the specified interrupt handler
+ \endif
+ \if OS_ANDROID
+ On Android, request_irq uses this value to register the specified interrupt handler
+ \endif
+ \return interrupt code
+ \retval 0 Don't use interrupt
+*/
+U32 CgxDriverDataReadyInterruptCode(void);
+
+
+
+/**
+ 0 means no IRQ code
+
+ \return IRQ # of DMA
+*/
+U32 CgxDriverDataReadyIrqCode(void);
+
+
+
+/**
+ Return the interrupt code for CGsnap interrupt
+ \if OS_LINUX
+ On Linux, request_irq uses this value to register the specified interrupt handler
+ \endif
+ \if OS_ANDROID
+ On Android, request_irq uses this value to register the specified interrupt handler
+ \endif
+ \return interrupt code
+ \retval 0 Don't use interrupt
+*/
+U32 CgxDriverGpsInterruptCode(void);
+
+
+
+/**
+ 0 means no IRQ code
+
+ \return IRQ # of GPS
+*/
+U32 CgxDriverGpsIrqCode(void);
+
+
+
+/**
+ Configure Data Ready (DMA) interrupt pin & directions
+ this function is called once, on driver startup (\ref CgxDriverConstruct)
+
+ \return System wide return code
+ \retval ECgOk Success
+*/
+TCgReturnCode CgxDriverDmaInterruptPrepare(void);
+
+
+
+/**
+ Initial setup for CGsnap interrupt
+ this function is called once, on driver startup (\ref CgxDriverConstruct)
+
+ \return System wide return code
+ \retval ECgOk Success
+*/
+TCgReturnCode CgxDriverGpsInterruptPrepare(void);
+
+
+
+
+/**
+ Return GPIO code for specific control line(for debug only)
+
+ \param[in] aPinNumber GPIO code (CellGuide format)
+ \param[out] aGpioCode Pointer to returned value
+
+ \return System wide return code
+ \retval ECgOk Success
+*/
+TCgReturnCode CgxDriverGpioCode(int aPinNumber, int *aGpioCode);
+
+
+TCgReturnCode CGxDriverGpsInterruptDone(U32 aIntCode);
+TCgReturnCode CGxDriverDataReadyInterruptDone(U32 aIntCode);
+
+
+
+/**
+ Enable/Disable TCXO power
+
+ \param[in] aEnable 1 = Enable TCXO, 0 =Disable TCXO
+
+ \note If required, use platform.h to define specific device pins,
+ and keep the actual function generic.
+
+ \return System wide return code
+ \retval ECgOk Success
+*/
+TCgReturnCode CgxDriverTcxoEnable(U32 aEnable);
+
+#endif /* _CGX_DRIVER_PLATFORM_H__ */
diff --git a/drivers/misc/gpsip/cgdriver/Makefile b/drivers/misc/gpsip/cgdriver/Makefile
new file mode 100644
index 00000000..e1144bb3
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/Makefile
@@ -0,0 +1,98 @@
+#PATH := $(PREBUILD)/bin:$(PATH)
+
+obj-$(CONFIG_CGX_DRIVER) := cgxdrv.o
+
+# C Object Files:
+cgxdrv-c-objs += CgxDriverLinux.o
+cgxdrv-c-objs += CgxDriverCore.o
+cgxdrv-c-objs += CgxDriverCoreCommon.o
+cgxdrv-c-objs += CgCpuLinux.o
+cgxdrv-c-objs += CgCpu.o
+cgxdrv-c-objs += platform.o
+
+
+#cgxdrv-c-objs += SPRD_FPGA_CPU.o
+#cgxdrv-c-objs += SPRD_FPGA_GPIO.o
+#cgxdrv-c-objs += SPRD_FPGA_DMA.o
+#cgxdrv-c-objs += SPRD_FPGA_CLK.o
+#cgxdrv-c-objs += SPRD_FPGA_INT.o
+#cgxdrv-c-objs += SPRD_FPGA_RF.o
+#cgxdrv-c-objs += gpsspi.o
+
+cgxdrv-c-objs += gps_gpio.o
+cgxdrv-c-objs += gps_dma.o
+
+#bxd
+ifeq ($(CONFIG_CGX_GE_GPS),y)
+cgxdrv-objs += gpsspi.o
+EXTRA_CFLAGS += -DCGCORE_ACCESS_VIA_SPI
+endif
+cgxdrv-objs += $(cgxdrv-c-objs)
+
+
+
+
+
+#LOCAL_CFLAGS := \
+#-DCGCORE_ACCESS_VIA_SPI
+# Headers:
+# Unused: CgFeatures.h pkfuncs.h toolhelp.h
+cgxdrv-hdrs += CgBuildNumber.h
+cgxdrv-hdrs += CgReturnCodes.h
+cgxdrv-hdrs += CgTypes.h
+cgxdrv-hdrs += CgVersion.h
+cgxdrv-hdrs += CgCpu.h
+cgxdrv-hdrs += CgCpuOs.h
+cgxdrv-hdrs += SPRD_FPGA_CPU.h
+cgxdrv-hdrs += SPRD_FPGA_CLK.h
+cgxdrv-hdrs += SPRD_FPGA_DMA.h
+cgxdrv-hdrs += SPRD_FPGA_GPIO.h
+cgxdrv-hdrs += SPRD_FPGA_INT.h
+cgxdrv-hdrs += CgxDriverCoreCommon.h
+cgxdrv-hdrs += CgxDriverApi.h
+cgxdrv-hdrs += CgxDriverCore.h
+cgxdrv-hdrs += CgxDriverOs.h
+cgxdrv-hdrs += CgxDriverPlatform.h
+cgxdrv-hdrs += platform.h
+
+
+#EXTRA_CFLAGS += \
+# -I. \
+# -I. \
+# -I. \
+# -I. \
+# -I. \
+# -I. \
+# -D__LINUX__ \
+# -D$(MODE) \
+# $(CG_CPPFLAGS)
+
+
+ifeq ($(KERNELRELEASE),)
+# on first call from remote location we get into this path
+# whilst on second call all is managed by the embedding kernel makefile
+
+cgxdrv-cfiles = ${cgxdrv-c-objs:.o=.c}
+
+#default:: kmod_build
+
+#kmod_build:: $(cgxdrv-cfiles) $(cgxdrv-hdrs)
+
+
+# distclean:: clean
+
+#grep::
+# grep $(G) $(cgxdrv-cfiles)
+
+#hgrep::
+# grep $(G) $(cgxdrv-hdrs)
+
+#clean::
+# rm -f *.o *.ko .*.cmd cgxdrv.mod.c $(cgxdrv-c-objs) $(obj-m)
+# rm -rf .tmp_versions
+
+#tags::
+# $(MAKE) -C $(CG_KERNEL_DIR) SUBDIRS=$(CURDIR) tags
+endif
+
+# ### EOF ###
diff --git a/drivers/misc/gpsip/cgdriver/gps_dma.c b/drivers/misc/gpsip/cgdriver/gps_dma.c
new file mode 100644
index 00000000..52371b5d
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/gps_dma.c
@@ -0,0 +1,302 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+
+#include <linux/kthread.h>
+#include <linux/signal.h>
+#include <soc/sprd/board.h>
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/dma.h>
+#include <linux/slab.h>
+
+#include "CgCpu.h"
+#include "platform.h"
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+#define INVALIDE_DMA_CHN (-1)
+
+static struct sci_dma_cfg *cfg_list;
+static struct reg_cfg_addr cfg_addr;
+static int node_size;
+static int cg_GpsDma_channel = INVALIDE_DMA_CHN;
+static char *CgGps_Dev_name = "CgGps_Dev";
+
+extern void clear_buf_data(void);
+extern void CCgCpuDmaHandle(int irq,void* dev_id);
+
+
+TCgReturnCode CgCpuDmaCreate(U32 aDmaChannel, U32 aIpDataSourceAddress)
+{
+ DBG_FUNC_NAME("CgCpuDmaCreate");
+ DBGMSG("entry");
+ if(cg_GpsDma_channel == INVALIDE_DMA_CHN)
+ {
+ cg_GpsDma_channel = sci_dma_request(CgGps_Dev_name, FULL_DMA_CHN);
+
+ if(cg_GpsDma_channel < 0)
+ {
+
+ printk("CgCpuDmaCreate fail err code = %d\n",cg_GpsDma_channel);
+ return cg_GpsDma_channel;
+
+ }
+ printk("CgCpuDmaCreate succ chn = %d\n",cg_GpsDma_channel);
+ }
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuDmaDestroy(U32 aDmaChannel, U32 aIpDataSourceAddress)
+{
+ int rc;
+ printk("%s cg_GpsDma_channel:%d\n",__func__,cg_GpsDma_channel);
+
+ if(cg_GpsDma_channel != INVALIDE_DMA_CHN)
+ {
+ rc = sci_dma_stop(cg_GpsDma_channel, DMA_GPS);
+ if(rc < 0)
+ {
+ printk("CgCpuDmaDestroy stop chn fail, chn num = %d, err code = %d\n",cg_GpsDma_channel,rc);
+ }
+
+ rc = sci_dma_free(cg_GpsDma_channel);
+ if(rc < 0)
+ {
+ printk("CgCpuDmaDestroy free chn fail, chn num = %d, err code = %d\n",cg_GpsDma_channel,rc);
+ }
+
+ cg_GpsDma_channel = INVALIDE_DMA_CHN;
+ }
+ return ECgOk ;
+}
+
+
+
+TCgReturnCode CgCpuDmaIsReady(U32 aDmaChannel)
+{
+ TCgReturnCode rc = ECgOk;
+ DBG_FUNC_NAME("CgCpuDmaIsReady");
+ DBGMSG("entry");
+
+ return rc;
+}
+
+TCgReturnCode CgCpuDmaStop(U32 aDmaChannel)
+{
+ int rc;
+
+ if(cfg_list != NULL)
+ {
+ kfree(cfg_list);
+ cfg_list = NULL;
+ }
+
+ if(cfg_addr.virt_addr)
+ {
+ dma_free_coherent(NULL, sizeof(struct sci_dma_cfg) * node_size, (void *)cfg_addr.virt_addr, cfg_addr.phys_addr);
+ cfg_addr.virt_addr = 0;
+ cfg_addr.phys_addr = 0;
+ node_size = 0;
+
+ }
+
+ rc = sci_dma_stop(cg_GpsDma_channel, DMA_GPS);
+ if(rc < 0)
+ {
+ printk("CgCpuDmaStop stop chn fail, chn num = %d, err code = %d\n",cg_GpsDma_channel,rc);
+ }
+
+ return ECgOk;
+
+}
+
+TCgReturnCode CgCpuDmaCurCount(U32 aDmaChannel, U32 *apCount)
+{
+ TCgReturnCode rc = ECgOk;
+ DBG_FUNC_NAME("CgCpuDmaCurCount");
+ DBGMSG("entry");
+
+ return rc;
+}
+
+// Get the DMA channel requested bytes count.
+TCgReturnCode CgCpuDmaRequestedCount(U32 aDmaChannel, U32 *apCount)
+{
+
+ TCgReturnCode rc = ECgOk;
+ DBG_FUNC_NAME("CgCpuDmaRequestedCount");
+ DBGMSG("entry");
+
+ return rc;
+}
+
+TCgReturnCode CgCpuDmaStart(U32 aDmaChannel)
+{
+ int rc;
+ printk("%s\n",__func__);
+ CgCpuCacheSync();
+ rc = sci_dma_start(cg_GpsDma_channel, DMA_GPS);
+ if(rc < 0)
+ {
+ printk("CgCpuDmaStart start chn fail, chn num = %d, err code = %d\n",cg_GpsDma_channel,rc);
+ }
+ //CgCpuCacheSync();
+
+ return ECgOk;
+}
+
+// Configure DMA to read data from GPS device.
+TCgReturnCode CgCpuDmaSetupFromGps(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDmaChannel, U32 aDeviceAddress)
+{
+ dma_addr_t cfg_p;
+ void * cfg_v;
+ int i,ret;
+
+ clear_buf_data();
+
+ if(aDmaTaskCount == 0)
+ {
+ return ECgBadArgument;
+ }
+
+ if(cfg_list != NULL)
+ {
+ kfree(cfg_list);
+ cfg_list = NULL;
+ }
+ if(cfg_addr.virt_addr != 0)
+ {
+ dma_free_coherent(NULL, sizeof(struct sci_dma_cfg) * node_size, (void *)cfg_addr.virt_addr, cfg_addr.phys_addr);
+ cfg_addr.virt_addr = 0;
+ cfg_addr.phys_addr = 0;
+ node_size = 0;
+ }
+
+ node_size = aDmaTaskCount;
+ if(cfg_list == NULL)
+ {
+ cfg_list = kzalloc(sizeof(struct sci_dma_cfg) * node_size, GFP_KERNEL);
+ if (!cfg_list) {
+ printk("alloc memory failed!\n");
+ return -ENOMEM;
+ }
+ }
+
+ cfg_v = dma_alloc_coherent(NULL, sizeof(struct sci_dma_cfg) * node_size,
+ &cfg_p, GFP_KERNEL);
+ if (!cfg_v) {
+ printk("alloc cfg list mem failed!\n");
+ return -ENOMEM;
+ }
+
+ cfg_addr.phys_addr = (u32)cfg_p;
+ cfg_addr.virt_addr = (u32)cfg_v;
+
+ /*must init the config with 0x0*/
+ memset((void *)cfg_list, 0x0, sizeof(struct sci_dma_cfg) * node_size);
+
+ for (i = 0; i < node_size; i++) {
+ /*the data width, byte short or word*/
+ cfg_list[i].datawidth = WORD_WIDTH;
+ cfg_list[i].src_step = 4;
+ cfg_list[i].des_step = 4;
+ cfg_list[i].wrap_ptr = 0x21c0007c;
+ cfg_list[i].wrap_to = 0x21c00070;
+ cfg_list[i].fragmens_len = 16;
+
+
+ /* request mode:
+ * when receive an hardware or software dma request
+ * the dma will transfer a fragment, block or a transcation data
+ */
+ cfg_list[i].req_mode = FRAG_REQ_MODE;
+ cfg_list[i].src_addr = aDeviceAddress;
+
+
+ cfg_list[i].des_addr = apDmaTask[i].address;
+ cfg_list[i].block_len = apDmaTask[i].length >= 65536 ? 65536 :apDmaTask[i].length;
+ cfg_list[i].transcation_len = apDmaTask[i].length;
+
+ //printk("\n cfg_list[%d].block_len = %d\n",i,cfg_list[i].block_len);
+ //printk("\n cfg_list[%d].transcation_len = %d\n",i,cfg_list[i].transcation_len);
+ //printk("\n cfg_list[%d].src_addr = 0x%x\n",i,cfg_list[i].src_addr);
+ //printk("\n cfg_list[%d].des_addr = 0x%x\n",i,cfg_list[i].des_addr);
+ }
+
+ /*indicate this the last node*/
+ cfg_list[node_size - 1].is_end = 1;
+
+ ret = sci_dma_config(cg_GpsDma_channel, cfg_list, node_size, &cfg_addr);
+ if (ret < 0) {
+ printk("dma config failed!\n");
+ }
+
+ sci_dma_register_irqhandle(cg_GpsDma_channel,TRANS_DONE,CCgCpuDmaHandle,NULL);
+
+ return ECgOk;
+}
+#else
+TCgReturnCode CgCpuDmaCreate(U32 aDmaChannel, U32 aIpDataSourceAddress)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaDestroy(U32 aDmaChannel, U32 aIpDataSourceAddress)
+{
+ return ECgOk ;
+}
+
+TCgReturnCode CgCpuDmaIsReady(U32 aDmaChannel)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaStop(U32 aDmaChannel)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaCurCount(U32 aDmaChannel, U32 *apCount)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaRequestedCount(U32 aDmaChannel, U32 *apCount)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaStart(U32 aDmaChannel)
+{
+ return ECgOk;
+}
+
+TCgReturnCode CgCpuDmaSetupFromGps(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDmaChannel, U32 aDeviceAddress)
+{
+ return ECgOk;
+}
+
+#endif
+
+#ifdef TRACE_ON
+void DbgStatDMA(const char *aTitle)
+{
+ //DBG_FUNC_NAME("DbgStatDMA");
+ //DBGMSG1("%s", aTitle);
+
+
+}
+#endif
+
+
diff --git a/drivers/misc/gpsip/cgdriver/gps_dma.h b/drivers/misc/gpsip/cgdriver/gps_dma.h
new file mode 100644
index 00000000..13168d93
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/gps_dma.h
@@ -0,0 +1,89 @@
+#ifndef GPS_DMA_H
+#define GPS_DMA_H
+
+#include <asm/io.h>
+
+#ifdef __cplusplus
+ extern "C"
+ {
+#endif
+
+#define MAX_DMA_CHUNK_SIZE (0x80000)
+
+#define MAX_DMA_TRANSFER_TASKS (64)
+
+#define DMAC_STATUS_SUCCESS (0)
+#define DMAC_STATUS_ERROR (-1)
+
+#define SPRD_GPS_DMA_IRQ (44)
+
+#define DMAC_BLOCK_SIZE (0xffff)
+
+#define CH_STAT_MASK (0x0000000f)
+
+#define CHANNEL_ENABLE (1)
+#define CHANNEL_DISABLE (0)
+
+#define DMAC_REMAP_NOACP 1
+
+#define REG_PERI_CTRL0 (IO_ADDRESS(0xFCA09000))
+
+#define RCHAIN_EN (0x02)
+#define RCHAIN_EN_MASK (0xfffffffc)
+
+//#define NUMBER_1K (1024)
+
+#define NUMBER_16K (16*1024)
+
+#define NUMBER_64K (64*1024)
+
+#define REG_DMAC_BASE CG_DRIVER_DMA_BASE_PA
+
+
+#define REG_DMAC_CX_CURR_CNT0 (IO_ADDRESS(REG_DMAC_BASE) + 0x0704)
+
+typedef struct DMA_CFG_S
+{
+ unsigned int src_addr;
+ unsigned int dma_phys;
+ unsigned int dma_size;
+ void __iomem *dma_virt;
+
+ unsigned int lli_count;
+ unsigned int lli_size;
+ unsigned int lli_addr_pa;
+ void *lli_addr_va;
+
+}GPS_DMAC_CFG;
+
+typedef union{
+ unsigned int cx_config_arg;
+ struct cx_config_bits
+ {
+ unsigned int ch_en : 1;
+ unsigned int itc_en : 1;
+ unsigned int flow_ctrl : 2;
+ unsigned int peri : 6;
+ unsigned int reserve1 : 2;
+ unsigned int dw : 3;
+ unsigned int reserve2 : 1;
+ unsigned int sw : 3;
+ unsigned int reserve3 : 1;
+ unsigned int dl : 4;
+ unsigned int sl : 4;
+ unsigned int dmode : 1;
+ unsigned int smode : 1;
+ unsigned int di : 1;
+ unsigned int si : 1;
+ }bits;
+}cx_config_reg_s;
+
+int CgCpuDmaLLIDataCopyFromGps(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDeviceAddress, U32 aDestAddress);
+
+int CgCpuDmaDataCopyFromGps(TCgCpuDmaTask *apDmaTask, U32 aDmaTaskCount, U32 aDeviceAddress, U32 aDestAddress);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
diff --git a/drivers/misc/gpsip/cgdriver/gps_gpio.c b/drivers/misc/gpsip/cgdriver/gps_gpio.c
new file mode 100644
index 00000000..fd550143
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/gps_gpio.c
@@ -0,0 +1,201 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+/**
+ \file
+ \brief SPRD_FPGA GPIO support
+
+ Functions to access GPIO unit in SPRD_FPGA CPU, allowing GPSenseEngine to control GPIO lines.
+ \attention This file is not completed, and must be updated for SPRD_FPGA (Please verify all 'TODO' comments are handled)
+
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//#include <linux/gpio.h>
+#include <soc/sprd/gpio.h>
+//#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <soc/sprd/board.h>
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/irqs.h>
+// ===========================================================================
+//Kernel Ioctl
+#include "CgTypes.h" /**< CellGuide Types */
+#include "CgCpu.h"
+
+/** OK status */
+#define ECgOk (0)
+
+
+
+
+// ===========================================================================
+
+
+
+
+
+
+// ===========================================================================
+
+
+/**
+ Internal function, set/reset a GPIO.
+
+ This function is used by API functions CgCpuGpioSet & CgCpuGpioReset
+*/
+#if 0
+static TCgReturnCode GpioSet(U32 aPin, U32 aValue)
+{
+ //DBG_FUNC_NAME("GpioSet");
+ TCgReturnCode rc = ECgOk;
+ // unsigned long gpio_addr = 0;
+ return rc;
+}
+#endif
+
+
+TCgReturnCode CgCpuGpioSet(U32 aPin)
+{
+
+ U32 gpio_num;
+ gpio_num = aPin;
+ __gpio_set_value(gpio_num,1);
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuGpioReset(U32 aPin)
+{
+ U32 gpio_num;
+
+ gpio_num = aPin;
+ __gpio_set_value(gpio_num,0);
+ return ECgOk ;
+}
+
+
+TCgReturnCode CgCpuGpioGet(U32 aPin, int *aValue)
+{
+ U32 rc = 0;
+ //DBG_FUNC_NAME("CgCpuGpioGet");
+
+
+ *aValue = __gpio_get_value(aPin);
+ *aValue = 0;
+ return rc;
+}
+
+
+TCgReturnCode CgCpuGpioModeSet(U32 aPin, TCgCpuGpioMode aMode)
+{
+ //U32 extint = 0;
+ TCgReturnCode rc = ECgOk;
+ // unsigned long gpio_dir = 0;
+//bxd add
+ if(aMode == ECG_CPU_GPIO_INPUT)
+ gpio_direction_input (aPin);
+ else if(aMode == ECG_CPU_GPIO_OUTPUT)
+ gpio_direction_output(aPin,1);
+
+ //DBG_FUNC_NAME("CgCpuGpioModeSet")
+
+ return rc;
+
+}
+
+TCgReturnCode CgCpuGpioPull(U32 aPinCode, TCgCpuGpioPull aPull)
+{
+ // U32 group = (aPinCode / CG_CPU_GPIO_GROUP_SIZE) - 1;
+ // U32 pin = aPinCode % CG_CPU_GPIO_GROUP_SIZE;
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuGpioStrength(U32 aPinCode, U32 aStrength)
+{
+ //U32 group = (aPinCode / CG_CPU_GPIO_GROUP_SIZE) - 1;
+ //U32 pin = aPinCode % CG_CPU_GPIO_GROUP_SIZE;
+
+
+ return ECgOk;
+}
+
+
+TCgReturnCode CgCpuGpioCreate(void)
+{
+ TCgReturnCode rc = ECgOk;
+
+ #if 0
+
+ gpio_request(GPIO_GPS_IRQ, "gps_irq");
+ gpio_direction_input(GPIO_GPS_IRQ);
+
+ gps_irq = gpio_to_irq(GPIO_RESET_IRQ);
+
+ gpio_request(GPIO_GPS_RESET , "gps_rst");
+ printk("%s oob_irq:%d\n", __func__, oob_irq);
+ #endif
+
+ return rc;
+}
+
+
+
+TCgReturnCode CgCpuGpioDestroy(void)
+{
+ u32 rc = 0;
+
+ #if 0
+ gpio_free(GPIO_GPS_IRQ);
+ gpio_free(GPIO_GPS_RESET);
+ #endif
+
+ return rc;
+}
+
+
+
+int SPRD_FPGA_gpio_set_regvalue(unsigned long addr, unsigned int bit, unsigned int data)
+{
+
+
+ return 0;
+}
+
+int SPRD_FPGA_gpio_get_regvalue(unsigned long addr, unsigned int bit)
+{
+ unsigned int value = 0;
+
+
+ return value;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
diff --git a/drivers/misc/gpsip/cgdriver/gpsspi.c b/drivers/misc/gpsip/cgdriver/gpsspi.c
new file mode 100644
index 00000000..a5dfe7d4
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/gpsspi.c
@@ -0,0 +1,459 @@
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spidev.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <soc/sprd/dma.h>
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/gpio.h>
+#include <linux/proc_fs.h>
+#include <linux/kthread.h>
+
+#include "CgCpuOs.h"
+#include "platform.h"
+#include "CgxDriverCore.h"
+#include "CgxDriverCoreCommon.h"
+
+
+
+#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \
+ | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP)
+
+
+#define SPI_READ_CMD(len,addr) ((1 << 30) | (addr & 0x1FFFF)|(((len-1) & 0x1FF) << 20))
+#define SPI_WRITE_CMD(len,addr) ((1 << 30) |(1 << 31) | (addr & 0x1FFFF)|(((len-1) & 0x1FF) << 20))
+#define SPI_BLOCK_READ_CMD(len) ( (len-1) & 0xF )
+#define SPI_BLOCK_WRITE_CMD(len) ( (1 << 9) | (len-1) & 0xF )
+
+#define SPI_BLOCK_DATA_ENC(len,addr) (( ((len-1)&0x7FFF) << 17 ) | ( addr & 0x1FFFF))
+//#define SPI_BLOCK_DATA_ENC(len,addr) (( ((len-1)&0x7FFF) << 17 ) | ( addr & 0x1FFFF))
+
+
+#define SPI_READ_SYS_CMD(len,addr) ((1 << 30) | (1 << 29) | (addr & 0x1FFFF)|(((len-1) & 0x1FF) << 20))
+#define SPI_WRITE_SYS_CMD(len,addr) ((1 << 30) | (1 << 29) | (1 << 31) | (addr & 0x1FFFF)|(((len-1) & 0x1FF) << 20))
+
+extern void DataReady_TH_start (void);
+extern int get_blocksize (void);
+extern unsigned int get_block_num (void);
+extern void* Data_Get_DrvContext(void);
+extern u32 GetRequestLen(void);
+
+
+struct spi_device *gps_spi_dev = NULL;
+static int irq_number, addr_flag_side;
+//static u32 count_block = 0;
+static u32 Revcount_block = 0;
+static u32 RevtotalLen = 0;
+
+
+//#define FIX_MEMORY
+#ifdef FIX_MEMORY
+extern unsigned char buf_data[6 * 1024 * 1024];
+static u8 *read_buf = (u8 *) buf_data;
+
+#else
+extern void *buf_data;
+static u8 *read_buf;
+#endif
+
+
+static void
+spi_transfer (unsigned char *tx1_buf, int write_len,
+ unsigned char *tx2_buf, int tx2_len,
+ unsigned char *rx_buf, int rx_len, bool cs_change)
+{
+ int status;
+ struct spi_message m;
+
+ struct spi_transfer _tx_1 = {
+ .tx_buf = tx1_buf,
+ .rx_buf = NULL,
+ .len = write_len,
+ .cs_change = 0,
+ .bits_per_word = 32,
+ // .delay_usecs = 200,
+ };
+ struct spi_transfer _tx_2 = {
+ .tx_buf = tx2_buf,
+ .rx_buf = NULL,
+ .len = tx2_len,
+ .cs_change = 0,
+ .bits_per_word = 32,
+ // .delay_usecs = 200,
+ };
+
+ struct spi_transfer _rx = {
+ .rx_buf = rx_buf,
+ .tx_buf = NULL,
+ .len = rx_len,
+
+ .bits_per_word = 32,
+ .cs_change = 0,
+ };
+ gpio_direction_output(CG_DRIVER_GPIO_GPS_SPI_CS, 0);
+
+ spi_message_init (&m);
+ if (write_len)
+ spi_message_add_tail (&_tx_1, &m);
+ if (tx2_len)
+ spi_message_add_tail (&_tx_2, &m);
+ if (rx_len)
+ spi_message_add_tail (&_rx, &m);
+
+ if (!list_empty (&m.transfers))
+ {
+ status = spi_sync (gps_spi_dev, &m);
+ }
+ gpio_direction_output(CG_DRIVER_GPIO_GPS_SPI_CS, 1);
+}
+
+
+int gps_spi_write_bytes (u32 len, u32 addr, u32 data)
+{
+ u32 write_cmd[2];
+
+ //printk ("%s addr:%x len:%x data:0x%x\n",__func__, addr, len, data);
+
+ //Because of the HwTest not enable the gps dma req,so force to set it.
+ if((addr == 0x88)&&(data == 0x06))
+ data = 0x6016;
+ if (addr > 0x6000)
+ {
+ BUG_ON (1);
+ return 0;
+ }
+ if (len == 1)
+ {
+ write_cmd[0] = SPI_WRITE_CMD (len * 1, (addr / 4 + 0x3000));
+ write_cmd[1] = data;
+ spi_transfer ((u8 *)&write_cmd[0], 8, NULL, 0, NULL, 0, true);
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL (gps_spi_write_bytes);
+
+
+
+/*make sure len is word units*/
+int
+gps_spi_read_bytes (u32 len, u32 addr, u32 * data)
+{
+ u32 read_cmd[2] = {0};
+
+ if (len == 1) /*one block all way */
+ {
+ read_cmd[0] = SPI_READ_CMD (len, (addr / 4 + 0x3000));
+ spi_transfer (NULL, 0, (u8 *) & read_cmd[0], 4,
+ (u8 *) & read_cmd[1], 4, true);
+
+ *data = read_cmd[1];
+ }
+ else /*more than one word,block */
+ {
+ u32 read_cmd_block[2];
+
+ /*len word unit */
+ read_cmd_block[0] = SPI_BLOCK_READ_CMD (1);
+ read_cmd_block[1] = SPI_BLOCK_DATA_ENC (len, addr);
+
+ spi_transfer (NULL, 0, (u8 *)&read_cmd_block[0], 8, (u8 *) data,len*4,
+ true);
+
+ read_cmd[1] = data[0];
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL (gps_spi_read_bytes);
+
+
+int gps_spi_sysreg_write_bytes (u32 len, u32 addr, u32 data)
+{
+ u32 write_cmd[2];
+
+ //printk ("%s addr:%x len:%x data:0x%x\n",__func__, addr, len, data);
+ if (len == 1)
+ {
+ write_cmd[0] = SPI_WRITE_SYS_CMD (len, addr);
+ write_cmd[1] = data;
+ spi_transfer ((u8 *)&write_cmd[0], 8, NULL, 0, NULL, 0, true);
+ }
+ return 0;
+}
+
+
+/*make sure len is word units*/
+int gps_spi_sysreg_read_bytes (u32 len, u32 addr, u32 * data)
+{
+ u32 read_cmd[2] = {0};
+
+ if (len == 1) /*one block all way */
+ {
+ read_cmd[0] = SPI_READ_SYS_CMD(len, addr);
+ spi_transfer (NULL, 0, (u8 *) & read_cmd[0], 4,
+ (u8 *) & read_cmd[1], 4, true);
+
+ *data = read_cmd[1];
+ }
+
+ return 0;
+}
+#define SYSREG_BIT3_BIT4_BIT5_BIT7 (1<<3|1<<4|1<<5|1<<7)
+#define SYS_BIT10 (1<<10)
+
+void PowerUpOtherClk(void)
+{
+ u32 value = 0;
+
+ gps_spi_sysreg_read_bytes(1,0x03,&value);
+ value |= SYSREG_BIT3_BIT4_BIT5_BIT7;
+ value &= ~SYS_BIT10;
+ gps_spi_sysreg_write_bytes(1,0x03,value);
+ gps_spi_sysreg_read_bytes(1,0x03,&value);
+ printk("PowerUpOtherClk:0x03=0x%x\n",(unsigned int)value);
+
+}
+
+void PowerDownOtherClk(void)
+{
+ u32 value = 0;
+
+ gps_spi_sysreg_read_bytes(1,0x03,&value);
+ value &= ~SYSREG_BIT3_BIT4_BIT5_BIT7;
+ value |= SYS_BIT10;
+ gps_spi_sysreg_write_bytes(1,0x03,value );
+ gps_spi_sysreg_read_bytes(1,0x03,&value);
+ printk("PowerDownOtherClk :0x03=0x%x\n",(unsigned int)value);
+
+}
+
+void Reset_GPS_RecvAddress(void)
+{
+ irq_number = 0;
+}
+
+int irq_count = 0;
+
+void init_spi_block_var(void)
+{
+ addr_flag_side = 0;
+ irq_number = 0;
+ Revcount_block = 0;
+ RevtotalLen = 0;
+ buf_data = Data_Get_DrvContext();
+}
+
+void gps_GetDataFromFPGA(void)
+{
+ u32 read_len=1024*4;
+ u32 block_size = get_blocksize();
+
+ // the use space reset rcv address and spi has rcv part data ,not conside the block szie less 4K size
+ if(irq_number ==1)
+ {
+
+ u32 len = RevtotalLen - Revcount_block * block_size;
+ void * pStart = Data_Get_DrvContext();
+
+ if(len)
+ {
+ printk (" SPI has rcv but not submit len = %d $$$$$$$\n", len);
+ memcpy(pStart, (void*)(read_buf + read_len*4 -len) ,len);
+ }
+ buf_data = (u8*)(pStart+ len);
+ }
+
+ read_buf = (u8*)((u8*)buf_data + (irq_number -1)* read_len*4);
+ gps_spi_read_bytes(read_len,0x5000+addr_flag_side*read_len,(u32*)read_buf);
+ if(addr_flag_side)
+ {
+ addr_flag_side = 0 ;
+ }
+ else
+ {
+ addr_flag_side = 1 ;
+ }
+ // recv all data len from FPGA
+ RevtotalLen = RevtotalLen + read_len*4;
+ // GPS_DEBUG_TRACE ("gps_GetDataFromFPGA buf=0x%p 0x%p rcvtotalLen = 0x%x, irq_number = %d &&&&& \n",
+ //buf_data,read_buf,RevtotalLen,irq_number);
+}
+
+// BlockNum: all total number
+static int submitLastBlock(int BlockNum)
+{
+ int lastFlag = FALSE;
+ u32 requestLen = GetRequestLen(); // user requset data len
+
+ if(Revcount_block ==(BlockNum -1))
+ {
+ if((requestLen < RevtotalLen ) ||(requestLen ==RevtotalLen))
+ {
+ Revcount_block++;
+ //GPS_DEBUG_TRACE ("sbumit last blocks Rev count_block =%d requestLen = 0x%x ,RevtotalLen = 0x%x&&&&&& \n",
+ //Revcount_block,requestLen,RevtotalLen);
+ DataReady_TH_start();
+ Revcount_block = 0;
+ lastFlag = TRUE;
+ }
+ }
+ return lastFlag;
+}
+
+void gps_DealWithBlocks(void)
+{
+ u32 dataLen = 0;
+ int lastfrag = 0;
+ int count = 0;
+ int i;
+
+ u32 block_size = get_blocksize();
+ u32 block_num = get_block_num();
+
+ if(0 == Revcount_block)
+ {
+ if((RevtotalLen > block_size) || (RevtotalLen == block_size))
+ {
+ count= RevtotalLen /block_size;
+ for(i = 0; i < count; i++)
+ {
+ Revcount_block ++;
+ DataReady_TH_start();
+ //GPS_DEBUG_TRACE ("gps_DealWithBocks Rev count_block = %d &&& \n",Revcount_block);
+ }
+ //check last blocks
+ submitLastBlock(block_num);
+ }
+ else
+ {
+ // GPS_DEBUG_TRACE ("gps_DealWithBocks no blocks submit $$$$$$ \n");
+ }
+ }
+ else
+ {
+
+ dataLen = RevtotalLen - Revcount_block * block_size;
+ //check the last datalen
+ lastfrag = submitLastBlock(block_num);
+ if(!lastfrag)
+ {
+ count= dataLen /block_size;
+ for( i = 0; i < count; i++)
+ {
+ Revcount_block++;
+ DataReady_TH_start();
+ // GPS_DEBUG_TRACE ("gps_DealWithBocks sbumit Revcount_block = %d &&&\n",Revcount_block);
+ }
+ //check the last block
+ submitLastBlock(block_num);
+ }
+ }
+ }
+
+ // the bottle interrupt deal with user data
+void gps_spi_recv_handle(void * data)
+{
+ gps_GetDataFromFPGA();
+ gps_DealWithBlocks();
+}
+
+/*gpio inturrupt handle*/
+int data_req_handle (int para, void *param)
+{
+ irq_number++;
+ //printk("irq_number:%d\n",irq_number);
+ //bxd test
+ irq_count++;
+ gps_spi_recv_handle (0);
+
+ return 0;
+}
+
+static int
+gpsspidev_probe (struct spi_device *spi)
+{
+ if(spi->master->bus_num != 2)
+ return -EINVAL;
+ gps_spi_dev = spi;
+
+ spi->max_speed_hz = 24000*1000;
+ spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 32;
+
+ spi_setup(gps_spi_dev);
+
+ return 0;
+}
+static int
+gpsspidev_remove (struct spi_device *spi)
+{
+
+ return 0;
+}
+
+
+static struct spi_board_info spi_boardinfo[] = {
+ {
+ .modalias = "spidev_gps",
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 24000 * 1000,
+ .mode = SPI_MODE_0,
+ }
+};
+
+
+static void sprd_spi_device_init(void)
+{
+ struct spi_board_info *info = spi_boardinfo;
+ spi_register_board_info(info, ARRAY_SIZE(spi_boardinfo));
+}
+
+
+static struct spi_driver gpsspidev_spi = {
+ .driver = {
+ .name = "spidev_gps",
+ .owner = THIS_MODULE,
+ },
+ .probe = gpsspidev_probe,
+ .remove = gpsspidev_remove,
+};
+
+int gpsspidev_init (void)
+{
+
+ int major;
+ sprd_spi_device_init();
+ major = spi_register_driver (&gpsspidev_spi);
+ if (major < 0)
+ {
+ unregister_chrdev (major, gpsspidev_spi.driver.name);
+ printk ("spi_register_driver fail !!major = %d\n", major);
+ }
+ printk ("gpsspidev_init end major=%d!\n", major);
+
+ return major;
+}
+
+
+void gpsspidev_exit (void)
+{
+ spi_unregister_driver (&gpsspidev_spi);
+}
+
+
diff --git a/drivers/misc/gpsip/cgdriver/platform.c b/drivers/misc/gpsip/cgdriver/platform.c
new file mode 100644
index 00000000..44f9e64d
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/platform.c
@@ -0,0 +1,770 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief platform/CPU specific code
+
+ \defgroup CGX_DRIVER_PLATFORM_ANDROID CPU/Android platform specific defines
+ \{
+*/
+
+#include <asm/uaccess.h>
+#include <soc/sprd/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <soc/sprd/regulator.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include "CgxDriverApi.h"
+#include "CgCpu.h"
+#include "platform.h"
+#include "CgReturnCodes.h"
+#include "CgxDriverOs.h"
+#include "CgxDriverCore.h"
+
+#ifdef CONFIG_ARCH_SCX20
+#include <linux/sprd_2351.h>
+#endif
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+extern TCgReturnCode CGCoreSclkEnable(int enable);
+struct sprd_2351_interface *gps_rf_ops;
+#endif
+
+/** Native byte order for this CPU */
+const TCgByteOrder CGX_DRIVER_NATIVE_BYTE_ORDER = ECG_BYTE_ORDER_4321; // SPRD_FPGA is little endian
+
+/*
+ Reset the core and timers and initialize GPIO (direction and special function)
+*/
+TCgReturnCode CgxDriverInit(void *pDriver)
+{
+ // Check all addresses are defined
+ /*
+ #if CG_DRIVER_CGSNAP_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_CGSNAP_BASE_PA with correct address
+ #endif
+ #if CG_DRIVER_REVISION_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_REVISION_BASE_PA with correct address
+ #endif
+ #if CG_DRIVER_GPIO_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_GPIO_BASE_PA with correct address
+ #endif
+ #if CG_DRIVER_DMA_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_DMA_BASE_PA with correct address
+ #endif
+ #if CG_DRIVER_INTR_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_INTR_BASE_PA with correct address
+ #endif
+ #if CG_DRIVER_CLK_BASE_PA == CG_UNDEFINED_ADDRESS
+ #error please define CG_DRIVER_CLK_BASE_PA with correct address
+ #endif
+ */
+ // TODO 1st time initialization
+
+ return ECgOk;
+}
+
+
+
+
+
+
+TCgReturnCode CgxDriverDataReadyPrepare(void)
+{
+ return CgCpuGpioModeSet(CGX5000_DR, ECG_CPU_GPIO_FALLING_INT);
+}
+
+
+TCgReturnCode CgxDriverInterruptPrepare(void)
+{
+ TCgReturnCode rc = ECgOk;
+
+ // not using 'GPS' interrupt, so there is nothing to do
+
+ return rc;
+}
+
+TCgReturnCode CgxDriverDmaInterruptPrepare(void)
+{
+ // TODO initial setup for DMA interrupt.
+ // if no special work is required, leave this function empty
+ return ECgOk;
+}
+
+
+
+
+TCgReturnCode CgxDriverGpsInterruptPrepare(void)
+{
+ // TODO return the interrupt code for 'CGsnap' interrupt
+ // if no special work is required, leave this function empty
+ return ECgOk;
+}
+
+
+
+
+U32 CgxDriverDataReadyInterruptCode(void)
+{
+ // TODO return the interrupt code for 'DMA end of transfer' interrupt
+
+ return 0;
+}
+
+
+U32 CgxDriverGpsInterruptCode(void)
+{
+ // TODO return the interrupt code for 'CGsnap' interrupt
+#ifndef CGCORE_ACCESS_VIA_SPI
+ return SPRD_GPS_INT;
+#else
+ gpio_direction_input (CG_DRIVER_GPIO_GPS_INT);
+ return gpio_to_irq(CG_DRIVER_GPIO_GPS_INT);
+#endif
+}
+
+
+TCgReturnCode CgxDriverWriteData(unsigned char *aSourceVirtualAddress, unsigned long aSourcePhysicalAddress, unsigned long aLengthBytes)
+{
+ //DBG_FUNC_NAME("CgxDriverWriteData")
+ TCgReturnCode rc = ECgOk;
+
+// #if WRITE_MODE == CG_CPU_SPI_MODE_DMA
+// if (OK(rc)) rc = CgCpuSpiDmaStop(SPI_CHANNEL);
+// CgCpuCacheSync();
+// CgCpuSpiSetup(SPI_CHANNEL, SPI_PRESCALE, ECG_CPU_SPI_OUTPUT_DMA);
+// CgCpuDmaSetupToDevice(aSourcePhysicalAddress,aLengthBytes,0,0);
+// if (OK(rc)) rc = CgCpuSpiDmaStart(SPI_CHANNEL);
+// if (OK(rc)) rc = CgCpuDmaWaitFinish(CG_DRIVER_DMA_CHANNEL_WRITE);
+// #elif WRITE_MODE == CG_CPU_SPI_MODE_MANUAL
+// U32 i;
+// CgCpuSpiSetup(SPI_CHANNEL, SPI_PRESCALE, ECG_CPU_SPI_OUTPUT_POLLING);
+//
+// for(i = 0; i < aLengthBytes; i++) {
+// CgCpuSpiTxFinishWait(SPI_CHANNEL);
+// CgCpuSpiWriteByte(SPI_CHANNEL, aSourceVirtualAddress[i]);
+// }
+// #endif
+
+ return rc;
+}
+
+
+TCgReturnCode CgxDriverGpioCode(int aControlLine, int *aGpioCode)
+{
+ *aGpioCode = 0;
+ return ECgNotSupported;
+}
+
+TCgReturnCode CgxDriverReadData(unsigned char *aTargetVirtualAddress, unsigned long aTargetPhysicalAddress, unsigned long aLengthBytes)
+{
+ //DBG_FUNC_NAME("CgxDriverReadData")
+ TCgReturnCode rc = ECgOk;
+
+// #if READ_MODE==CG_CPU_SPI_MODE_DMA
+// // memset(aTargetVirtualAddress, 0x55, aLengthBytes); //NG! debug
+// CgCpuCacheSync();//NG! debug
+// // Buffer data (not register data) is written in DMA mode
+// if (OK(rc)) rc = CgCpuSpiDmaStop(SPI_CHANNEL);
+//
+// CgCpuCacheSync();
+// if (OK(rc)) rc = CgCpuSpiSetup(SPI_CHANNEL, SPI_PRESCALE, ECG_CPU_SPI_INPUT_DMA);
+// if (OK(rc)) rc = CgCpuDmaSetupFromDevice(aTargetPhysicalAddress, aLengthBytes, SPI_PRESCALE, CG_DRIVER_DMA_CHANNEL_READ, CG_DRIVER_DMA_CHANNEL_WRITE, SPI_CHANNEL);
+// if (OK(rc)) rc = CgCpuSpiDmaStart(SPI_CHANNEL);
+// // no need to wait for DMA to finish
+//
+// #elif READ_MODE==CG_CPU_SPI_MODE_MANUAL
+// unsigned long i;
+// CgCpuSpiSetup(SPI_CHANNEL, SPI_PRESCALE, ECG_CPU_SPI_INPUT_POLLING);
+// for(i = 0; i < aLengthBytes; i++) {
+// CgCpuSpiWriteByte(SPI_CHANNEL, 0); //dummy transmit
+// CgCpuSpiRxFinishWait(SPI_CHANNEL);
+// CgCpuSpiReadByte(SPI_CHANNEL, (volatile unsigned char *)(aTargetVirtualAddress + i));
+// }
+// #endif
+
+ return rc;
+
+}
+
+
+TCgReturnCode CgxDriverClearData(unsigned char *aTargetVirtualAddress, unsigned long aTargetPhysicalAddress, unsigned long aLengthBytes)
+{
+ return CgxDriverReadData(aTargetVirtualAddress, aTargetPhysicalAddress, aLengthBytes);
+}
+
+
+TCgReturnCode CgxDriverIsDataReady(void)
+{
+ unsigned int val = 0;
+ CgCpuGpioModeSet(CGX5000_DR, ECG_CPU_GPIO_INPUT);
+ CgCpuGpioGet(CGX5000_DR, &val);
+ return (val == 0) ? ECgOk : ECgGeneralFailure;
+}
+
+
+TCgReturnCode CgxDriverReadDataTail(unsigned char *aTargetVirtualAddress, unsigned long aTargetPhysicalAddress, unsigned long aLengthBytes)
+{
+ // no tail reading is required for SPRD_FPGA
+
+ return ECgOk;
+}
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+static void CgxDriverRFInit(void)
+{
+ unsigned int value;
+
+ value = 0x005f8420;
+ gps_spi_write_bytes(1, 0x82*4, value);
+ gps_spi_read_bytes(1, 0x82*4, &value);
+
+ value = 0x00010003;
+ gps_spi_write_bytes(1, 0x83*4, value);
+
+ /*RF4in1 */
+ value = 0x006f0609;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x007b8020;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x07000001;//GPS Mode 0:Idle 1:Rx
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+#if 0
+ value = 0x004af417;
+ gps_spi_write_bytes(1, 0x80*4, value);
+#endif
+ value = 0x07385400;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x076c0721;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ /*for 26M/16M TCXO AGC 1bit*/
+ value = 0x07635140;//0x07635141;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x0704ef00;//max gain
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+#if 1 //def CGCORE_GPS_26M /*for 26M TCXO*/
+ value = 0x073c08d2;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x07023d61;
+ gps_spi_write_bytes(1, 0x80*4, value);
+#else /*for 16M TCXO*/
+ value = 0x073c0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x07026180;
+ gps_spi_write_bytes(1, 0x80*4, value);
+#endif
+
+ //for dma block size
+ gps_spi_sysreg_read_bytes(1,0x01,&value);;
+ value = 0;
+ value = ((1<<28)|(1<<26)|(1<<25));
+ gps_spi_sysreg_write_bytes(1,0x01,value );
+ gps_spi_sysreg_read_bytes(1,0x01,&value);
+
+#if 1
+ /*When for RX Analog test such as GAIN and IF frequency ,
+ we will add following configuration*/
+ value = 0x077b0112;//0x077b0101;
+ gps_spi_write_bytes(1, 0x80*4, value);
+#endif
+
+#if 0 //for RF Test
+ value = 0x075d88e6;
+ gps_spi_write_bytes(1, 0x80*4, value);
+
+ value = 0x070a7835;
+ gps_spi_write_bytes(1, 0x80*4, value);
+#endif
+
+ //read reg
+ value = 0x806f0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x006f0609:0x%x\n",value);
+
+ value = 0x807b0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x007b8020:0x%x\n",value);
+
+ value = 0x87000000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x07000001:0x%x\n",value);
+
+ value = 0x87380000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x07385400:0x%x\n",value);
+
+ value = 0x876c0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x076c0721:0x%x\n",value);
+
+
+ value = 0x87630000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x07635140:0x%x\n",value);
+
+ value = 0x87040000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x0704ef00:0x%x\n",value);
+
+#if 1 /*for 26M TCXO*/
+ value = 0x873c0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x073c08d2:0x%x\n",value);
+
+ value = 0x87020000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x07023d61:0x%x\n",value);
+#else
+ value = 0x873c0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x073c0000:0x%x\n",value);
+
+ value = 0x87020000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x07026180:0x%x\n",value);
+#endif
+
+ value = 0x877b0000;
+ gps_spi_write_bytes(1, 0x80*4, value);
+ gps_spi_read_bytes(1, 0x81*4, &value);
+ printk("rf 0x077b0112:0x%x\n",value);
+
+}
+
+void gps_gpio_request(void)
+{
+ int ret;
+ ret = gpio_request (CG_DRIVER_GPIO_GPS_PDN, "gps_pdn");
+ if (ret){
+ printk ("gps_pdn request err: %d\n", CG_DRIVER_GPIO_GPS_PDN);
+ }
+
+ ret = gpio_request (CG_DRIVER_GPIO_GPS_MRSTN, "gps_reset");
+ if (ret){
+ printk ("gps_reset request err: %d\n", CG_DRIVER_GPIO_GPS_MRSTN);
+ }
+
+ ret = gpio_request (CG_DRIVER_GPIO_GPS_SPI_CS, "gps_spi_cs");
+ if (ret){
+ printk ("gps_spi_cs request err: %d\n", CG_DRIVER_GPIO_GPS_SPI_CS);
+ }
+
+ ret = gpio_request (CG_DRIVER_GPIO_GPS_INT, "gps-req-int");
+ if (ret)
+ {
+ printk ("gps-req- int err: %d\n", CG_DRIVER_GPIO_GPS_INT);
+ }
+}
+
+static struct regulator *greeneye_vdd = NULL;
+static void greeneye_vddsim2_enable(bool on)
+{
+ int ret;
+ if (greeneye_vdd == NULL) {
+ greeneye_vdd = regulator_get(NULL, "vddsim2");
+
+ if (IS_ERR(greeneye_vdd)) {
+ pr_err("Get regulator of vddsim2 error!\n");
+ return;
+ }
+ }
+ if (on) {
+ regulator_set_voltage(greeneye_vdd, 2800000, 2800000);
+ ret = regulator_enable(greeneye_vdd);
+ }
+ else if (regulator_is_enabled(greeneye_vdd)) {
+ ret = regulator_disable(greeneye_vdd);
+ }
+}
+
+
+static void gps_clk_init(bool enable)
+{
+ static struct clk *gps_clk_32k=NULL;
+
+ if (gps_clk_32k == NULL) {
+ gps_clk_32k = clk_get(NULL, "ext_32k");
+ if (IS_ERR(gps_clk_32k)) {
+ printk("failed to get parent ext_32k\n");
+ return;
+ }
+ }
+ if (enable) {
+ #ifndef CONFIG_OF
+ clk_enable(gps_clk_32k);
+ #else
+ clk_prepare_enable(gps_clk_32k);
+ #endif
+ }else{
+ #ifndef CONFIG_OF
+ clk_disable(gps_clk_32k);
+ #else
+ clk_disable_unprepare(gps_clk_32k);
+ #endif
+ }
+}
+
+TCgReturnCode CgxDriverRFPowerDown(void)
+{
+ //DBG_FUNC_NAME("CgxDriverRFPowerDown")
+ TCgReturnCode rc = ECgOk;
+ unsigned int value;
+
+ printk("%s\n",__func__);
+
+ /*RF4in1 */
+ value = 0x07000000;//GPS Mode 0:Idle 1:Rx
+ gps_spi_write_bytes(1, 0x80*4, value);
+ return rc;
+}
+
+TCgReturnCode CgxDriverRFPowerUp(void)
+{
+ //DBG_FUNC_NAME("CgxDriverRFPowerDown")
+ TCgReturnCode rc = ECgOk;
+
+ printk("%s\n",__func__);
+ CgxDriverRFInit();
+ return rc;
+}
+
+void gps_chip_power_on(void)
+{
+ printk("%s\n",__func__);
+
+ greeneye_vddsim2_enable(1);
+ gps_clk_init(1);
+
+ //pdn pin pull high
+ CgCpuGpioModeSet(CG_DRIVER_GPIO_GPS_PDN, ECG_CPU_GPIO_OUTPUT);
+ CgCpuGpioSet(CG_DRIVER_GPIO_GPS_PDN);
+ CgCpuDelay(1000);
+
+ //reset
+ CgCpuGpioModeSet(CG_DRIVER_GPIO_GPS_MRSTN, ECG_CPU_GPIO_OUTPUT);
+ CgCpuIPMasterResetClear();
+ msleep(1);
+ CgCpuIPMasterResetOn();
+ msleep(5);
+ CgCpuIPMasterResetClear();
+ msleep(1);
+
+ //gps core reset
+ gps_spi_write_bytes(1, 0Xfc, 0x0);
+ gps_spi_write_bytes(1, 0Xfc, 0x0f);
+ msleep(1);
+ CgxDriverRFPowerUp();
+}
+
+void gps_chip_power_off(void)
+{
+ printk("%s\n",__func__);
+
+ //pdn pin pull low
+ CgCpuGpioModeSet(CG_DRIVER_GPIO_GPS_PDN, ECG_CPU_GPIO_OUTPUT);
+ CgCpuGpioReset(CG_DRIVER_GPIO_GPS_PDN);
+ CgCpuDelay(1000);
+ msleep(1);
+
+ //reset pin pull low
+ CgCpuIPMasterResetOn();
+
+ //spi2 pin pull low
+ gpio_direction_output(CG_DRIVER_GPIO_GPS_SPI_CS, 0);
+ greeneye_vddsim2_enable(0);
+ gps_clk_init(0);
+}
+
+#else
+static TCgReturnCode CgxDriverRFInit(void)
+{
+ u32 value;
+ gps_rf_ops->write_reg(0x0700,0x0001);
+ gps_rf_ops->write_reg(0x004a,0xf417);
+ gps_rf_ops->write_reg(0x076c,0x0721);
+ gps_rf_ops->write_reg(0x0763,0x5141);
+ gps_rf_ops->write_reg(0x0738,0x5400);
+ gps_rf_ops->write_reg(0x0704,0xef00);
+ gps_rf_ops->write_reg(0X077b,0x0102);
+
+ #if 1 /*for 26M TCXO*/
+ gps_rf_ops->write_reg(0X073c,0x08d2);
+ gps_rf_ops->write_reg(0X0702,0x3d61);
+ #else /*for 16M TCXO*/
+ gps_rf_ops->write_reg(0x073c,0x0000);
+ gps_rf_ops->write_reg(0X0702,0x6180);
+ #endif
+
+ /* for IF*/
+ #if 0
+ gps_rf_ops->write_reg(0x075d,0x88e6);
+ gps_rf_ops->write_reg(0x070a,0x7835);
+ #endif
+
+#if 1
+ /*for debug log */
+ gps_rf_ops->read_reg(0x004a,&value);
+ printk("0x004af417 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x076c,&value);
+ printk("0x076c0721 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x0763,&value);
+ printk("0x07635141 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x0738,&value);
+ printk("0x07385400 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x0704,&value);
+ printk("0x0704ef00 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0X077b,&value);
+ printk("0x077b0102 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x0700,&value);
+ printk("0x07000001 value: %x\n", value);
+
+ #if 1 /*for 26M TCXO*/
+ gps_rf_ops->read_reg(0X073c,&value);
+ printk("0x073c08d2 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0X0702,&value);
+ printk("0x07023d61 value: %x\n", value);
+ #else /*for 16M TCXO*/
+ gps_rf_ops->read_reg(0x073c,&value);
+ printk("0x073c0000 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0X0702,&value);
+ printk("0x07026180 value: %x\n", value);
+ #endif
+
+ /* for IF*/
+ #if 0
+ gps_rf_ops->read_reg(0x075d,&value);
+ printk("0x075d88e6 value: %x\n", value);
+
+ gps_rf_ops->read_reg(0x070a,&value);
+ printk("0x070a7835 value: %x\n", value);
+ #endif
+#endif
+
+ return 0;
+
+}
+
+void gps_gpio_request(void)
+{
+ int ret;
+ ret = gpio_request (SPRD_GPS_LNA_EN, "gps_lna");
+ if (ret){
+ printk ("GPS_LNE request err: %d\n", SPRD_GPS_LNA_EN);
+ }
+}
+
+static void gps_lna_enable(void)
+{
+ gpio_direction_output(SPRD_GPS_LNA_EN,1);
+}
+
+static void gps_lna_disable(void)
+{
+ gpio_direction_output(SPRD_GPS_LNA_EN,0);
+}
+
+static void gps_reg_init(void)
+{
+#ifdef CONFIG_ARCH_SCX30G
+ /*GPS Clock Select to CLK_SINE0*/
+ sci_glb_clr(SPRD_GPS_CLK_SEL,BIT_3);
+
+ /*Disable 26M Clock Gating*/
+ sci_glb_clr(SPRD_GPS_CLK_AUTO_GATING,BIT_0);
+#endif
+}
+
+TCgReturnCode CgxDriverRFPowerDown(void)
+{
+ //DBG_FUNC_NAME("CgxDriverRFPowerDown")
+ TCgReturnCode rc = ECgOk;
+
+ printk("%s\n",__func__);
+
+ gps_rf_ops->mspi_enable();
+ gps_rf_ops->write_reg(0x0700,0x0000);
+ gps_lna_disable();
+ gps_rf_ops->mspi_disable();
+ return rc;
+}
+
+TCgReturnCode CgxDriverRFPowerUp(void)
+{
+ //DBG_FUNC_NAME("CgxDriverRFPowerDown")
+ TCgReturnCode rc = ECgOk;
+
+ printk("%s\n",__func__);
+ gps_rf_ops->mspi_enable();
+ gps_lna_enable();
+ gps_reg_init();
+ CgxDriverRFInit();
+ gps_rf_ops->mspi_disable();
+ return rc;
+}
+
+void gps_chip_power_on(void)
+{
+ printk("%s\n",__func__);
+#ifdef CONFIG_ARCH_SCX20
+ rf2351_vddwpa_ctrl_power_enable(1);
+#endif
+ //enable gps sysclk
+ CGCoreSclkEnable(1);
+
+ //gps core reset
+ CgxCpuWriteMemory((U32)CG_DRIVER_CGCORE_BASE_VA, 0xfc,0xf);
+ CgxDriverRFPowerUp();
+}
+
+void gps_chip_power_off(void)
+{
+ printk("%s\n",__func__);
+ CgxDriverRFPowerDown();
+
+ //gps core reset
+ CgxCpuWriteMemory((U32)CG_DRIVER_CGCORE_BASE_VA, 0xfc,0x0);
+ CGCoreSclkEnable(0);
+#ifdef CONFIG_ARCH_SCX20
+ rf2351_vddwpa_ctrl_power_enable(0);
+#endif
+}
+#endif
+
+TCgReturnCode CgxDriverTcxoEnable(U32 aEnable)
+{
+ // default implementation assumes direct manipulation of TCXO LDO via a dedicated GPIO pin.
+ // either CG_DRIVER_GPIO_TCXO_ENABLE or CG_DRIVER_GPIO_TCXO_DISABLE should be defined depending
+ // on the LDO control level (active high / active low)
+
+ #if defined(CG_DRIVER_GPIO_TCXO_ENABLE)
+ if (aEnable)
+ CgCpuGpioSet(CG_DRIVER_GPIO_TCXO_ENABLE);
+ else
+ CgCpuGpioReset(CG_DRIVER_GPIO_TCXO_ENABLE);
+ #elif defined(CG_DRIVER_GPIO_TCXO_DISABLE)
+ if (aEnable)
+ CgCpuGpioReset(CG_DRIVER_GPIO_TCXO_DISABLE);
+ else
+ CgCpuGpioSet(CG_DRIVER_GPIO_TCXO_DISABLE);
+ #endif
+
+ return ECgOk;
+}
+
+
+
+TCgReturnCode CgCpuRevision(char *apRevisionCode)
+{
+
+ //sprintf(apRevisionCode,"SPRD_FPGA-R255",0);
+ sprintf(apRevisionCode,"SPRD_FPGA-R255");
+
+ return ECgOk;
+
+}
+
+
+TCgReturnCode CgCpuClockDestroy(void)
+{
+ TCgReturnCode rc = ECgOk;
+ return rc;
+}
+
+TCgReturnCode CgCpuIntrDestroy(void)
+{
+ TCgReturnCode rc = ECgOk;
+ // #if defined(CG_DRIVER_INTR_BASE_PA) && !defined(CG_DRIVER_INTR_BASE_VA)
+// rc = CgCpuVirtualFree((volatile void **)&gpINTR);
+ // #endif
+ return rc;
+}
+
+
+TCgReturnCode CgCpuIPMasterResetClear(void)
+{
+ TCgReturnCode rc = ECgOk;
+ DBG_FUNC_NAME("CgCpuIPMasterResetClear");
+
+ DBGMSG("start");
+ // Set master reset pin to '1' (reset off - device active)
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ CgCpuGpioSet(CG_DRIVER_GPIO_GPS_MRSTN);
+ #else
+ // CgCpuGpioSet(CG_DRIVER_GPIO_GPS_MRSTN);
+ #endif
+
+ return rc;
+}
+
+
+
+
+TCgReturnCode CgCpuIPMasterResetOn(void)
+{
+ TCgReturnCode rc = ECgOk;
+ DBG_FUNC_NAME("CgCpuIPMasterResetOn");
+
+ DBGMSG("start");
+ // Set master reset pin to '0' (reset on - device inactive)
+
+ #ifdef CGCORE_ACCESS_VIA_SPI
+ CgCpuGpioReset(CG_DRIVER_GPIO_GPS_MRSTN);
+ #else
+ //CgCpuGpioReset(CG_DRIVER_GPIO_GPS_MRSTN);
+ #endif
+
+ return rc;
+}
+
+
+TCgReturnCode CgCpuAllocateVa(void)
+{
+ // Nothing to do for SPRD_FPGA
+ return ECgOk;
+}
+
+
diff --git a/drivers/misc/gpsip/cgdriver/platform.h b/drivers/misc/gpsip/cgdriver/platform.h
new file mode 100644
index 00000000..df8d0e81
--- /dev/null
+++ b/drivers/misc/gpsip/cgdriver/platform.h
@@ -0,0 +1,250 @@
+/******************************************************************************
+ * LEGAL NOTICE *
+ * *
+ * USE OF THIS SOFTWARE (including any copy or compiled version thereof) AND *
+ * DOCUMENTATION IS SUBJECT TO THE SOFTWARE LICENSE AND RESTRICTIONS AND THE *
+ * WARRANTY DISLCAIMER SET FORTH IN LEGAL_NOTICE.TXT FILE. IF YOU DO NOT *
+ * FULLY ACCEPT THE TERMS, YOU MAY NOT INSTALL OR OTHERWISE USE THE SOFTWARE *
+ * OR DOCUMENTATION. *
+ * NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS NOTICE, INSTALLING OR *
+ * OTHERISE USING THE SOFTWARE OR DOCUMENTATION INDICATES YOUR ACCEPTANCE OF *
+ * THE LICENSE TERMS AS STATED. *
+ * *
+ ******************************************************************************/
+/* Version: 1.8.9\3686 */
+/* Build : 13 */
+/* Date : 12/08/2012 */
+
+/**
+ \file
+ \brief SPRD_FPGA specific defines
+
+ \defgroup CGX_DRIVER_PLATFORM_ANDROID SPRD_FPGA/Android platform specific defines
+ \{
+ The following values are specific to the SPRD_FPGA / Android implementation.
+ For other platforms, please select appropriate values.
+
+ */
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+///
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include<soc/sprd/system.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <linux/dma-mapping.h>
+
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/sci.h>
+#ifndef CGCORE_ACCESS_VIA_SPI
+#include <linux/sprd_2351.h>
+#endif
+#include "CgxDriverCore.h"
+
+
+#define CGX_PLATFORM_NAME "SPRD_FPGA_FPGA"
+
+/*************************************************************************************/
+
+/*New add by paul*/
+
+#define NUMBER_1K (1 *1024)
+#define NUMBER_16K (16*1024)
+#define NUMBER_64K (64*1024)
+
+
+#define MAX_DMA_CHUNK_SIZE (0x80000) // 512K
+#define MAX_DMA_TRANSFER_TASKS (64) /**< Maximum number of DMA tasks */
+
+/**
+ CGsnap IP physical address
+ \attention Need to be ported
+ \ingroup SPRD_FPGA_cpu_specific
+
+ TODO: modify by sprd
+
+*/
+#define CG_DRIVER_CGCORE_BASE_PA (0x21C00000) /* cg ip base */
+#define CG_DRIVER_GPIO_BASE_PA (0x8A000000)
+#define CG_DRIVER_INTR_BASE_PA (0xFC000000)
+#define CG_DRIVER_CLK_BASE_PA (0xFC802000)
+
+
+#ifdef CGCORE_ACCESS_VIA_SPI
+#define CG_DRIVER_GPIO_GPS_MRSTN (90)
+#ifdef CONFIG_ARCH_SCX35LT8
+#define CG_DRIVER_GPIO_GPS_PDN (142)
+#else
+#define CG_DRIVER_GPIO_GPS_PDN (76)
+#endif
+#define CG_DRIVER_GPIO_GPS_INT (96)
+#define CG_DRIVER_GPIO_GPS_SPI_CS (52)
+#else
+#ifdef CONFIG_OF
+struct gps_2351_addr
+{
+ u32 gps_base;
+ u32 ahb_base;
+ u32 irq_num;
+ u32 lna_gpio;
+ #ifdef CONFIG_ARCH_SCX30G
+ u32 pmu_base;
+ #endif
+};
+
+extern struct gps_2351_addr gps_2351;
+extern u32 gps_get_core_base(void);
+extern u32 gps_get_ahb_base(void);
+extern u32 gps_get_irq(void);
+extern u32 gps_get_lna_gpio(void);
+
+
+#define CG_DRIVER_CGCORE_BASE_VA gps_get_core_base()
+#define CG_DRIVER_SCLK_VA gps_get_ahb_base()
+#define SPRD_GPS_INT gps_get_irq()
+#define SPRD_GPS_LNA_EN gps_get_lna_gpio()
+
+#ifdef CONFIG_ARCH_SCX30G
+extern u32 gps_get_pmu_base(void);
+
+#define SPRD_GPS_CLK_SINEX gps_get_pmu_base()
+#define SPRD_GPS_CLK_AUTO_GATING (SPRD_GPS_CLK_SINEX+0x114)
+#define SPRD_GPS_CLK_SEL (SPRD_GPS_CLK_SINEX+0x134)
+#endif
+
+#else
+
+/** Virtual base address for CGsnap registers */
+#define CG_DRIVER_CGCORE_BASE_VA SPRD_GPS_BASE
+
+#ifdef CONFIG_ARCH_SCX30G
+#define SPRD_GPS_CLK_SINEX SPRD_PMU_BASE
+#define SPRD_GPS_CLK_AUTO_GATING (SPRD_GPS_CLK_SINEX+0x114)
+#define SPRD_GPS_CLK_SEL (SPRD_GPS_CLK_SINEX+0x134)
+#endif
+
+/** Virtual base address for CGsnap sclk */
+#define CG_DRIVER_SCLK_VA SPRD_AHB_BASE
+#define SPRD_GPS_INT IRQ_GPS_INT
+
+#if defined(CONFIG_DOLPHIN_CHIP_2351)
+#define SPRD_GPS_LNA_EN (35)
+#elif defined(CONFIG_SHARK_CHIP_2351)
+#define SPRD_GPS_LNA_EN (50)
+#endif
+#endif
+#endif
+
+
+/** \} Memory Mapping */
+
+
+/**
+
+
+ \name Interrupt Codes
+ \{
+ */
+
+
+/** DMA interrupt event name
+
+ For platforms where the interrupt is handled by BSP code, this is the event
+ name to be used by the driver.
+ in all other cases, this should be defined 'NULL'
+ */
+#define CGX_DRIVE_DMA_INT_EVENT_NAME (NULL)
+
+/** DMA completion exported sync-object name
+
+ For platforms where the DMA interrupt is handled by BSP code/driver, this is the sync-object name
+ exported by the operating system, that can be waited on, and that issues a signal when DMA
+ x-fer is complete.
+ in all other cases, this should not be defined
+*/
+
+/*modify bu paul for compile-----debug*/
+//#define gDMACompletion NULL
+// struct completion gDMACompletion;
+//#define CGX_DRIVE_DMA_INT_GLOBAL_SYNC_OBJECT (gDMACompletion)
+
+
+/** GPS interrupt event name
+ For platforms where the interrupt is handled by BSP code, this is the event
+ name to be used by the driver.
+ in all other cases, this should be defined 'NULL'
+ */
+#define CGX_DRIVE_GPS_INT_EVENT_NAME (NULL)
+
+/** \} Interrupt codes */
+
+/**
+
+
+ \name DMA Control
+ \{
+*/
+
+
+#define CG_DRIVER_DMA_CHANNEL_READ (0) /**< DMA channel to use for snap transfer */
+
+
+
+/** \} DMA Control */
+
+
+/**
+
+
+ \name GPIO mapping
+ \{
+ */
+
+
+
+
+/** GPIO assigned to RF front-end configuration data.
+ This line is used to configure the ACLYS-L, (send and receive data in I2C like protocol)
+ a.k.a. SER2
+ \attention Input & Output
+ */
+#define CG_DRIVER_GPIO_RF_DATA (0 + 3)
+
+/** GPIO assigned to RF front-end configuration clock.
+ This line is used to configure the ACLYS-L, (clocking the I2C like protocol)
+ a.k.a. SER1
+ \attention Output only
+ */
+#define CG_DRIVER_GPIO_RF_CLK (0 + 2)
+
+
+/** GPIO assigned to RF front-end power down.
+ This line is used to control RF FrontEnd power mode (i.e., select between power on and power down modes)
+ This value is used on if CG_DRIVER_CGCORE_CONTROLS_RF_PD is FALSE
+ \attention Output only
+ */
+#define CG_DRIVER_GPIO_RF_PD (0 + 0)
+#define CG_DRIVER_CG_CORE_CONTROLS_RF_PD (TRUE)
+#define RF_POWER_UP_VAL (0) // ACLYS RF requires '0' for PU
+
+#define CGX5000_DR (0 + 18)
+
+#ifndef CGCORE_ACCESS_VIA_SPI
+extern struct sprd_2351_interface *gps_rf_ops;
+#endif
+
+
+//#define CGX5000_INT (CG_CPU_GPIO_GROUP_D + 9)
+
+/** \} GPIO mapping */
+
+
+/** \} */
+
+#endif /* PLATFORM_H */