From ac25059a5dc3d359afee65b6fb1efd070fb6f279 Mon Sep 17 00:00:00 2001 From: lby Date: Wed, 3 Aug 2011 14:30:04 +0800 Subject: [PATCH] modify mtk23d.c --- drivers/misc/mtk23d.c | 260 ++++++++++++++++++++++++++++++----------- include/linux/mtk23d.h | 1 + 2 files changed, 192 insertions(+), 69 deletions(-) diff --git a/drivers/misc/mtk23d.c b/drivers/misc/mtk23d.c index ce7699ea9156..2a2c23636a1d 100755 --- a/drivers/misc/mtk23d.c +++ b/drivers/misc/mtk23d.c @@ -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) { diff --git a/include/linux/mtk23d.h b/include/linux/mtk23d.h index 356c4ca47598..9c5f11a819d5 100755 --- a/include/linux/mtk23d.h +++ b/include/linux/mtk23d.h @@ -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" -- 2.34.1