modify mtk23d.c
authorlby <lby@rock-chips.com>
Wed, 3 Aug 2011 06:30:04 +0000 (14:30 +0800)
committerroot <root@lw.(none)>
Tue, 9 Aug 2011 06:10:02 +0000 (14:10 +0800)
drivers/misc/mtk23d.c
include/linux/mtk23d.h

index ce7699ea9156704108d3072a01edf2073a9946c9..2a2c23636a1d0eee53781729fdc973075812c0b3 100755 (executable)
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
 #else
 #define MODEMDBG(fmt,argss...)
 #endif
-
+#define MTK23D_POWEROFF        0X00
 #define MTK23D_RESET 0x01
 #define MTK23D_POWERON  0x02
 #define MTK23D_POWER_HIGH 0x03
@@ -56,6 +56,105 @@ static struct wake_lock mtk23d_wakelock;
 //struct modem_dev *mt6223d_data = NULL;
 struct rk2818_23d_data *gpdata = NULL;
 
+static int rk29_uart_to_gpio(int uart_id)
+{
+       if(uart_id == 3) {
+               rk29_mux_api_set(GPIO2B3_UART3SOUT_NAME, GPIO2L_GPIO2B3);                       
+               rk29_mux_api_set(GPIO2B2_UART3SIN_NAME, GPIO2L_GPIO2B2);                
+
+               gpio_request(RK29_PIN2_PB3, NULL);
+               gpio_request(RK29_PIN2_PB2, NULL);
+
+               gpio_direction_output(RK29_PIN2_PB3, GPIO_LOW);
+               gpio_direction_output(RK29_PIN2_PB2, GPIO_LOW);
+       }
+       else if(uart_id == 2) {
+               rk29_mux_api_set(GPIO2B1_UART2SOUT_NAME, GPIO2L_GPIO2B1);                       
+               rk29_mux_api_set(GPIO2B0_UART2SIN_NAME, GPIO2L_GPIO2B0);                
+
+               gpio_request(RK29_PIN2_PB1, NULL);
+               gpio_request(RK29_PIN2_PB0, NULL);
+
+               gpio_direction_output(RK29_PIN2_PB1, GPIO_LOW);
+               gpio_direction_output(RK29_PIN2_PB0, GPIO_LOW);
+       }
+       else if(uart_id == 1) {
+               rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_GPIO2A5);                       
+               rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_GPIO2A4);                
+
+               gpio_request(RK29_PIN2_PA5, NULL);
+               gpio_request(RK29_PIN2_PA4, NULL);
+
+               gpio_direction_output(RK29_PIN2_PA5, GPIO_LOW);
+               gpio_direction_output(RK29_PIN2_PA4, GPIO_LOW);
+       }
+       else if(uart_id == 0){
+               rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_GPIO1B7);                       
+               gpio_request(RK29_PIN1_PB7, NULL);
+               gpio_direction_output(RK29_PIN1_PB7,GPIO_LOW);
+               gpio_pull_updown(RK29_PIN1_PB7, PullDisable);  // ÏÂÀ­½ûÖ¹
+
+               rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_GPIO1B6);                
+               gpio_request(RK29_PIN1_PB6, NULL);
+               gpio_direction_output(RK29_PIN1_PB6,GPIO_LOW);  
+               gpio_pull_updown(RK29_PIN1_PB6, PullDisable);  // ÏÂÀ­½ûÖ¹
+
+               rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);                        
+               gpio_request(RK29_PIN1_PC1, NULL);
+               gpio_direction_output(RK29_PIN1_PC1,GPIO_LOW);
+
+               rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_GPIO1C0);                 
+               gpio_request(RK29_PIN1_PC0, NULL);
+               //gpio_direction_input(RK29_PIN1_PC0);          
+               gpio_direction_output(RK29_PIN1_PC0,GPIO_LOW);
+       }
+
+       return 0;
+}
+
+static int rk29_gpio_to_uart(int uart_id)
+{
+       if(uart_id == 3) {
+               rk29_mux_api_set(GPIO2B3_UART3SOUT_NAME, GPIO2L_UART3_SOUT);
+               rk29_mux_api_set(GPIO2B2_UART3SIN_NAME, GPIO2L_UART3_SIN); 
+
+               gpio_request(RK29_PIN2_PB3, NULL);
+               gpio_request(RK29_PIN2_PB2, NULL);
+
+               gpio_direction_output(RK29_PIN2_PB3, GPIO_HIGH);
+               gpio_direction_output(RK29_PIN2_PB2, GPIO_HIGH);
+       }
+       else if(uart_id == 2) {
+               rk29_mux_api_set(GPIO2B1_UART2SOUT_NAME, GPIO2L_UART2_SOUT);                    
+               rk29_mux_api_set(GPIO2B0_UART2SIN_NAME, GPIO2L_UART2_SIN);              
+
+               gpio_request(RK29_PIN2_PB1, NULL);
+               gpio_request(RK29_PIN2_PB0, NULL);
+
+               gpio_direction_output(RK29_PIN2_PB1, GPIO_HIGH);
+               gpio_direction_output(RK29_PIN2_PB0, GPIO_HIGH);
+       }
+       else if(uart_id == 1) {
+               rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_UART1_SOUT);                    
+               rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_UART1_SIN);              
+
+               gpio_request(RK29_PIN2_PA5, NULL);
+               gpio_request(RK29_PIN2_PA4, NULL);
+
+               gpio_direction_output(RK29_PIN2_PA5, GPIO_HIGH);
+               gpio_direction_output(RK29_PIN2_PA4, GPIO_HIGH);
+       }
+       else if(uart_id == 0){
+               rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_UART0_SOUT);
+               rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_UART0_SIN); 
+               rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
+               rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_UART0_CTS_N);     
+       }
+
+       return 0;
+
+}
+
 static int  get_bp_statue(struct platform_device *pdev)
 {
        struct rk2818_23d_data *pdata = pdev->dev.platform_data;
@@ -144,53 +243,48 @@ int modem_poweron_off(int on_off)
        int result, error = 0, irq = 0; 
        
   if(on_off)
-  {
-                       printk("modem_poweron\n");
-                       
-                 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);  // power on enable
-                 mdelay(300);
-                       gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);  // release reset
-                       msleep(3000);
-                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);  // power on relase
-                               
-                       #if 1 // phc
-                       rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_UART0_SOUT);
-                       rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_UART0_SIN); 
-                       rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
-                       rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_UART0_CTS_N);     
-                       #endif
-                       
-                 gpio_direction_input(pdata->bp_statue);
-                 if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
-                       gpio_direction_input(pdata->bp_ap_wakeup);
-                       
-                       /* ³õʼ»¯BP»½ÐÑAPµÄ¹¦ÄÜ */
-                       wakelock_inited = false;
-                       irq = gpio_to_irq(pdata->bp_statue);
-                       if (irq < 0) {
-                               printk("can't get pdata->bp_statue irq \n");
-                       }
-                       else
-                       {
-                               error = request_irq(irq, BBwakeup_isr,
-                                                   IRQF_TRIGGER_FALLING,
-                                                   NULL,
-                                                   pdata);
-                               if (error) {
-                                       printk("mtk23d_probe bp_statue request_irq error!!! \n");
-                               }
-                       }
-                       if (!wakelock_inited) {
-                               wake_lock_init(&mtk23d_wakelock, WAKE_LOCK_SUSPEND, "23d_resume");
-                               wakelock_inited = true;
+       {
+               printk("modem_poweron\n");
+
+               gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);  // power on enable
+               mdelay(300);
+               gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);  // release reset
+               msleep(3000);
+               gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);  // power on relase
+
+               rk29_gpio_to_uart(0);
+               
+               gpio_direction_input(pdata->bp_statue);
+               if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
+               gpio_direction_input(pdata->bp_ap_wakeup);
+
+               /* ³õʼ»¯BP»½ÐÑAPµÄ¹¦ÄÜ */
+               wakelock_inited = false;
+               irq = gpio_to_irq(pdata->bp_statue);
+               if (irq < 0) {
+                       printk("can't get pdata->bp_statue irq \n");
+               }
+               else
+               {
+                       error = request_irq(irq, BBwakeup_isr,IRQF_TRIGGER_FALLING, NULL, pdata);
+                       if (error) {
+                               printk("mtk23d_probe bp_statue request_irq error!!! \n");
                        }
-  }
+               }
+               if (!wakelock_inited) {
+                       wake_lock_init(&mtk23d_wakelock, WAKE_LOCK_SUSPEND, "23d_resume");
+                       wakelock_inited = true;
+               }
+       }
   else
   {
                        printk("modem_poweroff\n");
+                       rk29_uart_to_gpio(0);
                        gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
-                       mdelay(100);
+                       msleep(2500);
                        gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
+                       msleep(500);
+                       gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH); 
   }
 }
 static int power_on =1;
