新的modem驱动
authorCMY <cmy@rock-chips.com>
Mon, 18 Jul 2011 09:59:11 +0000 (17:59 +0800)
committerCMY <cmy@rock-chips.com>
Mon, 18 Jul 2011 09:59:11 +0000 (17:59 +0800)
drivers/misc/rk29_modem/Kconfig
drivers/misc/rk29_modem/Makefile
drivers/misc/rk29_modem/modem_longcheer_u6300v.c [new file with mode: 0644]
drivers/misc/rk29_modem/modem_rockchip_demo.c [changed mode: 0755->0644]
drivers/misc/rk29_modem/modem_thinkwill_mw100g.c [new file with mode: 0644]
drivers/misc/rk29_modem/rk29_modem.c [changed mode: 0755->0644]
drivers/misc/rk29_modem/rk29_modem.h [changed mode: 0755->0644]

index 70113c1f164b673968a04cd5f2596396c15e8003..9e11339a5bc56b0fd1a765531bf0fe2dbe10181d 100644 (file)
@@ -4,7 +4,7 @@
 
 menuconfig RK29_SUPPORT_MODEM
        tristate "RK29 support Modem"
-       depends on USB11_HOST_EN
+#      depends on USB11_HOST_EN
        ---help---
          Say Y here if you have a support modem
 
@@ -12,35 +12,14 @@ choice
        depends on RK29_SUPPORT_MODEM
        prompt  "Select 3G Modem"
 
- config MODEM_ROCKCHIP_DEMO
   config MODEM_ROCKCHIP_DEMO
        bool "ROCKCHIP_GENERAL_MODEM_DEVICE"
 
-#    config MODEM_ZTE_MG3732
-#        bool "ZTE_MG3732"
+    config MODEM_LONGCHEER_U6300V
+       bool "LONGCHEER_U6300V"
 
-#config MODEM_ZTE_MF210
-#      bool "ZTE_MF210"
-       
-#config MODEM_ZTE_AD3812
-#      bool "ZTE_AD3812"
-
-#config MODEM_THINKWILL_ME800
-#      bool "THINKWILL_ME800"
-
-#config MODEM_HUAWEI_EM660
-#      bool "HUAWEI_EM660"
-       
-#config MODEM_HUAWEI_EM770
-#      bool "HUAWEI_EM770"
-
-#config MODEM_HUAWEI_EM660C
- #        bool "HUAWEI_EM660C"
-
-#config MODEM_ZTE_MU301        
-#      bool "ZTE_MU301"
-
-#config MODEM_TDM_330
-#      bool "TDM_330"
+    config MODEM_THINKWILL_MW100G
+        bool "THINKWILL_MW100G"
 
 endchoice
 
index 6d5c5ad49636ea3d0ace142f1f36591329d213c6..a98c411d53ae6a7a633919ed2e2b986781de1779 100644 (file)
@@ -1,16 +1,5 @@
-obj-$(CONFIG_RK29_SUPPORT_MODEM)              += rk29_modem.o
-
-obj-$(CONFIG_MODEM_ROCKCHIP_DEMO)              +=modem_rockchip_demo.o
-
-obj-$(CONFIG_MODEM_ZTE_MG3732)                 +=modem_zte_mg3732.o
-
-#obj-$(CONFIG_MODEM_ZTE_MF210)                         += modem_zte_mf210.o
-#obj-$(CONFIG_MODEM_ZTE_AD3812)                 += modem_zte_ad3812.o
-#obj-$(CONFIG_MODEM_THINKWILL_ME800)   += modem_thinkwill_me800.o
-#obj-$(CONFIG_MODEM_HUAWEI_EM660)              += modem_huawei_em660.o
-#obj-$(CONFIG_MODEM_HUAWEI_EM770)              += modem_huawei_em770.o
-#obj-$(CONFIG_MODEM_HUAWEI_EM660C)     += modem_huawei_em660c.o
-#obj-$(CONFIG_MODEM_ZTE_MU301)                 += modem_zte_mu301.o
-#obj-$(CONFIG_MODEM_TDM_330)                   += modem_tdm_330.o
-
+obj-$(CONFIG_RK29_SUPPORT_MODEM)                += rk29_modem.o
+obj-$(CONFIG_MODEM_ROCKCHIP_DEMO)              += modem_rockchip_demo.o
+obj-$(CONFIG_MODEM_LONGCHEER_U6300V)           +=modem_longcheer_u6300v.o
+obj-$(CONFIG_MODEM_THINKWILL_MW100G)           +=modem_thinkwill_mw100g.o
 
