[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/kernel/modules/connectivity/gps_driver/gps_emi.c b/src/kernel/modules/connectivity/gps_driver/gps_emi.c
new file mode 100644
index 0000000..a0c14ec
--- /dev/null
+++ b/src/kernel/modules/connectivity/gps_driver/gps_emi.c
@@ -0,0 +1,394 @@
+/*
+ * Implementation of the GPS EMI driver.
+ *
+ * Copyright (C) 2014 Mediatek
+ * Authors:
+ * Heiping <Heiping.Lei@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/******************************************************************************
+ * Dependency
+ ******************************************************************************/
+#ifdef CONFIG_MTK_GPS_EMI
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/printk.h>
+#include <linux/version.h>
+#include <asm/memblock.h>
+#include <mach/emi_mpu.h>
+#include "gps.h"
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt
+
+/******************************************************************************
+ * Definition
+ ******************************************************************************/
+/* device name and major number */
+#define GPSEMI_DEVNAME "gps_emi"
+#define IOCTL_MNL_IMAGE_FILE_TO_MEM 1
+#define IOCTL_MNL_NVRAM_FILE_TO_MEM 2
+#define IOCTL_MNL_NVRAM_MEM_TO_FILE 3
+
+/******************************************************************************
+ * Debug configuration
+ ******************************************************************************/
+#define GPS_DBG_NONE(fmt, arg...) do {} while (0)
+#define GPS_DBG pr_err
+#define GPS_TRC GPS_DBG_NONE
+#define GPS_VER pr_err
+#define GPS_ERR pr_err
+/******************************************************************************
+ * structure & enumeration
+ ******************************************************************************/
+/*---------------------------------------------------------------------------*/
+struct gps_emi_dev {
+ struct class *cls;
+ struct device *dev;
+ dev_t devno;
+ struct cdev chdev;
+};
+/*typedef unsigned char UINT8, *PUINT8, **PPUINT8;*/
+
+/******************************************************************************
+ * local variables
+ ******************************************************************************/
+phys_addr_t gGpsEmiPhyBase;
+UINT8 __iomem *pGpsEmibaseaddr;
+struct gps_emi_dev *devobj;
+#define EMI_MPU_PROTECTION_IS_READY 1
+
+void mtk_wcn_consys_gps_memory_reserve(void)
+{
+#if 0
+#ifdef MTK_WCN_ARM64
+ gGpsEmiPhyBase = arm64_memblock_steal(SZ_1M, SZ_1M);
+#else
+ gGpsEmiPhyBase = arm_memblock_steal(SZ_1M, SZ_1M);
+#endif
+#else
+ gGpsEmiPhyBase = gConEmiPhyBase + SZ_1M;
+
+#endif
+ if (gGpsEmiPhyBase)
+ GPS_DBG("memblock done: 0x%zx\n", (size_t)gGpsEmiPhyBase);
+ else
+ GPS_DBG("memblock fail\n");
+}
+INT32 mtk_wcn_consys_gps_emi_init(void)
+{
+ INT32 iRet = -1;
+
+ mtk_wcn_consys_gps_memory_reserve();
+ if (gGpsEmiPhyBase) {
+ #if CONSYS_EMI_MPU_SETTING
+ /*set MPU for EMI share Memory*/
+ GPS_DBG("setting MPU for EMI share memory\n");
+ #if EMI_MPU_PROTECTION_IS_READY
+ emi_mpu_set_region_protection(gGpsEmiPhyBase,
+ gGpsEmiPhyBase + SZ_1M - 1,
+ 20,
+ SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
+ FORBIDDEN, NO_PROTECTION));
+ #endif
+
+ #endif
+ GPS_DBG("get consys start phy address(0x%zx)\n",
+ (size_t)gGpsEmiPhyBase);
+ #if 0
+ /*consys to ap emi remapping register:10001310,
+ *cal remapping address
+ */
+ addrPhy = (gGpsEmiPhyBase & 0xFFF00000) >> 20;
+
+ /*enable consys to ap emi remapping bit12*/
+ addrPhy -= 0x400;/*Gavin ??*/
+ addrPhy = addrPhy | 0x1000;
+
+ CONSYS_REG_WRITE(conn_reg.topckgen_base +
+ CONSYS_EMI_MAPPING_OFFSET, CONSYS_REG_READ
+ (conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)
+ | addrPhy);
+
+ GPS_DBG("GPS_EMI_MAPPING dump(0x%08x)\n",
+ CONSYS_REG_READ(conn_reg.topckgen_base
+ + CONSYS_EMI_MAPPING_OFFSET));
+ #endif
+
+ pGpsEmibaseaddr = ioremap_nocache(gGpsEmiPhyBase, SZ_1M);
+ if (pGpsEmibaseaddr != NULL) {
+ UINT8 *pFullPatchName = "/system/etc/firmware/MNL.bin";
+ firmware *pPatch = NULL;
+
+ GPS_DBG("EMI mapping OK(0x%p)\n", pGpsEmibaseaddr);
+ memset_io(pGpsEmibaseaddr, 0, SZ_1M);
+ if ((pFullPatchName != NULL)
+ && (wmt_dev_patch_get(pFullPatchName, &pPatch,
+ 0/*BCNT_PATCH_BUF_HEADROOM*/) == 0)) {
+ if (pPatch != NULL) {
+ /*get full name patch success*/
+ GPS_DBG("get full patch name(%s) ",
+ pFullPatchName);
+ GPS_DBG("buf(0x%p) ", (pPatch)->data);
+ GPS_DBG("size(%ld)\n", (pPatch)->size);
+ GPS_DBG("AF get patch, pPatch(0x%p)\n",
+ pPatch);
+ }
+ }
+ if (pPatch != NULL) {
+ if ((pPatch)->size <= SZ_1M) {
+ memcpy(pGpsEmibaseaddr,
+ (pPatch)->data, (pPatch)->size);
+ iRet = 1;
+ }
+ }
+ } else {
+ GPS_DBG("EMI mapping fail\n");
+ }
+ } else {
+ GPS_DBG("gps emi memory address gGpsEmiPhyBase invalid\n");
+ }
+ return iRet;
+}
+
+/*---------------------------------------------------------------------------*/
+long gps_emi_unlocked_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+
+ GPS_DBG("cmd (%d),arg(%ld)\n", cmd, arg);
+
+ switch (cmd) {
+ case IOCTL_MNL_IMAGE_FILE_TO_MEM:
+ retval = mtk_wcn_consys_gps_emi_init();
+ GPS_DBG("IOCTL_MNL_IMAGE_FILE_TO_MEM\n");
+ break;
+
+ case IOCTL_MNL_NVRAM_FILE_TO_MEM:
+ GPS_DBG("IOCTL_MNL_NVRAM_FILE_TO_MEM\n");
+ break;
+
+ case IOCTL_MNL_NVRAM_MEM_TO_FILE:
+ GPS_DBG("IOCTL_MNL_NVRAM_MEM_TO_FILE\n");
+ break;
+
+ default:
+ GPS_DBG("unknown cmd (%d)\n", cmd);
+ retval = 0;
+ break;
+ }
+ return retval;
+
+}
+
+/******************************************************************************/
+/*****************************************************************************/
+static int gps_emi_open(struct inode *inode, struct file *file)
+{
+ GPS_TRC();
+ return nonseekable_open(inode, file);
+}
+
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+static int gps_emi_release(struct inode *inode, struct file *file)
+{
+ GPS_TRC();
+
+ return 0;
+}
+
+/******************************************************************************/
+static ssize_t gps_emi_read(struct file *file,
+ char __user *buf, size_t count, loff_t *ppos)
+{
+ ssize_t ret = 0;
+
+ GPS_TRC();
+
+ return ret;
+}
+/******************************************************************************/
+static ssize_t gps_emi_write(struct file *file,
+ const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ ssize_t ret = 0;
+
+ GPS_TRC();
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+/* Kernel interface */
+static const struct file_operations gps_emi_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = gps_emi_unlocked_ioctl,
+ .open = gps_emi_open,
+ .read = gps_emi_read,
+ .write = gps_emi_write,
+ .release = gps_emi_release,
+};
+
+/*****************************************************************************/
+static int gps_emi_probe(struct platform_device *dev)
+{
+ int ret = 0, err = 0;
+
+ devobj = kzalloc(sizeof(*devobj), GFP_KERNEL);
+ if (devobj == NULL) {
+ err = -ENOMEM;
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ GPS_DBG("Registering chardev\n");
+ ret = alloc_chrdev_region(&devobj->devno, 0, 1, GPSEMI_DEVNAME);
+ if (ret) {
+ GPS_ERR("alloc_chrdev_region fail: %d\n", ret);
+ kfree(devobj);
+ err = -ENOMEM;
+ goto err_out;
+ } else {
+ GPS_DBG("major: %d, minor: %d\n",
+ MAJOR(devobj->devno), MINOR(devobj->devno));
+ }
+ cdev_init(&devobj->chdev, &gps_emi_fops);
+ devobj->chdev.owner = THIS_MODULE;
+ err = cdev_add(&devobj->chdev, devobj->devno, 1);
+ if (err) {
+ GPS_ERR("cdev_add fail: %d\n", err);
+ kfree(devobj);
+ goto err_out;
+ }
+ devobj->cls = class_create(THIS_MODULE, "gpsemi");
+ if (IS_ERR(devobj->cls)) {
+ GPS_ERR("Unable to create class, err = %d\n",
+ (int)PTR_ERR(devobj->cls));
+ kfree(devobj);
+ goto err_out;
+ }
+ devobj->dev = device_create(devobj->cls, NULL,
+ devobj->devno, devobj, "gps_emi");
+
+ GPS_DBG("Done\n");
+ return 0;
+
+err_out:
+ if (err == 0)
+ cdev_del(&devobj->chdev);
+ if (ret == 0)
+ unregister_chrdev_region(devobj->devno, 1);
+ return -1;
+}
+
+/*****************************************************************************/
+static int gps_emi_remove(struct platform_device *dev)
+{
+ if (!devobj) {
+ GPS_ERR("null pointer: %p\n", devobj);
+ return -1;
+ }
+
+ GPS_DBG("Unregistering chardev\n");
+ cdev_del(&devobj->chdev);
+ unregister_chrdev_region(devobj->devno, 1);
+ device_destroy(devobj->cls, devobj->devno);
+ class_destroy(devobj->cls);
+ kfree(devobj);
+ GPS_DBG("Done\n");
+ return 0;
+}
+
+/*****************************************************************************/
+#ifdef CONFIG_PM
+/*****************************************************************************/
+static int gps_emi_suspend(struct platform_device *dev, pm_message_t state)
+{
+ GPS_DBG("dev = %p, event = %u,", dev, state.event);
+ if (state.event == PM_EVENT_SUSPEND)
+ GPS_DBG("Receive PM_EVENT_SUSPEND!!\n");
+ return 0;
+}
+
+/*****************************************************************************/
+static int gps_emi_resume(struct platform_device *dev)
+{
+ GPS_DBG("");
+ return 0;
+}
+
+/*****************************************************************************/
+#endif /* CONFIG_PM */
+/*****************************************************************************/
+#ifdef CONFIG_OF
+static const struct of_device_id apgps_of_ids[] = {
+ { .compatible = "mediatek,gps_emi-v1", },
+ {}
+};
+#endif
+static struct platform_driver gps_emi_driver = {
+ .probe = gps_emi_probe,
+ .remove = gps_emi_remove,
+#if defined(CONFIG_PM)
+ .suspend = gps_emi_suspend,
+ .resume = gps_emi_resume,
+#endif
+ .driver = {
+ .name = GPSEMI_DEVNAME,
+ .bus = &platform_bus_type,
+#ifdef CONFIG_OF
+ .of_match_table = apgps_of_ids,
+#endif
+ },
+};
+
+/*****************************************************************************/
+static int __init gps_emi_mod_init(void)
+{
+ int ret = 0;
+
+ GPS_TRC();
+
+ ret = platform_driver_register(&gps_emi_driver);
+
+ return ret;
+}
+
+/*****************************************************************************/
+static void __exit gps_emi_mod_exit(void)
+{
+ GPS_TRC();
+ platform_driver_unregister(&gps_emi_driver);
+}
+
+/*****************************************************************************/
+module_init(gps_emi_mod_init);
+module_exit(gps_emi_mod_exit);
+/*****************************************************************************/
+MODULE_AUTHOR("Heiping Lei <Heiping.Lei@mediatek.com>");
+MODULE_DESCRIPTION("GPS EMI Driver");
+MODULE_LICENSE("GPL");
+#endif