@@ -227,24 +321,64 @@ static int mtk23d_release(struct inode *inode, struct file *file)
 static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct rk2818_23d_data *pdata = gpdata;
-       int i;
+       int i,ret;
        void __user *argp = (void __user *)arg;
        
        char SectorBuffer[512];
        
        printk("mtk23d_ioctl\n");
+       ret = down_interruptible(&pdata->power_sem);
+       if (ret < 0) {
+               printk("%s: down power_sem error ret = %d\n", __func__, ret);
+               return ret;
+       }
+       
        switch(cmd)
        {
+
+               case MTK23D_POWEROFF:
+                       printk("MTK23D_POWEROFF\n");
+                       rk29_uart_to_gpio(0);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
+                       msleep(2500);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
+                       msleep(500);
+                       gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
+                       break;
+
                case MTK23D_RESET:              
                        printk("MTK23D_RESET\n");
+                       /****power off 23d and uart to gpio***/
+                       rk29_uart_to_gpio(0);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
+                       msleep(2500);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
+                       msleep(500);
                        gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
-                       mdelay(100);
+                       
+                       /****power on 23d***/
+                       msleep(100);
                        gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
-                       mdelay(300);
+                       rk29_gpio_to_uart(0);
+                       msleep(300);
                        gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
-                       msleep(3000);
+                       msleep(2500);
                        gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
                        break;
+
+               case MTK23D_POWERON:            
+                       /****power on 23d***/
+                       printk("MTK23D_POWERON\n");
+                       gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
+                       msleep(100);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
+                       rk29_gpio_to_uart(0);
+                       msleep(300);
+                       gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
+                       msleep(2500);
+                       gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
+                       break;
+                       
                case MTK23D_IMEI_READ:
                        printk("MTK23D_IMEI_READ\n");
                        
@@ -253,6 +387,7 @@ static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd,
                        if(copy_to_user(argp, &(SectorBuffer[451]), 16))  // IMEIºó´Ó451Æ«ÒÆ¿ªÊ¼µÄ16bytes£¬µÚÒ»¸öbyteΪ³¤¶È¹Ì¶¨Îª15
                        {
                                printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
+                               up(&pdata->power_sem);
                                return -EFAULT;
                        }
                        //printk("IMEI:%d %d %d %d\n", SectorBuffer[451], SectorBuffer[452], SectorBuffer[453], SectorBuffer[454]);
@@ -260,6 +395,9 @@ static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd,
                default:
                        break;
        }