diff --git a/drivers/misc/rk29_modem/modem_longcheer_u6300v.c b/drivers/misc/rk29_modem/modem_longcheer_u6300v.c
new file mode 100644 (file)
index 0000000..350ae34
--- /dev/null
@@ -0,0 +1,168 @@
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/moduleparam.h>\r
+#include <linux/init.h>\r
+#include <linux/device.h>\r
+#include <linux/errno.h>\r
+#include <linux/types.h>\r
+#include <linux/stat.h>         /* permission constants */\r
+#include <linux/io.h>\r
+#include <linux/vmalloc.h>\r
+#include <asm/io.h>\r
+#include <asm/sizes.h>\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <linux/delay.h>\r
+\r
+#include <linux/wakelock.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/gpio.h>\r
+#include <mach/board.h>\r
+\r
+#include <linux/platform_device.h>\r
+\r
+#include "rk29_modem.h"\r
+\r
+// È·±£²»³öÏÖÖظ´´¦Àíwakeup\r
+static int do_wakeup_handle = 0;\r
+static irqreturn_t u6300v_irq_handler(int irq, void *dev_id);\r
+static int __devinit u6300v_resume(struct platform_device *pdev);\r
+\r
+static struct rk29_io_t u6300v_io_ap_ready = {\r
+    .io_addr    = RK29_PIN3_PC2,\r
+    .enable     = GPIO_LOW,\r
+    .disable    = GPIO_HIGH,\r
+};\r
+\r
+static struct rk29_io_t u6300v_io_power = {\r
+    .io_addr    = RK29_PIN6_PB1,\r
+    .enable     = GPIO_HIGH,\r
+    .disable    = GPIO_LOW,\r
+};\r
+\r
+static struct rk29_irq_t u6300v_irq_bp_wakeup_ap= {\r
+    .irq_addr   = RK29_PIN3_PD7,\r
+    .irq_trigger = IRQF_TRIGGER_FALLING, // Ï½µÑØ´¥·¢\r
+};\r
+\r
+static struct platform_driver u6300v_platform_driver = {\r
+       .driver         = {\r
+               .name           = "longcheer_u6300v",\r
+       },
+       .suspend    = rk29_modem_suspend,\r
+       .resume     = rk29_modem_resume,\r
+};\r
+\r
+static struct rk29_modem_t u6300v_driver = {\r
+    .driver         = &u6300v_platform_driver,\r
+    .modem_power    = &u6300v_io_power,\r
+    .ap_ready       = &u6300v_io_ap_ready,\r
+    .bp_wakeup_ap   = &u6300v_irq_bp_wakeup_ap,\r
+    .status         = MODEM_ENABLE,\r
+    .dev_init       = NULL,\r
+    .dev_uninit     = NULL,\r
+    .irq_handler    = u6300v_irq_handler,\r
+    .suspend        = NULL,\r
+    .resume         = u6300v_resume,\r
+    \r
+    .enable         = NULL,\r
+    .disable        = NULL,\r
+    .sleep          = NULL,\r
+    .wakeup         = NULL,\r
+};\r
+\r
+static void do_test1(struct work_struct *work)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    // ±êÖ¾APÒѾÍÐ÷£¬BB¿ÉÒÔÉϱ¨Êý¾Ý¸øAP\r
+    gpio_direction_output(u6300v_driver.ap_ready->io_addr, u6300v_driver.ap_ready->enable);\r
+}\r
+\r
+static DECLARE_DELAYED_WORK(test1, do_test1);\r
+\r
+static int __devinit u6300v_resume(struct platform_device *pdev)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+/* cmy: Ä¿Ç°ÔÚϵͳ±»»½ÐѺó£¬ÔÚÕâ±ßÉèÖÃAP_RDY£¬µ«ÓÉÓÚͨÐÅÒÀÀµÓÚÆäËüµÄÉ豸Çý¶¯(±ÈÈçUSB»òÕß´®¿Ú)\r
+        ÐèÒªÑÓʱÉèÖÃAP_RDYÐźÅ\r
+        ¸üºÃµÄ×ö·¨ÊÇÔÚËüËùÒÀÀµµÄÉ豸¾ÍÐ÷ºó(»½ÐÑ)£¬ÔÙÉèÖÃAP_RDY¡£×ö·¨Á½ÖÖ:\r
+            1 ½«ÉèÖÃAP_RDYµÄº¯Êý×¢È뵽Ŀ±êÉ豸µÄresumeº¯ÊýÖÐ\r
+            2 ÔÚrk29_modem_resumeÖУ¬µÈ´ýÄ¿±êÉ豸resumeÖ®ºó£¬ÔÙÉèÖÃAP_RDY\r
+ */\r
+    schedule_delayed_work(&test1, 2*HZ);\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+    u6300v Ä£×éµÄ IRQ ´¦Àíº¯Êý£¬¸Ãº¯ÊýÓÉrk29_modemÖеÄIRQ´¦Àíº¯Êýµ÷ÓÃ\r
+ */\r
+static irqreturn_t u6300v_irq_handler(int irq, void *dev_id)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    if( irq == gpio_to_irq(u6300v_driver.bp_wakeup_ap->irq_addr) )\r
+    {\r
+        if( !do_wakeup_handle )\r
+        {\r
+            do_wakeup_handle = 1;\r
+            // µ±½ÓÊÕµ½ bb wakeup ap µÄIRQºó£¬ÉêÇëÒ»¸ö8ÃëµÄsuspendËø£¬Ê±¼äµ½ºó×Ô¶¯ÊÍ·Å\r
+            // ÊÍ·ÅʱÈç¹ûûÓÐÆäËüµÄËø£¬¾Í½«ÔٴιÒÆð.\r
+            wake_lock_timeout(&u6300v_driver.wakelock_bbwakeupap, 8 * HZ);\r
+        } else\r
+            printk("%s: already wakeup\n", __FUNCTION__);\r
+        return IRQ_HANDLED;\r
+    }\r
+    \r
+    return IRQ_NONE;\r
+}\r
+\r
+static int __init u6300v_init(void)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    return rk29_modem_init(&u6300v_driver);\r
+}\r
+\r
+static void __exit u6300v_exit(void)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    rk29_modem_exit();\r
+}\r
+\r
+module_init(u6300v_init);\r
+module_exit(u6300v_exit);\r
+\r
+MODULE_AUTHOR("lintao lintao@rock-chips.com");\r
+MODULE_DESCRIPTION("ROCKCHIP modem driver");\r
+MODULE_LICENSE("GPL");\r
+\r
+#if 0\r
+int test(void)\r
+{\r
+    printk(">>>>>> test \n ");\r
+    int ret = gpio_request(IRQ_BB_WAKEUP_AP, NULL);\r
+    if(ret != 0)\r
+    {\r
+        printk(">>>>>> gpio_request failed! \n ");\r
+        gpio_free(IRQ_BB_WAKEUP_AP);\r
+        return ret;\r
+    }\r
+\r
+//    printk(">>>>>> set GPIOPullUp \n ");\r
+//    gpio_pull_updown(IRQ_BB_WAKEUP_AP, GPIOPullUp);\r
+//    printk(">>>>>> set GPIO_HIGH \n ");\r
+//    gpio_direction_output(IRQ_BB_WAKEUP_AP, GPIO_HIGH);\r
+\r
+//    printk(">>>>>> set GPIO_LOW \n ");\r
+//    gpio_direction_output(IRQ_BB_WAKEUP_AP, GPIO_LOW);\r
+//    msleep(1000);\r
+    \r
+    gpio_free(IRQ_BB_WAKEUP_AP);\r
+\r
+    printk(">>>>>> END \n ");\r
+}\r
+#endif\r
+\r
old mode 100755 (executable)
new mode 100644 (file)
index c5e6a68..7a3fff8
 #include <linux/device.h>\r
 #include <linux/errno.h>\r
 #include <linux/types.h>\r
