From: phc <phc@rk29>
Date: Sun, 3 Apr 2011 09:21:53 +0000 (+0800)
Subject: RK29 Mobile SDK:mtk23 modem support
X-Git-Tag: firefly_0821_release~10564
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=49f53f59d84d237a58e3ab8617a917f1d1d7bee6;p=firefly-linux-kernel-4.4.55.git

RK29 Mobile SDK:mtk23 modem support
---

diff --git a/arch/arm/configs/rk29_phonesdk_defconfig b/arch/arm/configs/rk29_phonesdk_defconfig
index fd58e3f97509..e30d6d5d4c34 100755
--- a/arch/arm/configs/rk29_phonesdk_defconfig
+++ b/arch/arm/configs/rk29_phonesdk_defconfig
@@ -606,6 +606,7 @@ CONFIG_ANDROID_PMEM=y
 CONFIG_APANIC=y
 CONFIG_APANIC_PLABEL="kpanic"
 # CONFIG_STE is not set
+CONFIG_MTK23D=y
 # CONFIG_C2PORT is not set
 
 #
diff --git a/arch/arm/mach-rk29/board-rk29-phonesdk.c b/arch/arm/mach-rk29/board-rk29-phonesdk.c
index 08f0d1afb093..adb72812b568 100755
--- a/arch/arm/mach-rk29/board-rk29-phonesdk.c
+++ b/arch/arm/mach-rk29/board-rk29-phonesdk.c
@@ -57,6 +57,9 @@
 
 #include "devices.h"
 
+#if defined(CONFIG_MTK23D)
+#include <linux/mtk23d.h>
+#endif
 
 
 /*set touchscreen different type header*/