+
+       up(&pdata->power_sem);
+       
        return 0;
 }
 
@@ -332,30 +470,13 @@ static int mtk23d_probe(struct platform_device *pdev)
        }
        
 #if 1 // GPIO³õʼ»¯£¬²¢ÇÒ·Àֹ©µç
-       rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_GPIO1B7);                       
-       gpio_request(RK29_PIN1_PB7, NULL);
-       gpio_direction_output(RK29_PIN1_PB7,GPIO_LOW);
-       gpio_pull_updown(RK29_PIN1_PB7, PullDisable);  // ÏÂÀ­½ûÖ¹
-       
-       rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_GPIO1B6);                
-       gpio_request(RK29_PIN1_PB6, NULL);
-       gpio_direction_output(RK29_PIN1_PB6,GPIO_LOW);  
-       gpio_pull_updown(RK29_PIN1_PB6, PullDisable);  // ÏÂÀ­½ûÖ¹
-       
-       rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);                        
-       gpio_request(RK29_PIN1_PC1, NULL);
-       gpio_direction_output(RK29_PIN1_PC1,GPIO_LOW);
-       
-       rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_GPIO1C0);                 
-       gpio_request(RK29_PIN1_PC0, NULL);
-       //gpio_direction_input(RK29_PIN1_PC0);          
-       gpio_direction_output(RK29_PIN1_PC0,GPIO_LOW);
+       rk29_uart_to_gpio(0);
 
-
-  gpio_direction_output(pdata->bp_power, GPIO_LOW);
+       /***power off 23d***/
+       gpio_direction_output(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
+       
        gpio_direction_output(pdata->ap_statue, GPIO_LOW);
        gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);   
-       gpio_direction_output(pdata->bp_reset, GPIO_LOW);
        //gpio_direction_output(pdata->bp_statue,GPIO_LOW);
        gpio_direction_input(pdata->bp_statue);
        if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
@@ -363,7 +484,7 @@ static int mtk23d_probe(struct platform_device *pdev)
                //gpio_direction_output(pdata->bp_ap_wakeup,GPIO_LOW);
                gpio_direction_input(pdata->bp_ap_wakeup);
        }
-       
+
        /*¸´Î»BP*/
        gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
        //mdelay(200);
@@ -371,7 +492,8 @@ static int mtk23d_probe(struct platform_device *pdev)
 #endif 
 
        INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
-  power_on = 1;
+       init_MUTEX(&pdata->power_sem);
+       power_on = 1;
        result = misc_register(&mtk23d_misc);
        if(result)
        {
index 356c4ca47598469195644287019b5ee752f720f9..9c5f11a819d54bba93660e87afe55cb20b4fdb56 100755 (executable)
@@ -21,6 +21,7 @@ struct rk2818_23d_data {
        unsigned int ap_statue;
        unsigned int ap_bp_wakeup;
        unsigned int bp_ap_wakeup;
+       struct semaphore power_sem;
 };
 
 #define MODEM_NAME "mtk23d"