-#include <linux/stat.h>         /* permission constants */\r
+#include <linux/stat.h>\r
 #include <linux/io.h>\r
 #include <linux/vmalloc.h>\r
 #include <asm/io.h>\r
 #include <asm/sizes.h>\r
 #include <mach/iomux.h>\r
 #include <mach/gpio.h>\r
-//#include <asm/arch/iomux.h>\r
 #include <linux/delay.h>\r
 \r
-#include "rk29_modem.h"\r
-\r
-/****************************************************************\r
-        huawei-em660/em660c/em770\r
-        zte-ad3812/mf210/mu301\r
-        thinkwill-me800                                                                \r
-\r
-*****************************************************************/\r
-\r
-static int modem_enable(void){\r
-       printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
-       // PG1: 3G reset\r
-         /*arch/arm/mach-rockchip/iomux.c*/\r
-//     rockchip_mux_api_set(G3_RESET_IOMUX_NAME, G3_RESET_IOMUX_MODE);\r
-       // PB0: 3G poweron\r
-//     rockchip_mux_api_set(G3_POWER_ON_IOMUX_NAME, G3_POWER_ON_IOMUX_MODE);\r
-       // PG0: 3G Radio On/Off\r
-//     rockchip_mux_api_set(G3_RADIO_ON_OFF_IOMUX_NAME, G3_RADIO_ON_OFF_IOMUX_MODE);\r
-//     msleep(10);\r
-       \r
-       /*3G Modem Power On*/\r
-        int ret = gpio_request(G3_POWER_ON, NULL);\r
-        if(ret != 0)\r
-        {\r
-            gpio_free(G3_POWER_ON);\r
-            printk(">>>>>> G3_POWER_ON gpio_request err \n ");\r
-           return ret;\r
-        }\r
-        gpio_direction_output(G3_POWER_ON, G3_POWER_ENABLE);\r
-//        gpio_set_value(FB_LCD_CABC_EN_PIN, GPIO_LOW);\r
-\r
-//     GPIOSetPinDirection(G3_POWER_ON, GPIO_OUT);\r
-//     GPIOSetPinLevel(G3_POWER_ON, G3_POWER_ENABLE);\r
-       msleep(100);\r
-       gpio_free(G3_POWER_ON);\r
-       \r
-       /*3G Modem Radio On*/\r
-//     GPIOSetPinDirection(G3_RADIO_ON_OFF, GPIO_OUT);\r
-//     GPIOSetPinLevel(G3_RADIO_ON_OFF, G3_RADIO_ENABLE);\r
-//     msleep(100);\r
-\r
-       /*3G Modem Reset Controll if needed*/\r
-//     if(G3_RESET){\r
-//             GPIOSetPinDirection(G3_RESET, GPIO_OUT);\r
-//             GPIOSetPinLevel(G3_RESET, G3_RESET_ENABLE);\r
-//             msleep(120);\r
-//             GPIOSetPinLevel(G3_RESET, G3_RESET_DISABLE);\r
-//     }\r
-       return 0;\r
-}\r
-\r
-static int modem_disable(void){\r
-       printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
-       // PG1: 3G reset\r
-//     rockchip_mux_api_set(G3_RESET_IOMUX_NAME, G3_RESET_IOMUX_MODE);\r
-       // PB0: 3G poweron\r
-//     rockchip_mux_api_set(G3_POWER_ON_IOMUX_NAME, G3_POWER_ON_IOMUX_MODE);\r
-       // PG0: 3G On/Off\r
-//     rockchip_mux_api_set(G3_RADIO_ON_OFF_IOMUX_NAME, G3_RADIO_ON_OFF_IOMUX_MODE);\r
-//     msleep(10);\r
-\r
-#if 1\r
-        int ret = gpio_request(G3_POWER_ON, NULL);\r
-        if(ret != 0)\r
-        {\r
-            gpio_free(G3_POWER_ON);\r
-            printk(">>>>>> G3_POWER_ON gpio_request err \n ");\r
-           return ret;\r
-        }\r
-        gpio_direction_output(G3_POWER_ON, G3_POWER_DISABLE);\r
-#else  \r
-       /*3G Modem Power off*/\r
-       GPIOSetPinDirection(G3_POWER_ON, GPIO_OUT);\r
-       GPIOSetPinLevel(G3_POWER_ON, G3_POWER_DISABLE);\r
-#endif\r
-       msleep(100);\r
-       gpio_free(G3_POWER_ON);\r
+#include <linux/wakelock.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/gpio.h>\r
+#include <mach/board.h>\r
 \r
-       /*3G Modem  Radio off*/\r
-//     GPIOSetPinDirection(G3_RADIO_ON_OFF, GPIO_OUT);\r
-//     GPIOSetPinLevel(G3_RADIO_ON_OFF, G3_RADIO_DISABLE);\r
-//     msleep(10);\r
+#include <linux/platform_device.h>\r
 \r
-       /*3G Modem Reset enable if needed*/\r
-//     if(G3_RESET){\r
-//             GPIOSetPinDirection(G3_RESET, GPIO_OUT);\r
-//             GPIOSetPinLevel(G3_RESET, G3_RESET_ENABLE);\r
-//     }\r
-       return 0;\r
-}\r
+#include "rk29_modem.h"\r
 \r
