From: wlq <wlq@rock-chips.com>
Date: Tue, 23 Jul 2013 10:16:49 +0000 (+0800)
Subject: 【修改内容】更新bp-auto驱动
X-Git-Tag: firefly_0821_release~6857^2
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=51bd07b11b2508581bbbe0061ff28fed3fe20cee;p=firefly-linux-kernel-4.4.55.git

【修改内容】更新bp-auto驱动
【涉及文件】
	drivers/misc/bp/bp-auto.c
	drivers/misc/bp/chips/Kconfig
	drivers/misc/bp/chips/Makefile
	drivers/misc/bp/chips/a85xx.c
	drivers/misc/bp/chips/aw706.c
	drivers/misc/bp/chips/m51.c
	drivers/misc/bp/chips/sc6610.c
	include/linux/bp-auto.h
---

diff --git a/drivers/misc/bp/bp-auto.c b/drivers/misc/bp/bp-auto.c
index 5d79dbf7f17e..e5f972c4705d 100755
--- a/drivers/misc/bp/bp-auto.c
+++ b/drivers/misc/bp/bp-auto.c
@@ -98,6 +98,16 @@ static int bp_request_gpio(struct bp_private_data *bp)
 
 	}
 	
+	if(bp->ops->bp_assert != BP_UNKNOW_DATA)
+	{
+		result = gpio_request(bp->ops->bp_assert, "bp_assert");
+		if(result)
+		{
+			printk("%s:fail to request gpio %d\n",__func__, bp->ops->bp_assert);
+			//return -1;
+		}
+	}
+	
 	if(bp->ops->bp_power != BP_UNKNOW_DATA)
 	{
 		result = gpio_request(bp->ops->bp_power, "bp_power");
@@ -200,7 +210,7 @@ static irqreturn_t bp_wake_up_irq(int irq, void *dev_id)
 {
 	
 	struct bp_private_data *bp = dev_id;
-	printk("<---%s:bp_id=%d--->\n",__FUNCTION__,bp->ops->bp_id);	
+	//printk("<---%s:bp_id=%d--->\n",__FUNCTION__,bp->ops->bp_id);	
 	if(bp->ops->bp_wake_ap){
 		bp->ops->bp_wake_ap(bp);
 	}	
@@ -367,7 +377,7 @@ static long bp_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		case BP_IOCTL_GET_IMEI:
 			printk("BP_IMEI_READ\n");
 			GetSNSectorInfo(SectorBuffer); 
-			if(copy_to_user(argp, &(SectorBuffer[451]), 16))  // IMEIo¨®¡ä¨®451??¨°??a¨º?¦Ì?16bytes¡ê?¦Ì¨²¨°???byte?a3¡è?¨¨1¨¬?¡§?a15
+			if(copy_to_user(argp, &(SectorBuffer[451]), 16))  // IMEIo¡§???¡§?451??¡§¡ã??a¡§o?|¨¬?16bytes?¨º?|¨¬¡§2¡§¡ã???byte?a3?¨¨?¡§¡§1¡§???¡ì?a15
 			{
 				printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
 				return -EFAULT;
@@ -416,14 +426,21 @@ static ssize_t bp_status_write(struct class *cls, struct class_attribute *attr,
 			if(bp->ops->active)
 			bp->ops->active(bp, 0);
 			break;		
-			
+		case 2://power en gpio low
+			if(bp->ops->active)
+			bp->ops->active(bp, 2);
+			break;
+		case 3://power en gpio high
+			if(bp->ops->active)
+			bp->ops->active(bp, 3);
+			break;
 		default:
 			break;
 		}
 	}	   
 	return result; 
 }
-//static CLASS_ATTR(bp_status, 0777, bp_status_read, bp_status_write);
+static CLASS_ATTR(bp_status, 0777, bp_status_read, bp_status_write);
 static int bp_probe(struct platform_device *pdev)
 {
 	struct bp_platform_data *pdata = pdev->dev.platform_data;
@@ -473,7 +490,7 @@ static int bp_probe(struct platform_device *pdev)
                 bp->ops->init(bp);
 	bp->ops->irq = 0;
 	wake_lock_init(&bp->bp_wakelock, WAKE_LOCK_SUSPEND, "bp_wakelock");
-	if((bp->ops->bp_wakeup_ap) && (bp->ops->trig != BP_UNKNOW_DATA))
+	if((bp->ops->bp_wakeup_ap != BP_UNKNOW_DATA) && (bp->ops->trig != BP_UNKNOW_DATA))
 	{
 		irq = gpio_to_irq(bp->ops->bp_wakeup_ap);
 		result = request_irq(irq, bp_wake_up_irq, bp->ops->trig, "bp_wakeup_ap", bp);
@@ -619,12 +636,12 @@ static struct platform_driver bp_driver = {
 static int __init bp_init(void)
 {
 	int ret ;
-	//bp_class = class_create(THIS_MODULE, "bp-auto");
-	//ret =  class_create_file(bp_class, &class_attr_bp_status);
-	//if (ret)
-	//{
-	//	printk("Fail to create class bp-auto\n");
-	//}
+	bp_class = class_create(THIS_MODULE, "bp-auto");
+	ret =  class_create_file(bp_class, &class_attr_bp_status);
+	if (ret)
+	{
+		printk("Fail to create class bp-auto\n");
+	}
 	return platform_driver_register(&bp_driver);
 }
 
diff --git a/drivers/misc/bp/chips/Kconfig b/drivers/misc/bp/chips/Kconfig
index bf2367482d4e..5662db07171a 100755
--- a/drivers/misc/bp/chips/Kconfig
+++ b/drivers/misc/bp/chips/Kconfig
@@ -22,6 +22,10 @@ bool "modem sew290"
 config BP_AUTO_U7501
 bool "modem u7501"
         default n
+	
 config BP_AUTO_U5501
 bool "modem u5501"
+
+config BP_AUTO_AW706
+bool "modem aw706"
         default n
\ No newline at end of file
diff --git a/drivers/misc/bp/chips/Makefile b/drivers/misc/bp/chips/Makefile
index 56bc1b54c3af..5b7acf26c34c 100755
--- a/drivers/misc/bp/chips/Makefile
+++ b/drivers/misc/bp/chips/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_BP_AUTO)                           += sew290.o
 obj-$(CONFIG_BP_AUTO)                           += u7501.o
 obj-$(CONFIG_BP_AUTO)                           += a85xx.o
 obj-$(CONFIG_BP_AUTO)                           += u5501.o
+obj-$(CONFIG_BP_AUTO)                           += aw706.o
diff --git a/drivers/misc/bp/chips/a85xx.c b/drivers/misc/bp/chips/a85xx.c
index ac79d68b7737..ac38e8c9ce47 100755
--- a/drivers/misc/bp/chips/a85xx.c
+++ b/drivers/misc/bp/chips/a85xx.c
@@ -48,32 +48,46 @@
 
 
 /****************operate according to bp chip:start************/
+
 static int bp_active(struct bp_private_data *bp, int enable)
 {	
 	int result = 0;
-
-	if(enable)
-	{		
-		printk("<-----a85xx power on-------->\n");	
-		gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
-		msleep(100);
-		gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
-		mdelay(100);
-		gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
-		mdelay(2500);
-		gpio_set_value(bp->ops->bp_en,GPIO_LOW);
-	}
-	else
-	{
-		printk("<-----a85xx power off-------->\n");
-		gpio_set_value(bp->ops->bp_en, GPIO_LOW);
-		msleep(2500);
-		gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
-		msleep(500);
-		gpio_set_value(bp->ops->bp_reset, GPIO_HIGH); 
-		gpio_set_value(bp->ops->bp_power, GPIO_LOW);
-	}
-	
+	switch(enable){
+		case 0:
+			printk("<-----a85xx power off-------->\n");
+			gpio_set_value(bp->ops->bp_en, GPIO_LOW);
+			msleep(2500);
+			gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
+			msleep(500);
+			gpio_set_value(bp->ops->bp_reset, GPIO_HIGH); 
+			gpio_set_value(bp->ops->bp_power, GPIO_LOW);	
+			break;
+		case 1:
+			printk("<-----a85xx power on-------->\n");	
+			gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			msleep(100);
+			gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
+			//mdelay(100);
+			//gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
+			mdelay(2500);
+			gpio_set_value(bp->ops->bp_en,GPIO_LOW);
+			break;
+		case 2:
+			printk("<-----a85xx udate power_en low-------->\n");
+			gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			msleep(100);
+			
+			gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
+			//mdelay(100);
+			//gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
+			break;
+		case 3:
+			printk("<-----a85xx udate power_en high-------->\n");
+			gpio_set_value(bp->ops->bp_en,GPIO_LOW);
+			break;
+		default:
+			break;
+	}	
 	return result;
 }
 static void  ap_wake_bp_work(struct work_struct *work)
@@ -173,19 +187,19 @@ struct bp_operate bp_a85xx_ops = {
 	.resume			= bp_resume,
 	.misc_name		= NULL,
 	.private_miscdev	= NULL,
-#elif defined(CONFIG_ARCH_RK30)
+#elif defined(CONFIG_SOC_RK3028)
 	.name			= "a85xx",
 	.bp_id			= BP_ID_A85XX,
 	.bp_bus			= BP_BUS_TYPE_UART,		
 	.bp_pid			= 0,	
 	.bp_vid			= 0,	
-	.bp_power		= BP_UNKNOW_DATA,	// RK2928_PIN3_PC2, 	// 3g_power
-	.bp_en			= BP_UNKNOW_DATA,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+	.bp_power		= RK30_PIN0_PC2,	// RK2928_PIN3_PC2, 	// 3g_power
+	.bp_en			= RK30_PIN3_PD0,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
 	.bp_reset			= BP_UNKNOW_DATA,	// RK2928_PIN0_PB6,
 	.ap_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD0,	//
 	.bp_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD6,
-	.ap_wakeup_bp	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC4,
-	.bp_wakeup_ap	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC3,	//
+	.ap_wakeup_bp	= RK30_PIN3_PC6,	// RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= RK30_PIN0_PC1,	// RK2928_PIN3_PC3,	//
 	.bp_assert		= BP_UNKNOW_DATA,
 	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
 	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
diff --git a/drivers/misc/bp/chips/aw706.c b/drivers/misc/bp/chips/aw706.c
new file mode 100755
index 000000000000..36ebf1cbd53a
--- /dev/null
+++ b/drivers/misc/bp/chips/aw706.c
@@ -0,0 +1,326 @@
+/* drivers/misc/bp/chips/aw706.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#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 <asm/gpio.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <linux/earlysuspend.h>
+
+#include <linux/bp-auto.h>
+	 
+	 
+#if 0
+#define DBG(x...)  printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/****************operate according to bp chip:start************/
+static int bp_active(struct bp_private_data *bp, int enable)
+{	
+	int result = 0;
+	switch(enable){
+		case 0:
+			printk("<-----aw706 power off-------->\n");
+			//result = gpio_get_value(bp->ops->bp_assert);
+			//if(!result){ 
+			//printk("<-----aw706 is poweroff-------->\n");
+			//return result;}
+			gpio_set_value(bp->ops->bp_en, GPIO_LOW);
+			msleep(2500);
+			gpio_set_value(bp->ops->bp_en, GPIO_HIGH);		
+			gpio_set_value(bp->ops->bp_power, GPIO_LOW);	
+			break;
+		case 1:
+			printk("<-----aw706 power on-------->\n");	
+			//result = gpio_get_value(bp->ops->bp_assert);
+			//if(result){
+			//	printk("<-----aw706 power bp_assert is high no need to power on again-------->\n");
+			//	return result;
+			//}
+        	gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			mdelay(100);
+			gpio_set_value(bp->ops->bp_en,GPIO_LOW);
+			gpio_set_value(bp->ops->ap_wakeup_bp,GPIO_HIGH);	
+        	mdelay(1000);		
+			gpio_set_value(bp->ops->ap_wakeup_bp,GPIO_LOW);
+			gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
+			break;
+		case 2:
+			printk("<-----aw706 udate power_en low-------->\n");
+			gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			mdelay(50);
+			gpio_set_value(bp->ops->bp_en,GPIO_LOW);
+			gpio_set_value(bp->ops->ap_wakeup_bp,GPIO_HIGH);
+			break;
+		case 3:
+			printk("<-----aw706 udate power_en high-------->\n");
+			gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
+			gpio_set_value(bp->ops->ap_wakeup_bp,GPIO_LOW);
+			break;
+		default:
+			break;
+	}	
+	return result;
+}
+static void  ap_wake_bp_work(struct work_struct *work)
+{
+	return;
+}
+static int bp_wake_ap(struct bp_private_data *bp)
+{
+	int result = 0;
+	
+	if(bp->suspend_status)
+	{
+		//iomux_set(UART1_RTSN);
+		//gpio_direction_output(RK30_PIN1_PA6, GPIO_LOW);
+		printk("bp_wake_ap aw706 done!!! \n");	
+		
+		bp->suspend_status = 0;		
+		wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
+	}
+	
+	return result;
+}
+static int bp_init(struct bp_private_data *bp)
+{
+	int result = 0;
+	
+	gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
+	//gpio_direction_output(bp->ops->bp_reset, GPIO_LOW);
+	gpio_direction_output(bp->ops->bp_en, GPIO_HIGH);
+	//gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);
+	gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);   
+	//gpio_direction_input(bp->ops->bp_ready);	
+	gpio_direction_input(bp->ops->bp_wakeup_ap);
+	gpio_direction_input(bp->ops->bp_assert);
+	gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);	
+	
+	//if(bp->ops->active)
+		//bp->ops->active(bp, 1);	
+	INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
+	return result;
+}
+
+static int bp_reset(struct bp_private_data *bp)
+{
+	printk("ioctrl aw706 reset !!! \n");	
+	return 0;
+	gpio_set_value(bp->ops->bp_en,GPIO_LOW);
+	mdelay(6000);
+	gpio_set_value(bp->ops->bp_en,GPIO_HIGH);
+	
+}
+static int bp_shutdown(struct bp_private_data *bp)
+{
+	int result = 0;
+	
+	if(bp->ops->active)
+		bp->ops->active(bp, 0);
+	
+	cancel_delayed_work_sync(&bp->wakeup_work);	
+		
+	return result;
+}
+static int bp_suspend(struct bp_private_data *bp)
+{	
+	int result = 0;
+	int ret = 0;
+	printk("aw706 %s !!! \n",__func__);
+	bp->suspend_status = 1;
+	//gpio_set_value(bp->ops->ap_ready, GPIO_HIGH);
+	gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
+	/*
+	iomux_set(GPIO1_A7);
+	ret = gpio_request(RK30_PIN1_PA7,"bp_auto");
+	if(ret < 0){
+		printk("%s rk30_pin1_pa7 request failed\n",__func__);
+		return result;
+	}	
+	gpio_direction_output(RK30_PIN1_PA7, GPIO_HIGH);
+	*/
+	return result;
+}
+static int bp_resume(struct bp_private_data *bp)
+{
+	
+	bp->suspend_status = 0;	
+		
+	//iomux_set(UART1_RTSN);		
+	//gpio_direction_output(RK30_PIN1_PA7, GPIO_LOW);
+	gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
+	return 0;
+}
+
+
+struct bp_operate bp_aw706_ops = {
+#if defined(CONFIG_ARCH_RK2928)
+	.name			= "aw706",
+	.bp_id			= BP_ID_AW706,
+	.bp_bus			= BP_BUS_TYPE_UART,		
+	.bp_pid			= 0,	
+	.bp_vid			= 0,	
+	.bp_power		= RK2928_PIN3_PC2, 	// 3g_power
+	.bp_en			= RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+	.bp_reset			= RK2928_PIN0_PB6,
+	.ap_ready		= RK2928_PIN0_PD0,	//
+	.bp_ready		= RK2928_PIN0_PD6,
+	.ap_wakeup_bp	= RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= RK2928_PIN3_PC3,	//
+	.bp_assert		= BP_UNKNOW_DATA,
+	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
+	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
+	.trig				= IRQF_TRIGGER_FALLING,
+
+	.active			= bp_active,
+	.init				= bp_init,
+	.reset			= bp_reset,
+	.ap_wake_bp		= NULL,
+	.bp_wake_ap		= bp_wake_ap,
+	.shutdown		= bp_shutdown,
+	.read_status		= NULL,
+	.write_status		= NULL,
+	.suspend 		= bp_suspend,
+	.resume			= bp_resume,
+	.misc_name		= NULL,
+	.private_miscdev	= NULL,
+#elif defined(CONFIG_SOC_RK3028)
+	.name			= "aw706",
+	.bp_id			= BP_ID_AW706,
+	.bp_bus			= BP_BUS_TYPE_UART,		
+	.bp_pid			= 0,	
+	.bp_vid			= 0,	
+	.bp_power		= RK30_PIN0_PC2,//BP_UNKNOW_DATA,// 3g_power
+#if defined(CONFIG_MACH_RK3028_PHONEPAD_780)
+	.bp_en			= RK30_PIN0_PC5,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+#else
+	.bp_en			= RK30_PIN3_PD0,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+#endif
+	.bp_reset		= BP_UNKNOW_DATA,//BP_UNKNOW_DATA,	// RK2928_PIN0_PB6,
+	.ap_ready		= BP_UNKNOW_DATA,//RK30_PIN1_PB5,//BP_UNKNOW_DATA,	// RK2928_PIN0_PD0,	//
+	.bp_ready		= BP_UNKNOW_DATA,//RK30_PIN3_PD0,//BP_UNKNOW_DATA,	// RK2928_PIN0_PD6,
+	.ap_wakeup_bp	= RK30_PIN3_PC6,//BP_UNKNOW_DATA,	// RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= RK30_PIN0_PC1,//BP_UNKNOW_DATA,	// RK2928_PIN3_PC3,	//
+	.bp_assert		= RK30_PIN0_PC0,
+	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
+	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
+	.trig				= IRQF_TRIGGER_FALLING,
+
+	.active			= bp_active,
+	.init				= bp_init,
+	.reset			= bp_reset,
+	.ap_wake_bp		= NULL,
+	.bp_wake_ap		= bp_wake_ap,
+	.shutdown		= bp_shutdown,
+	.read_status		= NULL,
+	.write_status		= NULL,
+	.suspend 		= bp_suspend,
+	.resume			= bp_resume,
+	.misc_name		= NULL,
+	.private_miscdev	= NULL,
+#else
+	.name			= "aw706",
+	.bp_id			= BP_ID_AW706,
+	.bp_bus			= BP_BUS_TYPE_UART,		
+	.bp_pid			= 0,	
+	.bp_vid			= 0,	
+	.bp_power		= BP_UNKNOW_DATA,	// RK2928_PIN3_PC2, 	// 3g_power
+	.bp_en			= BP_UNKNOW_DATA,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+	.bp_reset			= BP_UNKNOW_DATA,	// RK2928_PIN0_PB6,
+	.ap_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD0,	//
+	.bp_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD6,
+	.ap_wakeup_bp	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC3,	//
+	.bp_assert		= BP_UNKNOW_DATA,
+	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
+	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
+	.trig				= IRQF_TRIGGER_FALLING,
+
+	.active			= bp_active,
+	.init				= bp_init,
+	.reset			= bp_reset,
+	.ap_wake_bp		= NULL,
+	.bp_wake_ap		= bp_wake_ap,
+	.shutdown		= bp_shutdown,
+	.read_status		= NULL,
+	.write_status		= NULL,
+	.suspend 		= bp_suspend,
+	.resume			= bp_resume,
+	.misc_name		= NULL,
+	.private_miscdev	= NULL,
+#endif
+};
+
+/****************operate according to bp chip:end************/
+
+//function name should not be changed
+static struct bp_operate *bp_get_ops(void)
+{
+	return &bp_aw706_ops;
+}
+
+static int __init bp_aw706_init(void)
+{
+	struct bp_operate *ops = bp_get_ops();
+	int result = 0;
+	result = bp_register_slave(NULL, NULL, bp_get_ops);
+	if(result)
+	{	
+		return result;
+	}
+	
+	if(ops->private_miscdev)
+	{
+		result = misc_register(ops->private_miscdev);
+		if (result < 0) {
+			printk("%s:misc_register err\n",__func__);
+			return result;
+		}
+	}
+	
+	DBG("%s\n",__func__);
+	return result;
+}
+
+static void __exit bp_aw706_exit(void)
+{
+	//struct bp_operate *ops = bp_get_ops();
+	bp_unregister_slave(NULL, NULL, bp_get_ops);
+}
+
+
+subsys_initcall(bp_aw706_init);
+module_exit(bp_aw706_exit);
+
diff --git a/drivers/misc/bp/chips/m51.c b/drivers/misc/bp/chips/m51.c
index 8684e018c89f..d2e29cb94f7a 100755
--- a/drivers/misc/bp/chips/m51.c
+++ b/drivers/misc/bp/chips/m51.c
@@ -51,31 +51,43 @@
 static int bp_active(struct bp_private_data *bp, int enable)
 {	
 	int result = 0;
-	if(enable)
-	{		
-		printk("<-----m51 power on-------->\n");
-		gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
-		msleep(100);
-		gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
-		msleep(500);
-		gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
-		gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
-		msleep(1000);
-		//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
-	}
-	else
-	{
-		printk("<-----m51 power off-------->\n");
-		//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
-		//msleep(1000);
-		gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
-        	msleep(200);
-		gpio_set_value(bp->ops->bp_power, GPIO_LOW);
-		msleep(500);
-	}
-	
+	switch(enable){
+		case 0:
+			printk("<-----m51 power off-------->\n");
+			gpio_set_value(bp->ops->bp_en, GPIO_LOW);
+			msleep(2000);		
+			gpio_set_value(bp->ops->bp_power, GPIO_LOW);
+			msleep(1000);
+			break;
+		case 1:
+			printk("<-----m51 power on-------->\n");
+			
+			gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			//msleep(100);		
+			//gpio_set_value(bp->ops->bp_en, GPIO_LOW);
+			msleep(500);
+			gpio_set_value(bp->ops->bp_en, GPIO_HIGH);	
+			msleep(2500);
+			break;
+		case 2:
+			printk("<-----aw706 udate power_en low-------->\n");
+			gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
+			msleep(100);		
+			gpio_set_value(bp->ops->bp_en, GPIO_LOW);
+			msleep(1000);
+			gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
+			break;
+		case 3:
+			printk("<-----aw706 udate power_en high-------->\n");
+			
+			break;
+		default:
+			break;
+	}	
 	return result;
 }
+
+
 static void  ap_wake_bp_work(struct work_struct *work)
 {
 	return;
@@ -96,9 +108,9 @@ static int bp_init(struct bp_private_data *bp)
 		
 	}
 	gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
-	gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);
+//	gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);
 	gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
-	gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);
+	//gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);
 	gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);
 	gpio_direction_input(bp->ops->bp_wakeup_ap);
 	gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);	
