RK29 Mobile SDK:mtk23 modem support
authorphc <phc@rk29>
Sun, 3 Apr 2011 09:21:53 +0000 (17:21 +0800)
committerphc <phc@rk29>
Sun, 3 Apr 2011 09:21:53 +0000 (17:21 +0800)
arch/arm/configs/rk29_phonesdk_defconfig
arch/arm/mach-rk29/board-rk29-phonesdk.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/mtk23d.c [new file with mode: 0644]
include/linux/mtk23d.h [new file with mode: 0644]

index fd58e3f975093041cc496e66114447deb7a628e1..e30d6d5d4c343386183b540e995cc9b3eee0f242 100755 (executable)
@@ -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
 
 #
index 08f0d1afb0930b9af58a5d3a7feef91fd6ef370b..adb72812b568d52762a3206b7b6aae27844bdf2c 100755 (executable)
@@ -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 //中æ\96­è\84?#define DEBOUNCE_REPTIME  3
 
 static struct xpt2046_platform_data xpt2046_info = {
        .model                  = 2046,
index 02badf554d043810746bcf93e7255b5bf1c806c7..82d8929dc132d7fcf88e6c411d9858b4c72cd62d 100644 (file)
@@ -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"
index c545d1c456b4de46a90b13891fc5b0e8517fc535..986eb9a5f1cff43f85a3403ad02b14790205536a 100644 (file)
@@ -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 (file)
index 0000000..4bc69eb
--- /dev/null
@@ -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 (file)
index 0000000..84f0350
--- /dev/null
@@ -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"