-static int modem_sleep(void){\r
-       printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
-       \r
-       return 0;\r
-}\r
+static struct rk29_io_t demo_io_power = {\r
+    .io_addr    = RK29_PIN6_PB1,\r
+    .enable     = GPIO_HIGH,\r
+    .disable    = GPIO_LOW,\r
+};\r
 \r
-static int modem_init(void){\r
-    return modem_disable();\r
-}\r
+static struct platform_driver demo_platform_driver = {\r
+       .driver         = {\r
+               .name           = "rk29_demo",\r
+       },
+};\r
 \r
-struct rk29_modem_t rk29_modem = {\r
-       .name    = "ThinkWill_ME800",\r
-       .enable  = modem_enable,\r
-       .disable = modem_disable,\r
-       .sleep   = modem_sleep,\r
-       .init    = modem_init,\r
+static struct rk29_modem_t demo_driver = {\r
+    .driver         = &demo_platform_driver,\r
+    .modem_power    = &demo_io_power,\r
+    .ap_ready       = NULL,\r
+    .bp_wakeup_ap   = NULL,\r
+    .status         = MODEM_ENABLE,\r
+    .dev_init       = NULL,\r
+    .dev_uninit     = NULL,\r
+    .irq_handler    = NULL,\r
+    \r
+    .enable         = NULL,\r
+    .disable        = NULL,\r
+    .sleep          = NULL,\r
+    .wakeup         = NULL,\r
 };\r
 \r
-static int __init rk29_modem_init(void)\r
+static int __init demo_init(void)\r
 {\r
-       return rk29_modem_register(&rk29_modem);\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    return rk29_modem_init(&demo_driver);\r
 }\r
 \r
-static void __exit rk29_modem_exit(void)\r
+static void __exit demo_exit(void)\r
 {\r
-       rk29_modem_unregister(&rk29_modem);\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    rk29_modem_exit();\r
 }\r
 \r
-\r
-late_initcall(rk29_modem_init);\r
-//module_init(rk29_modem_init);\r
-module_exit(rk29_modem_exit);\r
+module_init(demo_init);\r
+module_exit(demo_exit);\r
 \r
 MODULE_AUTHOR("lintao lintao@rock-chips.com");\r
 MODULE_DESCRIPTION("ROCKCHIP modem driver");\r
 MODULE_LICENSE("GPL");\r
 \r
-\r
diff --git a/drivers/misc/rk29_modem/modem_thinkwill_mw100g.c b/drivers/misc/rk29_modem/modem_thinkwill_mw100g.c
new file mode 100644 (file)
index 0000000..182fbf4
--- /dev/null
@@ -0,0 +1,130 @@
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/moduleparam.h>\r
+#include <linux/init.h>\r
+#include <linux/device.h>\r
+#include <linux/errno.h>\r
+#include <linux/types.h>\r
+#include <linux/stat.h>         /* permission constants */\r
+#include <linux/io.h>\r
+#include <linux/vmalloc.h>\r
+#include <asm/io.h>\r
+#include <asm/sizes.h>\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <linux/delay.h>\r
+\r
+#include <linux/wakelock.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/gpio.h>\r
+#include <mach/board.h>\r
+\r
+#include <linux/platform_device.h>\r
+\r
+#include "rk29_modem.h"\r
+\r
+// È·±£²»³öÏÖÖظ´´¦Àíwakeup\r
+static int do_wakeup_handle = 0;\r
+static irqreturn_t mw100g_irq_handler(int irq, void *dev_id);\r
+\r
+static int __devinit mw100g_suspend(struct platform_device *pdev, pm_message_t state)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    do_wakeup_handle = 0;\r
+    return rk29_modem_suspend(pdev, state);\r
+}\r
+
+static int __devinit mw100g_resume(struct platform_device *pdev)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    return rk29_modem_resume(pdev);\r
+}\r
+\r
+static struct rk29_io_t mw100g_io_power = {\r
+    .io_addr    = RK29_PIN6_PB1,\r
+    .enable     = GPIO_HIGH,\r
+    .disable    = GPIO_LOW,\r
+};\r
+\r
+static struct rk29_irq_t mw100g_irq_bp_wakeup_ap= {\r
+    .irq_addr   = RK29_PIN3_PC4,\r
+    .irq_trigger = IRQF_TRIGGER_FALLING, // Ï½µÑØ´¥·¢\r
+};\r
+\r
+static struct platform_driver mw100g_platform_driver = {\r
+       .driver         = {\r
+               .name           = "thinkwill_mw100g",\r
+       },
+       .suspend    = mw100g_suspend,\r
+       .resume     = mw100g_resume,\r
+};\r
+\r
+static struct rk29_modem_t mw100g_driver = {\r
+    .driver         = &mw100g_platform_driver,\r
+    .modem_power    = &mw100g_io_power,\r
+    .ap_ready       = NULL,\r
+    .bp_wakeup_ap   = &mw100g_irq_bp_wakeup_ap,\r
+    .status         = MODEM_ENABLE,\r
+    .dev_init       = NULL,\r
+    .dev_uninit     = NULL,\r
+    .irq_handler    = mw100g_irq_handler,\r
+    \r
+    .enable         = NULL,\r
+    .disable        = NULL,\r
+    .sleep          = NULL,\r
+    .wakeup         = NULL,\r
+};\r
+\r
+static void do_wakeup(struct work_struct *work)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+//    rk28_send_wakeup_key();\r
+}\r
+\r
+static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);\r
+\r
+/*\r
+    mw100g Ä£×éµÄ IRQ ´¦Àíº¯Êý£¬¸Ãº¯ÊýÓÉrk29_modemÖеÄIRQ´¦Àíº¯Êýµ÷ÓÃ\r
+ */\r
+static irqreturn_t mw100g_irq_handler(int irq, void *dev_id)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    if( irq == gpio_to_irq(mw100g_driver.bp_wakeup_ap->irq_addr) )\r
+    {\r
+        if( !do_wakeup_handle )\r
+        {\r
+            do_wakeup_handle = 1;\r
+            // µ±½ÓÊÕµ½ bb wakeup ap µÄIRQºó£¬ÉêÇëÒ»¸ö8ÃëµÄsuspendËø£¬Ê±¼äµ½ºó×Ô¶¯ÊÍ·Å\r
+            // ÊÍ·ÅʱÈç¹ûûÓÐÆäËüµÄËø£¬¾Í½«ÔٴιÒÆð.\r
+            wake_lock_timeout(&mw100g_driver.wakelock_bbwakeupap, 20 * HZ);\r
+            schedule_delayed_work(&wakeup_work, HZ / 10);\r
+        } else\r
+            printk("%s: already wakeup\n", __FUNCTION__);\r
+        return IRQ_HANDLED;\r
+    }\r
+    \r
+    return IRQ_NONE;\r
+}\r
+\r
+static int __init mw100g_init(void)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    return rk29_modem_init(&mw100g_driver);\r
+}\r
+\r
+static void __exit mw100g_exit(void)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    rk29_modem_exit();\r
+}\r
+\r
+module_init(mw100g_init);\r
+module_exit(mw100g_exit);\r
+\r
+MODULE_AUTHOR("lintao lintao@rock-chips.com");\r
+MODULE_DESCRIPTION("ROCKCHIP modem driver");\r
+MODULE_LICENSE("GPL");\r
+\r
old mode 100755 (executable)
new mode 100644 (file)
index 0a3279d..56de034
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/stat.h>         /* permission constants */
-
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-#include "rk29_modem.h"
-
-struct rk29_modem_t *g_rk29_modem = NULL;
-
-extern void rk29_host11_driver_enable(void);
-extern void rk29_host11_driver_disable(void);
-
-static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
-{
-       struct rk29_modem_t *rk29_modem = g_rk29_modem;
-
-    int new_mode = simple_strtoul(_buf, NULL, 16);
-    printk("[%s] new_mode: %s\n", __func__, _buf);
-    
-    if(rk29_modem == NULL){
-       printk("!!!! g_rk29_modem is NULL !!!!\n");
-       return _count;
-    }
-    
-    if(new_mode == rk29_modem->cur_mode){
-       printk("[%s] current already in %d mode\n", __func__, new_mode);
-        return _count;
-    }
-    
-    switch(new_mode){
-    case MODEM_DISABLE:
-       if(rk29_modem->disable){
-               printk("modem disable!\n");
-//             rk29_host11_driver_disable();
-  //           mdelay(10);
-               rk29_modem->disable();
-               rk29_modem->cur_mode = new_mode;
-       }
-       break;
-       
-    case MODEM_ENABLE :
-       if(rk29_modem->enable){
-               printk("modem enable!\n");
-//             rk29_host11_driver_enable();
-//             mdelay(100);
-               rk29_modem->enable();
-               rk29_modem->cur_mode = new_mode;
-       }
-       break;
-       
-    case MODEM_SLEEP:
-       if(rk29_modem->sleep){
-               printk("modem sleep!\n");
-               rk29_modem->sleep();
-               rk29_modem->cur_mode = new_mode;
-       }
-       break;
-       
-    default:
-       printk("[%s] invalid new mode: %d\n", __func__, new_mode);
-       break;
-    }
-    
-       return _count;
-}
-
-static ssize_t modem_status_read(struct class *cls, char *_buf)
-{
-       struct rk29_modem_t *rk29_modem = g_rk29_modem;
-       
-//     printk("Modem type: %s, cur_mode = %d\n", rk29_modem->name, rk29_modem->cur_mode);
-       
-       return sprintf(_buf, "%d\n", rk29_modem->cur_mode);
-}
-
-static struct class *rk29_modem_class = NULL;
-static CLASS_ATTR(modem_status, 0666, modem_status_read, modem_status_write);
-
-int modem_is_turn_on()
-{
-    return (g_rk29_modem->cur_mode != 0);
-}
-
-void turn_off_modem()
+#include <linux/vmalloc.h>\r
+#include <asm/io.h>\r
+#include <asm/sizes.h>\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#include <linux/delay.h>\r
+\r
+#include <linux/wakelock.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/gpio.h>\r
+#include <mach/board.h>\r
+\r
+#include "rk29_modem.h"\r
+\r
+struct rk29_modem_t *g_rk29_modem;\r
+//static struct wake_lock wakelock_bbwakeupap;\r
+static struct class *rk29_modem_class = NULL;\r
+static void rk29_modem_turnon(struct rk29_io_t *modem_power, int onoff);\r
+\r
+int rk29_modem_change_status(struct rk29_modem_t *rk29_modem, int status)\r
+{\r
+    int ret = 0;\r
+    switch(status)\r
+    {\r
+    case MODEM_DISABLE:\r
+        rk29_modem_turnon(rk29_modem->modem_power, 0);\r
+        break;\r
+    case MODEM_ENABLE :\r
+        rk29_modem_turnon(rk29_modem->modem_power, 1);\r
+        break;\r
+    case MODEM_SLEEP:\r
+        ret = -1;\r
+    case MODEM_WAKEUP:\r
+        ret = -1;\r
+        break;\r
+    }\r
+    \r
+    return ret;\r
+}\r
+\r
+static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)\r
+{\r
+    struct rk29_modem_t *rk29_modem = g_rk29_modem;\r
+    int ret = 0;\r
+    int new_state = simple_strtoul(_buf, NULL, 16);\r
+\r
+    if(rk29_modem == NULL){\r
+        printk("!!!! g_rk29_modem is NULL !!!!\n");\r
+        return _count;\r
+    }\r
+    \r
+    printk("[%s] statue change: %d -> %d\n", __func__, rk29_modem->status, new_state);\r
+\r
+    if(new_state == rk29_modem->status) return _count;\r
+\r
+\r
+    switch(new_state)\r
+    {\r
+    case MODEM_DISABLE:\r
+        if(rk29_modem->disable)\r
+            ret = rk29_modem->disable(rk29_modem);\r
+        else\r
+            ret = rk29_modem_change_status(rk29_modem, new_state);\r
+        break;\r
+    case MODEM_ENABLE :\r
+        if(rk29_modem->enable)\r
+            ret = rk29_modem->enable(rk29_modem);\r
+        else\r
+            ret = rk29_modem_change_status(rk29_modem, new_state);\r
+        break;\r
+    case MODEM_SLEEP:\r
+        if(rk29_modem->sleep)\r
+            ret = rk29_modem->sleep(rk29_modem);\r
+        else\r
+            ret = rk29_modem_change_status(rk29_modem, new_state);\r
+        break;\r
+    case MODEM_WAKEUP:\r
+        if(rk29_modem->wakeup)\r
+            ret = rk29_modem->wakeup(rk29_modem);\r
+        else\r
+            ret = rk29_modem_change_status(rk29_modem, new_state);\r
+        break;\r
+    default:\r
+        ret = -1;\r
+        printk("[%s] Invalid new status: %d\n", __func__, new_state);\r
+        break;\r
+    }\r
+\r
+    if( !ret ) rk29_modem->status = new_state;\r
+    \r
+    return _count;\r
+}\r
+\r
+static ssize_t modem_status_read(struct class *cls, char *_buf)\r
+{\r
+    struct rk29_modem_t *rk29_modem = g_rk29_modem;\r
+\r
+    return sprintf(_buf, "%d\n", rk29_modem->status);\r
+}\r
+static CLASS_ATTR(modem_status, 0666, modem_status_read, modem_status_write);\r
+\r
+int __devinit rk29_modem_suspend(struct platform_device *pdev, pm_message_t state)\r
 {
-    modem_status_write( NULL, "0", sizeof("0") );
+#ifdef CONFIG_PM\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    if( g_rk29_modem->suspend )\r
+        g_rk29_modem->suspend(pdev, state);\r
+    else\r
+    {\r
+        if(g_rk29_modem->ap_ready) // ±êÖ¾APÒѹÒÆð\r
+            gpio_direction_output(g_rk29_modem->ap_ready->io_addr, g_rk29_modem->ap_ready->disable);\r
+    }\r
+#endif\r
+       return 0;
 }
 