@@ -111,7 +123,7 @@ static int bp_init(struct bp_private_data *bp)
 static int bp_reset(struct bp_private_data *bp)
 {
 	printk("ioctrl m51 reset !!! \n");
-	gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
+//	gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
 	msleep(500);
 	//gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
 	gpio_set_value(bp->ops->bp_power, GPIO_LOW);	
@@ -135,7 +147,7 @@ static int bp_shutdown(struct bp_private_data *bp)
 static int bp_suspend(struct bp_private_data *bp)
 {	
 	int result = 0;
-	
+	printk("m51 bp_suspend   !!! \n");
 	bp->suspend_status = 1;
 	//gpio_set_value(bp->ops->ap_ready, GPIO_HIGH);
 	gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
@@ -146,7 +158,7 @@ static int bp_suspend(struct bp_private_data *bp)
 }
 static int bp_resume(struct bp_private_data *bp)
 {
-	
+	printk("m51 bp_resume   !!! \n");
 	bp->suspend_status = 0;	
 	//gpio_set_value(bp->ops->ap_ready, GPIO_LOW);
 	gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
@@ -159,15 +171,15 @@ static int bp_resume(struct bp_private_data *bp)
 struct bp_operate bp_m51_ops = {
 #if defined(CONFIG_ARCH_RK2928)
 	.name			= "m51",
-	.bp_id			= BP_ID_M50,
+	.bp_id			= BP_ID_M51,
 	.bp_bus			= BP_BUS_TYPE_UART,		
 	.bp_pid			= 0,	
 	.bp_vid			= 0,	
 	.bp_power		= RK2928_PIN3_PC2, 	// 3g_power
 	.bp_en			= RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
 	.bp_reset			= RK2928_PIN0_PB6,
-	.ap_ready		= RK2928_PIN0_PD6,	//
-	.bp_ready		= RK2928_PIN0_PD0,
+	.ap_ready		= BP_UNKNOW_DATA,	//
+	.bp_ready		= BP_UNKNOW_DATA,
 	.ap_wakeup_bp	= RK2928_PIN3_PC4,
 	.bp_wakeup_ap	= RK2928_PIN3_PC3,	//
 	.bp_assert		= BP_UNKNOW_DATA,
@@ -189,17 +201,17 @@ struct bp_operate bp_m51_ops = {
 	.private_miscdev	= NULL,
 #elif defined(CONFIG_ARCH_RK30)
 	.name			= "m51",
-	.bp_id			= BP_ID_M50,
+	.bp_id			= BP_ID_M51,
 	.bp_bus			= BP_BUS_TYPE_UART,		
 	.bp_pid			= 0,	
 	.bp_vid			= 0,	
-	.bp_power		= BP_UNKNOW_DATA,	// RK2928_PIN3_PC2, 	// 3g_power
-	.bp_en			= BP_UNKNOW_DATA,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
+	.bp_power		= RK30_PIN0_PC2,	// RK2928_PIN3_PC2, 	// 3g_power
+	.bp_en			= RK30_PIN0_PC0,	// RK2928_PIN3_PC5,//BP_UNKNOW_DATA,	// 3g_en
 	.bp_reset			= BP_UNKNOW_DATA,	// RK2928_PIN0_PB6,
 	.ap_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD6,	//
 	.bp_ready		= BP_UNKNOW_DATA,	// RK2928_PIN0_PD0,
-	.ap_wakeup_bp	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC4,
-	.bp_wakeup_ap	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC3,	//
+	.ap_wakeup_bp	= RK30_PIN3_PC6,	// RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= RK30_PIN0_PC1,	// RK2928_PIN3_PC3,	//
 	.bp_assert		= BP_UNKNOW_DATA,
 	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
 	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
@@ -219,7 +231,7 @@ struct bp_operate bp_m51_ops = {
 	.private_miscdev	= NULL,
 #else
 	.name			= "m51",
-	.bp_id			= BP_ID_M50,
+	.bp_id			= BP_ID_M51,
 	.bp_bus			= BP_BUS_TYPE_UART,		
 	.bp_pid			= 0,	
 	.bp_vid			= 0,	
diff --git a/drivers/misc/bp/chips/sc6610.c b/drivers/misc/bp/chips/sc6610.c
index 684f7fc14920..4ae1cc571f6f 100755
--- a/drivers/misc/bp/chips/sc6610.c
+++ b/drivers/misc/bp/chips/sc6610.c
@@ -166,16 +166,16 @@ struct bp_operate bp_sc6610_ops = {
 	.bp_bus			= BP_BUS_TYPE_UART,		
 	.bp_pid			= 0,	
 	.bp_vid			= 0,	
-	.bp_power		= BP_UNKNOW_DATA,	// RK2928_PIN3_PC2, 	// 3g_power
+	.bp_power		= RK30_PIN0_PC2,	// RK2928_PIN3_PC2, 	// 3g_power
 	.bp_en			= BP_UNKNOW_DATA,	// 3g_en
 	.bp_reset			= BP_UNKNOW_DATA,
 	.ap_ready		= BP_UNKNOW_DATA,	//
 	.bp_ready		= BP_UNKNOW_DATA,
-	.ap_wakeup_bp	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC4,
-	.bp_wakeup_ap	= BP_UNKNOW_DATA,	// RK2928_PIN3_PC3,	//
+	.ap_wakeup_bp	= RK30_PIN3_PC6,	// RK2928_PIN3_PC4,
+	.bp_wakeup_ap	= RK30_PIN0_PC1,	// RK2928_PIN3_PC3,	//
 	.bp_uart_en		= BP_UNKNOW_DATA, 	//EINT9
 	.bp_usb_en		= BP_UNKNOW_DATA, 	//W_disable
-	.bp_assert		= BP_UNKNOW_DATA,	// RK2928_PIN3_PC5,
+	.bp_assert		= RK30_PIN0_PC0,	// RK2928_PIN3_PC5,
 	.trig				= IRQF_TRIGGER_RISING,
 
 	.active			= bp_active,
diff --git a/include/linux/bp-auto.h b/include/linux/bp-auto.h
old mode 100644
new mode 100755
index a2609e352a13..5ecae14e3388
--- a/include/linux/bp-auto.h
+++ b/include/linux/bp-auto.h
@@ -32,7 +32,7 @@ enum bp_id{
 	BP_ID_MW100,	//4 thinkwill MW100 WCDMA
 	BP_ID_TD8801,	//5 spreadtrum SC8803 TD-SCDMA
 	BP_ID_SC6610,	//6 spreadtrum SC6610 GSM
-	BP_ID_M50,	//7 spreadtrum RDA GSM
+	BP_ID_M51,	//7 spreadtrum RDA GSM
 	BP_ID_MT6250,   //8 ZINN M50  EDGE
 	BP_ID_C66A,     //9 ZHIGUAN C66A GSM
 	BP_ID_SEW290,   //10 SCV SEW290 WCDMA