@@ -2105,6 +2108,26 @@ static struct platform_device rk29_device_pwm_regulator = {
 
 #endif
 
+
+#if defined(CONFIG_MTK23D)
+struct rk2818_23d_data rk2818_23d_info = {
+	.bp_power = RK29_PIN0_PA0,
+	//.bp_reset = TCA6424_P11,
+	//.bp_statue = RK2818_PIN_PH7,//input  high bp sleep;
+	//.ap_statue = RK2818_PIN_PA4,//output high ap sleep;
+	//.ap_bp_wakeup = RK2818_PIN_PF5, //output AP wake up BP used rising edge;
+	//.bp_ap_wakeup = RK2818_PIN_PE0,//input BP wake up AP
+};
+struct platform_device rk2818_device_mtk23d = {	
+        .name = "mtk23d",	
+    	.id = -1,	
+	.dev		= {
+		.platform_data = &rk2818_23d_info,
+	}    	
+    };
+#endif
+
+
 /*****************************************************************************************
  * SDMMC devices
 *****************************************************************************************/
@@ -2529,6 +2552,10 @@ static struct platform_device *devices[] __initdata = {
         &rk29sdk_rfkill,
 #endif
 
+#if defined(CONFIG_MTK23D)
+	&rk2818_device_mtk23d,
+#endif
+
 #ifdef CONFIG_MTD_NAND_RK29
 	&rk29_device_nand,
 #endif
@@ -2733,8 +2760,7 @@ struct rk29xx_spi_platform_data rk29xx_spi1_platdata = {
  * author: hhb@rock-chips.com
  *****************************************************************************************/
 #if defined(CONFIG_TOUCHSCREEN_XPT2046_NORMAL_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_TSLIB_SPI)
-#define XPT2046_GPIO_INT           RK29_PIN4_PD5 //中断脚
-#define DEBOUNCE_REPTIME  3
+#define XPT2046_GPIO_INT           RK29_PIN4_PD5 //中断è„?#define DEBOUNCE_REPTIME  3
 
 static struct xpt2046_platform_data xpt2046_info = {
 	.model			= 2046,
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 02badf554d04..82d8929dc132 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -288,6 +288,10 @@ config STE
 	bool "STE modem control driver"
 	default n
 	
+config MTK23D
+	bool "MTK6223D modem control driver"
+	default n	
+	
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c545d1c456b4..986eb9a5f1cf 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -28,6 +28,7 @@ obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_WL127X_RFKILL)	+= wl127x-rfkill.o
 obj-$(CONFIG_APANIC)		+= apanic.o
+obj-$(CONFIG_MTK23D)		+= mtk23d.o
 obj-$(CONFIG_STE)		+= ste.o
 obj-$(CONFIG_RK29_SUPPORT_MODEM)        += rk29_modem/
 obj-$(CONFIG_GPS_GNS7560)			+=	gps/
diff --git a/drivers/misc/mtk23d.c b/drivers/misc/mtk23d.c
new file mode 100644
index 000000000000..4bc69ebfe60a
--- /dev/null
+++ b/drivers/misc/mtk23d.c
@@ -0,0 +1,344 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/circ_buf.h>
+#include <linux/interrupt.h>
+#include <linux/miscdevice.h>
+#include <mach/iomux.h>
+#include <mach/gpio.h>
+//#include <mach/spi_fpga.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+//#include <linux/android_power.h>
+//#include <asm/arch/gpio_extend.h>
+#include <linux/workqueue.h>
+#include <linux/mtk23d.h>
+
+MODULE_LICENSE("GPL");
+
+#define DEBUG
+#ifdef DEBUG
+#define MODEMDBG(x...) printk(x)
+#else
+#define MODEMDBG(fmt,argss...)
+#endif
+
+//#define BP_POW_EN	TCA6424_P02
+//#define BP_STATUS    RK2818_PIN_PH7    //input  high bp sleep
+//#define AP_STATUS    RK2818_PIN_PA4    //output high ap sleep
+
+//#define BP_RESET	TCA6424_P11	//Ryan
+
+//#define AP_BP_WAKEUP  RK2818_PIN_PF5   //output AP wake up BP used rising edge
+//#define BP_AP_WAKEUP  RK2818_PIN_PE0	//input BP wake up AP
+
+#define SLEEP 1
+#define READY 0
+
+//struct modem_dev *mt6223d_data = NULL;
+struct rk2818_23d_data *gpdata = NULL;
+
+static int  get_bp_statue(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	
+	if(gpio_get_value(pdata->bp_statue))
+		return SLEEP;
+	else
+		return READY;
+}
+static void ap_sleep(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	
+	MODEMDBG("ap sleep!\n");
+	gpio_set_value(pdata->ap_statue,GPIO_HIGH);
+}
+static void ap_wakeup(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	
+	MODEMDBG("ap wakeup!\n");
+	gpio_set_value(pdata->ap_statue,GPIO_LOW);
+}
+/* */
+static void ap_wakeup_bp(struct platform_device *pdev, int wake)//low to wakeup bp
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+        struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
+	MODEMDBG("ap_wakeup_bp\n");
+
+	gpio_set_value(pdata->ap_bp_wakeup, wake);  // phc
+	//gpio_set_value(RK2818_PIN_PF5, wake);
+}
+
+static void bpwakeup_work_func_work(struct work_struct *work)
+{
+	struct modem_dev *bdata = container_of(work, struct modem_dev, work);
+	
+	MODEMDBG("%s\n", __FUNCTION__);
+	
+}
+/*  */
+static irqreturn_t  bpwakeup_work_func(int irq, void *data)
+{
+	struct modem_dev *mt6223d_data = (struct modem_dev *)data;
+	
+   	MODEMDBG("bpwakeup_work_func\n");
+	schedule_work(&mt6223d_data->work);
+	return IRQ_HANDLED;
+}
+static irqreturn_t  bp_apwakeup_work_func(int irq, void *data)
+{
+	//struct modem_dev *dev = &mtk23d_misc;
+	
+   	MODEMDBG("bp_apwakeup_work_func\n");
+	//wake_up_interruptible(&dev->wakeup);
+	return IRQ_HANDLED;
+}
+
+static int mtk23d_open(struct inode *inode, struct file *file)
+{
+	struct rk2818_23d_data *pdata = gpdata;
+	//struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
+	struct platform_data *pdev = container_of(pdata, struct device, platform_data);
+
+	MODEMDBG("modem_open\n");
+
+	int ret = 0;
+
+#if 0 //phc
+	gpio_direction_output(pdata->bp_power, GPIO_HIGH);
+	
+	gpio_direction_input(pdata->bp_statue);
+	
+	rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 0);
+	gpio_direction_output(pdata->ap_statue, GPIO_LOW);
+	
+	rk2818_mux_api_set(GPIOF5_APWM3_DPWM3_NAME,0);
+	gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);
+	mdelay(100);
+	//rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);
+	gpio_direction_output(pdata->bp_reset, GPIO_LOW);
+	mdelay(100);
+	gpio_set_value(pdata->bp_reset, GPIO_HIGH);
+	
+	mdelay(2000);
+	gpio_set_value(pdata->bp_power, GPIO_LOW);
+	
+	gpio_set_value(pdata->ap_bp_wakeup, GPIO_HIGH);
+	
+	//INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
+	device_init_wakeup(&pdev, 1);
+#endif
+  gpio_direction_output(pdata->bp_power, GPIO_HIGH);
+  mdelay(2000);
+  gpio_set_value(pdata->bp_power, GPIO_LOW);
+
+	return 0;
+}
+
+static int mtk23d_release(struct inode *inode, struct file *file)
+{
+	MODEMDBG("mtk23d_release\n");
+
+	//gpio_free(pdata->bp_power);
+	return 0;
+}
+
+static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
+{
+	MODEMDBG("mtk23d_ioctl\n");
+	return 0;
+}
+
+static struct file_operations mtk23d_fops = {
+	.owner = THIS_MODULE,
+	.open = mtk23d_open,
+	.release = mtk23d_release,
+	.ioctl = mtk23d_ioctl
+};
+
+static struct miscdevice mtk23d_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = MODEM_NAME,
+	.fops = &mtk23d_fops
+};
+
+static int mtk23d_probe(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
+	struct modem_dev *mt6223d_data = NULL;
+	int result, irq = 0;	
+	
+	MODEMDBG("mtk23d_probe\n");
+
+	mt6223d_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
+	if(NULL == mt6223d_data)
+	{
+		printk("failed to request mt6223d_data\n");
+		goto err6;
+	}
+	platform_set_drvdata(pdev, mt6223d_data);
+
+#if 0 //phc
+	result = gpio_request(pdata->bp_statue, "mtk23d");
+	if (result) {
+		printk("failed to request BP_STATUS gpio\n");
+		goto err5;
+	}
+	
+	result = gpio_request(pdata->ap_statue, "mtk23d");
+	if (result) {
+		printk("failed to request AP_STATUS gpio\n");
+		goto err4;
+	}	
+	
+	result = gpio_request(pdata->ap_bp_wakeup, "mtk23d");
+	if (result) {
+		printk("failed to request AP_BP_WAKEUP gpio\n");
+		goto err3;
+	}	
+	result = gpio_request(pdata->bp_reset, "mtk23d");
+	if (result) {
+		printk("failed to request BP_RESET gpio\n");
+		goto err2;
+	}		
+#endif		// phc
+	
+	result = gpio_request(pdata->bp_power, "mtk23d");
+	if (result) {
+		printk("failed to request BP_POW_EN gpio\n");
+		goto err1;
+	}
+
+	
+#if 0
+	gpio_direction_output(pdata->bp_power, GPIO_HIGH);	
+	
+	gpio_direction_input(pdata->bp_statue);
+
+	rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 0);
+	gpio_direction_output(pdata->ap_statue, GPIO_LOW);
+
+	rk2818_mux_api_set(GPIOF5_APWM3_DPWM3_NAME,0);
+	gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);
+	mdelay(100);
+	
+	//rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);	
+	gpio_direction_output(pdata->bp_reset, GPIO_LOW);
+	mdelay(100);	
+	gpio_set_value(pdata->bp_reset, GPIO_HIGH);
+
+	mdelay(2000);
+	gpio_set_value(pdata->bp_power, GPIO_LOW);
+
+	gpio_set_value(pdata->ap_bp_wakeup, GPIO_HIGH);
+
+	//INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
+
+	device_init_wakeup(&pdev->dev, 1);
+#endif
+	INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
+
+	result = misc_register(&mtk23d_misc);
+	if(result)
+	{
+		MODEMDBG("misc_register err\n");
+	}
+	MODEMDBG("mtk23d_probe ok\n");
+	return result;
+err0:
+	cancel_work_sync(&mt6223d_data->work);
+	gpio_free(pdata->bp_ap_wakeup);
+err1:
+	gpio_free(pdata->bp_power);
+err2:
+	gpio_free(pdata->bp_reset);
+err3:
+	gpio_free(pdata->ap_bp_wakeup);
+err4:
+	gpio_free(pdata->ap_statue);
+err5:
+	gpio_free(pdata->bp_statue);
+err6:
+	kfree(mt6223d_data);
+ret:
+	return result;
+}
+
+int mtk23d_suspend(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	//int irq = gpio_to_irq(pdata->bp_ap_wakeup);
+	
+	MODEMDBG("%s \n", __FUNCTION__);
+	//enable_irq_wake(irq);
+	ap_sleep(pdev);
+	ap_wakeup_bp(pdev, 0);
+	return 0;
+}
+
+int mtk23d_resume(struct platform_device *pdev)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	//int irq = gpio_to_irq(pdata->bp_ap_wakeup);
+	
+	MODEMDBG("%s \n", __FUNCTION__);
+	//disable_irq_wake(irq);
+	ap_wakeup(pdev);
+	ap_wakeup_bp(pdev, 1);
+	return 0;
+}
+
+void mtk23d_shutdown(struct platform_device *pdev, pm_message_t state)
+{
+	struct rk2818_23d_data *pdata = pdev->dev.platform_data;
+	struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
+	
+	MODEMDBG("%s \n", __FUNCTION__);
+
+	cancel_work_sync(&mt6223d_data->work);
+	gpio_free(pdata->bp_ap_wakeup);
+	gpio_free(pdata->bp_power);
+	gpio_free(pdata->bp_reset);
+	gpio_free(pdata->ap_bp_wakeup);
+	gpio_free(pdata->ap_statue);
+	gpio_free(pdata->bp_statue);
+	kfree(mt6223d_data);
+}
+
+static struct platform_driver mtk23d_driver = {
+	.probe	= mtk23d_probe,
+	.shutdown	= mtk23d_shutdown,
+	.suspend  	= mtk23d_suspend,
+	.resume		= mtk23d_resume,
+	.driver	= {
+		.name	= "mtk23d",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init mtk23d_init(void)
+{
+	MODEMDBG("mtk23d_init ret=%d\n");
+	return platform_driver_register(&mtk23d_driver);
+}
+
+static void __exit mtk23d_exit(void)
+{
+	MODEMDBG("mtk23d_exit\n");
+	platform_driver_unregister(&mtk23d_driver);
+}
+
+module_init(mtk23d_init);
+//late_initcall_sync(mtk23d_init);
+module_exit(mtk23d_exit);
diff --git a/include/linux/mtk23d.h b/include/linux/mtk23d.h
new file mode 100644
index 000000000000..84f0350b3e23
--- /dev/null
+++ b/include/linux/mtk23d.h
@@ -0,0 +1,22 @@
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/miscdevice.h>
+
+struct modem_dev
+{
+	const char *name;
+	struct miscdevice miscdev;
+	struct work_struct work;
+};
+
+/* 耳机数据结构体 */
+struct rk2818_23d_data {
+	unsigned int bp_power;
+	unsigned int bp_reset;
+	unsigned int bp_statue;
+	unsigned int ap_statue;
+	unsigned int ap_bp_wakeup;
+	unsigned int bp_ap_wakeup;
+};
+
+#define MODEM_NAME "mtk23d"