-void turn_on_modem()
+int __devinit rk29_modem_resume(struct platform_device *pdev)\r
 {
-    modem_status_write( NULL, "1", sizeof("1") );
-}
-
-int rk29_modem_register(struct rk29_modem_t *rk29_modem){
-       int ret = -1;
-       
-       if(rk29_modem == NULL)
-               return -1;
-
-#if 1
-       if(rk29_modem->enable) rk29_modem->enable();
-#else
-       if(rk29_modem->disable) rk29_modem->disable();
-#endif 
-       rk29_modem_class = class_create(THIS_MODULE, "rk291x_modem");
-       if(rk29_modem_class == NULL){
-               printk("create class rk291x_modem failed!\n");
-               goto err1;
-       }
-       
-       ret = class_create_file(rk29_modem_class, &class_attr_modem_status);
-       if(ret != 0){
-               printk("create rk291x_modem class file failed!\n");
-               goto err2;
-       }
-       
-       g_rk29_modem = rk29_modem;
-       
+#ifdef CONFIG_PM\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    if( g_rk29_modem->resume )\r
+        g_rk29_modem->resume(pdev);\r
+    else\r
+    {\r
+        if(g_rk29_modem->ap_ready) // ±êÖ¾APÒѻָ´\r
+            gpio_direction_output(g_rk29_modem->ap_ready->io_addr, g_rk29_modem->ap_ready->enable);\r
+    }\r
+#endif\r
        return 0;
-       
-err2:
-       class_destroy(rk29_modem_class);
-err1:
-       return ret;     
-}
-
-void rk29_modem_unregister(struct rk29_modem_t *rk29_modem){
-       /* disable 3G modem */          
-       if(rk29_modem->disable)
-               rk29_modem->disable();
-               
-       class_remove_file(rk29_modem_class, &class_attr_modem_status);
-       class_destroy(rk29_modem_class);
-       
-       rk29_modem_class = NULL;
-}
-
+}\r
+\r
+static irqreturn_t irq_bbwakeupap_handler(int irq, void *dev_id)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    irqreturn_t irqret = IRQ_NONE;\r
+    if( g_rk29_modem->irq_handler )\r
+    {\r
+        irqret = g_rk29_modem->irq_handler(irq, dev_id);\r
+        if( irqret != IRQ_NONE ) return irqret;\r
+    }\r
+\r
+    // ¾ßÌåÉ豸ûÓРirq_handler º¯Êý£¬»òÕßËüµÄirq_handlerº¯ÊýûÓд¦Àí¸Ã irq£¬ÔòʹÓÃ\r
+    // ÒÔÏµĹ«¹²irq´¦Àí.\r
+\r
+    return IRQ_HANDLED;\r
+}\r
+\r
+static void uninstall_irq(struct rk29_irq_t *irq)\r
+{\r
+    gpio_free(irq->irq_addr);\r
+}\r
+\r
+static int install_irq(struct rk29_irq_t *rk29_irq, const char* label)\r
+{\r
+       int ret;\r
+    int irq;\r
+    \r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+       irq = gpio_to_irq(rk29_irq->irq_addr);\r
+    printk("%s: %d ==> %d\n", __func__, rk29_irq->irq_addr, irq);\r
+\r
+       ret = gpio_request(rk29_irq->irq_addr, label);\r
+       if (ret < 0) {\r
+               pr_err("%s: gpio_request(%d) failed\n", __func__, rk29_irq->irq_addr);\r
+               return ret;\r
+       }\r
+\r
+       gpio_direction_input(rk29_irq->irq_addr);\r
+    gpio_pull_updown(rk29_irq->irq_addr, 0);\r
+       ret = request_irq(irq, irq_bbwakeupap_handler, rk29_irq->irq_trigger, label, NULL);\r
+       if (ret < 0) {\r
+               pr_err("%s: request_irq(%d) failed\n", __func__, irq);\r
+               gpio_free(rk29_irq->irq_addr);\r
+               return ret;\r
+       }\r
+\r
+       enable_irq_wake(irq);\r
+       return 0;\r
+}\r
+\r
+// ¸ømodemÉϵç\r
+static void rk29_modem_turnon(struct rk29_io_t *modem_power, int onoff)\r
+{\r
+    if( modem_power )\r
+        gpio_direction_output(modem_power->io_addr, onoff?modem_power->enable:modem_power->disable);\r
+}\r
+\r
+/*\r
+    RK29 modem Í¨ÓõÄÉ豸³õʼ»¯º¯Êý\r
+    Ö÷ÒªÉèÖø÷¸öGPIOÒÔ¼°IRQµÄÉêÇëµÈ\r
+ */\r
+static int rk29_modem_dev_init(struct rk29_modem_t *rk29_modem)\r
+{\r
+    int ret=0;\r
+    \r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+// ÉêÇë¿ØÖÆmodemµçÔ´µÄGPIO\r
+    if( rk29_modem->modem_power )\r
+    {\r
+        ret = gpio_request(rk29_modem->modem_power->io_addr, "modem_power");\r
+        if(ret != 0)\r
+        {\r
+            gpio_free(rk29_modem->modem_power->io_addr);\r
+            printk(">>>>>> Modem power io request failed!\n");\r
+            return ret;\r
+        }\r
+        \r
+        // ÉèÖóõʼµÄmodem״̬\r
+        rk29_modem_change_status(rk29_modem, rk29_modem->status);\r
+    }\r
+\r
+// ÉêÇë¿ØÖÆAP¾ÍÐ÷״̬µÄGPIO\r
+    if( rk29_modem->ap_ready )\r
+    {\r
+        ret = gpio_request(rk29_modem->ap_ready->io_addr, "ap_ready");\r
+        if(ret != 0)\r
+        {\r
+            gpio_free(rk29_modem->ap_ready->io_addr);\r
+            printk(">>>>>> AP ready io request failed!\n");\r
+            return ret;\r
+        }\r
+\r
+        // Ä¬ÈÏ AP is ready\r
+        gpio_direction_output(rk29_modem->ap_ready->io_addr, rk29_modem->ap_ready->enable);\r
+    }\r
+\r
+// ÉèÖàbb_wakeup_ap µÄirq£¬ÓÃÓÚap¹ÒÆðÖ®ºó£¬ÓÉbbÀ´»½ÐÑap\r
+    if( rk29_modem->bp_wakeup_ap )\r
+    {\r
+        ret = install_irq(rk29_modem->bp_wakeup_ap, "bb_wakeup_ap");\r
+    }\r
+    \r
+    wake_lock_init(&rk29_modem->wakelock_bbwakeupap, WAKE_LOCK_SUSPEND, "bb_wakeup_ap");\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+    modemϵ硢ÊÍ·Ågpio wait_lock µÈ\r
+ */\r
+static void rk29_modem_dev_uninit(struct rk29_modem_t *rk29_modem)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    \r
+// ¸ømodemϵç\r
+    if( rk29_modem->modem_power )\r
+        rk29_modem_turnon(rk29_modem->modem_power, 0);\r
+\r
+// ÊÍ·ÅGPIO\r
+    if( rk29_modem->modem_power )\r
+        gpio_free(rk29_modem->modem_power->io_addr);\r
+\r
+    if(rk29_modem->ap_ready)\r
+        gpio_free(rk29_modem->ap_ready->io_addr);\r
+\r
+    if(rk29_modem->bp_wakeup_ap)\r
+        uninstall_irq(rk29_modem->bp_wakeup_ap);\r
+\r
+// ÊÍ·Å wake lock\r
+    wake_lock_destroy(&rk29_modem->wakelock_bbwakeupap);\r
+}\r
+\r
+/*\r
+    Çý¶¯¼ÓÔØ\r
+ */\r
+int rk29_modem_init(struct rk29_modem_t *rk29_modem)\r
+{\r
+    int retval = 0;\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+\r
+    retval = platform_driver_register(rk29_modem->driver);\r
+    if( retval )\r
+    {\r
+        printk("could not register rk29_modem!\n");\r
+        return retval;\r
+    }\r
+\r
+       rk29_modem_class = class_create(THIS_MODULE, "rk291x_modem");\r
+    if(rk29_modem_class == NULL){\r
+        printk("create class rk291x_modem failed!\n");\r
+        return -1;\r
+    }\r
+    retval = class_create_file(rk29_modem_class, &class_attr_modem_status);\r
+    if(retval != 0){\r
+        printk("create rk291x_modem class file failed!\n");\r
+        goto failed_create_class;\r
+    }\r
+    \r
+// ¶Ômodem³õʼ»¯\r
+    if( rk29_modem->dev_init )\r
+        retval = rk29_modem->dev_init(rk29_modem);\r
+    else\r
+        retval = rk29_modem_dev_init(rk29_modem);\r
+        \r
+    if( retval )\r
+        goto failed_device_init;\r
+\r
+    g_rk29_modem = rk29_modem;\r
+\r
+    return 0;\r
+\r
+failed_device_init:\r
+    platform_driver_unregister(rk29_modem->driver);\r
+\r
+failed_create_class:\r
+    class_destroy(rk29_modem_class);\r
+    \r
+    return retval;\r
+}\r
+\r
+/*\r
+    Í˳öÇý¶¯Ê±µ÷ÓÃ\r
+    Ä¿Ç°driverÊÇbuild-in£¬²»´æÔÚÍ˳öµÄÇé¿ö£¬²»»áµ÷Óõ½Õâ±ß\r
+ */\r
+void rk29_modem_exit(void)\r
+{\r
+    printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);\r
+    platform_driver_unregister(g_rk29_modem->driver);\r
+\r
+// ¶Ômodem·´³õʼ»¯\r
+    if( g_rk29_modem->dev_uninit )\r
+        g_rk29_modem->dev_uninit(g_rk29_modem);\r
+    else\r
+        rk29_modem_dev_uninit(g_rk29_modem);\r
+}\r
+\r
old mode 100755 (executable)
new mode 100644 (file)
index 5e68129..0e5f402
@@ -1,41 +1,51 @@
-#ifndef _rk29_MODEM_H
-#define _rk29_MODEM_H
-
-/* Modem states */
-#define MODEM_DISABLE       0
-#define MODEM_ENABLE        1
-#define MODEM_SLEEP         2
-#define MODEM_MAX_STATUS    3
-
-/*===================lintao@rock-chips====================*/
-#define G3_POWER_ON                                    RK29_PIN6_PB1//GPIOPortB_Pin0
-//#define G3_POWER_ON_IOMUX_NAME               GPIOB0_SPI0CSN1_MMC1PCA_NAME
-//#define G3_POWER_ON_IOMUX_MODE               IOMUXA_GPIO0_B0
-#define G3_POWER_ENABLE                                GPIO_HIGH
-#define G3_POWER_DISABLE                               GPIO_LOW
-/*===================================================*/
-//#define G3_RADIO_ON_OFF                                      GPIOPortG_Pin0
-//#define G3_RADIO_ON_OFF_IOMUX_NAME       GPIOG0_UART0_MMC1DET_NAME
-//#define G3_RADIO_ON_OFF_IOMUX_MODE   IOMUXA_GPIO1_C0
-//#define G3_RADIO_ENABLE                              GPIO_HIGH
-//#define G3_RADIO_DISABLE                             GPIO_LOW
-/*====================================================*/
-//#define G3_RESET                                             GPIOPortG_Pin1
-//#define G3_RESET_IOMUX_NAME                  GPIOG1_UART0_MMC1WPT_NAME
-//#define G3_RESET_IOMUX_MODE                  IOMUXA_GPIO1_C1
-//#define G3_RESET_ENABLE                              GPIO_LOW
-//#define G3_RESET_DISABLE                             GPIO_HIGH
-/*====================================================*/
-struct rk29_modem_t {
-       char *name;
-       int cur_mode;
-       int (*enable)(void);
-       int (*disable)(void);
-       int (*sleep)(void);
-       int (*init)(void);
-};
-
-int rk29_modem_register(struct rk29_modem_t *rk29_modem);
-void rk29_modem_unregister(struct rk29_modem_t *rk29_modem);
-
-#endif
+#include <linux/platform_device.h>\r
+\r
+/* Modem states */\r
+#define MODEM_DISABLE       0\r
+#define MODEM_ENABLE        1\r
+#define MODEM_SLEEP         2\r
+#define MODEM_WAKEUP        3\r
+#define MODEM_MAX_STATUS    4\r
+\r
+struct rk29_io_t {\r
+    unsigned long io_addr;\r
+    unsigned long enable;\r
+    unsigned long disable;\r
+};\r
+\r
+struct rk29_irq_t {\r
+    unsigned long irq_addr;\r
+    unsigned long irq_trigger;\r
+};\r
+\r
+struct rk29_modem_t {\r
+    struct platform_driver *driver;\r
+    // ¿ØÖÆmodemµçÔ´µÄIO\r
+    struct rk29_io_t *modem_power;\r
+    // µ±AP¾ÍÐ÷»òÕßδ¾ÍÐ÷ʱ£¬Í¨¹ý ap_ready Õâ¸öIOÀ´Í¨ÖªBP¡£\r
+    struct rk29_io_t *ap_ready;\r
+    // µ±BP½ÓÊÕµ½¶ÌÐÅ»òÕßÀ´µçʱ£¬Í¨¹ý bp_wakeup_ap Õâ¸öIRQÀ´»½ÐÑAP\r
+    struct rk29_irq_t *bp_wakeup_ap;\r
+    // µ±Ç°modem״̬£¬Ä¿Ç°Ö»Óõ½MODEM_ENABLE(Éϵç)¡¢MODEM_DISABLE(ϵç)\r
+    // Í¬Ê±£¬statusµÄ³õʼֵҲ¾ö¶¨¿ª»úʱµÄmodemÊÇ·ñÉϵç\r
+    int status;\r
+    struct wake_lock wakelock_bbwakeupap;\r
+\r
+    // É豸³õʼ»¯º¯Êý, Ö÷ÒªÉèÖø÷¸öGPIOÒÔ¼°IRQµÄÉêÇëµÈ\r
+    int (*dev_init)(struct rk29_modem_t *driver);\r
+    int (*dev_uninit)(struct rk29_modem_t *driver);\r
+    irqreturn_t (*irq_handler)(int irq, void *dev_id);\r
+    int (*suspend)(struct platform_device *pdev, pm_message_t state);\r
+    int (*resume)(struct platform_device *pdev);\r
+\r
+    int (*enable)(struct rk29_modem_t *driver);\r
+    int (*disable)(struct rk29_modem_t *driver);\r
+    int (*sleep)(struct rk29_modem_t *driver);\r
+    int (*wakeup)(struct rk29_modem_t *driver);\r
+};\r
+\r
+void rk29_modem_exit(void);\r
+int rk29_modem_init(struct rk29_modem_t *rk29_modem);\r
+int rk29_modem_suspend(struct platform_device *pdev, pm_message_t state);\r
+int rk29_modem_resume(struct platform_device *pdev);\r
+\r