[Feature][R307][task-view-492][CHARGER] modify charger and usb detect for R307

Change-Id: I1f996b2f68308d500ab5cd703261a097bc79152e
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-ufi-devices.c b/lynq/R307/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-ufi-devices.c
index 0998240..165a587 100755
--- a/lynq/R307/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-ufi-devices.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-ufi-devices.c
@@ -1078,8 +1078,13 @@
 	.name		= "rt-pd-manager",
 	.id		= 0
 };
+#endif
 
-
+#ifdef CONFIG_DWC_DEVICE_GPIO_CHARGER
+static struct platform_device zx29_usb_detect_device = {
+	.name		= "usb_detect",
+	.id		= 0,
+};
 #endif
 
 /* --------------------------------------------------------------------
@@ -1105,6 +1110,9 @@
 #ifdef CONFIG_DWC_OTG_USB
 	&zx29_usb0_device,
 #endif
+#ifdef CONFIG_DWC_DEVICE_GPIO_CHARGER
+	&zx29_usb_detect_device,
+#endif
 #ifdef CONFIG_USB_DWC_OTG_HCD
 	&zx29_usb1_device,
 #endif
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/power/sgm41513_charger.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/power/sgm41513_charger.c
index 795a832..62070f8 100755
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/power/sgm41513_charger.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/power/sgm41513_charger.c
@@ -41,6 +41,9 @@
 //*/
 
 static int ce_enabled = 0;
+static int required_iindpm = 0;
+static int notify_supply_change = 0;
+
 /*
  * The FAULT register is latched by the sgm41513 (except for NTC_FAULT)
  * so the first read after a fault returns the latched value and subsequent
@@ -90,6 +93,19 @@
 
 //struct sgm41513_platform_data *g_platform_data = NULL;
 struct sgm41513_dev_info *g_bdi = NULL;
+static int g_last_real_voltage = 0;
+int can_cc_hardreset(void) {
+	int ret;
+	if (g_bdi == NULL)
+	    return 0;
+	if (g_bdi->charger.type == POWER_SUPPLY_PCAC__AC)
+		ret = g_last_real_voltage > 3500;
+	else
+		ret = ce_enabled == 0 ? (get_adc1_voltage() > 3500) : (g_last_real_voltage > 3500);
+	
+	printk("cy: can_cc_hardreset %d, g_last_real_voltage %d, voltage %d\n", ret, g_last_real_voltage, get_adc1_voltage());
+	return ret;
+}
 
 /* REG01[2:0] (ISET_DCIN) in mAh */
 static const int sgm41513_in_ilimit_values[] = {
@@ -492,7 +508,7 @@
 	int status=POWER_SUPPLY_STATUS_UNKNOWN;
 	int ret=0;
 
-	printk("cy: sgm41513_charger_get_status 3\n");
+	//printk("cy: sgm41513_charger_get_status 3\n");
 	//dump_sgm_regs(bdi->client);
 	//set_typec_try_role(0);
 	//typec_pwr_role_set1();
@@ -519,7 +535,7 @@
 	}
 	else if(chrg_stat == 0)
 	{
-		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		status = POWER_SUPPLY_STATUS_DISCHARGING;
 	}
 	else if(chrg_stat == 3)
 	{
@@ -529,7 +545,7 @@
 	if (!ret)
 		val->intval = status;
 
-	printk("cy: sgm41513_charger_get_status exit\n");
+	printk("cy: sgm41513_charger_get_status %d exit\n", val->intval);
 	return ret;
 }
 
@@ -738,6 +754,48 @@
 	}
 }
 
+static set_charge_current(struct sgm41513_dev_info *bdi)
+{
+	int ret;
+	u8 last_curr = -1;
+	u8 need_curr = -1;
+	
+	ret = sgm41513_read_mask(bdi,SGM41513_REG02,
+		SGM41513_REG02_ICHG_MASK,
+		SGM41513_REG02_ICHG_SHIFT,
+		&last_curr);
+
+	ret = get_adc2_voltage();
+	pr_err("%s voltage %d\n",__func__, ret);
+	if (ret >1284 || ret < 422){ // bellow 0 deg or above 60 deg, curr set to 0
+		need_curr = 0x0;
+		printk("cy: need 0\n");
+	} else if (ret > 1057) { // above 0 deg and bellow 15 deg, curr set to 500mA
+		need_curr = 0x1F;
+		printk("cy: need 1F\n");
+	} else if (ret > 623 && ret <= 1057) { // above 15 deg and bellow 45 dec, curr set to 1.26A
+		need_curr = 0x2C;
+		printk("cy: need 2C\n");
+	} else if (ret >= 422 && ret <= 623) { // above 45 deg and bellow 60 dec, curr set to 0.6A, max vol set to 4.1V
+		need_curr = 0x21;
+		printk("cy: need 21\n");
+		//sgm41513_charger_set_voltage(bdi, &val);
+	}
+	else {
+		need_curr = -1;
+		printk("cy: unkown condition\n");
+	}
+	printk("cy: last_curr %d, need_curr %d\n",last_curr, need_curr);
+	if (need_curr != -1 && last_curr != need_curr)
+	{
+		ret = sgm41513_write_mask(bdi,SGM41513_REG02,
+			SGM41513_REG02_ICHG_MASK,
+			SGM41513_REG02_ICHG_SHIFT,
+			need_curr);
+		last_curr = need_curr;
+	}
+}
+
 static int sgm41513_charger_set_charger_config(struct sgm41513_dev_info *bdi,const union power_supply_propval *val)
 {
 	int ret;
@@ -763,18 +821,27 @@
 
 	if (enable_charge.intval == 1)
 	{
+		set_charge_current(bdi);
 		ret = sgm41513_write_mask(bdi, SGM41513_REG00,
 			SGM41513_REG00_EN_HIZ_MASK, 
 			SGM41513_REG00_EN_HIZ_SHIFT, 0);
 	}
 
-	printk("cy: sgm41513_charger_set_charger_config 2\n");
-	 ret = sgm41513_write_mask(bdi, SGM41513_REG01,
+	ret = sgm41513_write_mask(bdi, SGM41513_REG01,
 			SGM41513_REG01_CHG_CONFIG_MASK,
 			SGM41513_REG01_CHG_CONFIG_SHIFT, enable_charge.intval );  /*0:disable 1:enable*/
 
 	 set_ce_gpio(enable_charge.intval);
 	 
+	if (enable_charge.intval == 0)
+	{
+		power_supply_changed(&bdi->charger);
+	}
+	else{
+		notify_supply_change = 1; //notify later		
+		cancel_delayed_work_sync(&g_bdi->charge_monitor_work);
+		schedule_delayed_work(&g_bdi->charge_monitor_work, HZ*2);
+	}
 	 return ret;
 }
 
@@ -871,6 +938,12 @@
 		break;
 	case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
 		printk("cy: POWER_SUPPLY_PROP_PD_CURRENT_MAX %d\n", val->intval);
+		if (val->intval > 100 && val->intval <= 3000)
+		{
+			required_iindpm = (val->intval-100)/100;
+			cancel_delayed_work_sync(&bdi->charge_monitor_work);
+			schedule_delayed_work(&bdi->charge_monitor_work, HZ/2);
+		}
 		break;
 	case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
 		printk("cy: POWER_SUPPLY_PROP_PD_VOLTAGE_MIN %d\n", val->intval);
@@ -880,11 +953,14 @@
 		break;
 	case POWER_SUPPLY_PROP_PD_ACTIVE:
 		printk("cy: POWER_SUPPLY_PROP_PD_ACTIVE %d\n", val->intval);
+		if (val->intval == 0)
+		{
+			ret = sgm41513_charger_set_charger_config(bdi, val);
+		}
 		break;
-    	case POWER_SUPPLY_PROP_CHARGE_ENABLED:
+    case POWER_SUPPLY_PROP_CHARGE_ENABLED:
 		printk("cy: POWER_SUPPLY_PROP_CHARGE_ENABLED\n");
-        	ret = sgm41513_charger_set_charger_config(bdi, val);			
-		power_supply_changed(&bdi->charger);
+        	ret = sgm41513_charger_set_charger_config(bdi, val);
         	break;
 	case POWER_SUPPLY_PROP_USB_OTG:
 		printk("cy: POWER_SUPPLY_PROP_USB_OTG\n");
@@ -1499,7 +1575,7 @@
 	ret = sgm41513_write_mask(bdi,SGM41513_REG03,
 		SGM41513_REG03_ITERM_MASK,
 		SGM41513_REG03_ITERM_SHIFT,
-		0xd);
+		0x6); //50mA
 	if (ret < 0){
 		pr_err("cy: line %d ret %d\n", __LINE__, ret);
 		//goto out;
@@ -1531,7 +1607,7 @@
 		goto out;
 	}
 	*/
-	voltage_val.intval = 4400;
+	voltage_val.intval = 4200;
 	ret = sgm41513_charger_set_voltage(bdi,&voltage_val);
 	if (ret < 0){
 		pr_err("cy: line %d ret %d\n", __LINE__, ret);
@@ -1551,7 +1627,7 @@
 	ret = sgm41513_write_mask(bdi,SGM41513_REG02,
 		SGM41513_REG02_BOOST_LIM_MASK,
 		SGM41513_REG02_BOOST_LIM_SHIFT,
-		0x1);
+		0x0);
 	if (ret < 0){
 		pr_err("cy: line %d ret %d\n", __LINE__, ret);
 		goto out;
@@ -1567,8 +1643,8 @@
 	}
 	
 	dump_sgm_regs(bdi->client);
-	printk("cy: get_adc1_voltage %d\n", ret);
 	voltage = get_adc1_voltage();
+	printk("cy: get_adc1_voltage %d\n", voltage);
 	//*
 	if (voltage < 3800) {
 		set_typec_try_role(0); // try dongle
@@ -1952,24 +2028,26 @@
 
 }
 
-static T_TYPE_USB_DETECT g_chg_type = 0;
 void sgm41513_charge_typedet(T_TYPE_USB_DETECT chg_type)
 {
 	int ret;
+	u8 otg_flag;
 	union power_supply_propval val = {.intval = 0};
 	#ifdef DBG_CHARGE
 	printk(KERN_INFO"charge type is %d in\n",chg_type);
 	#endif
 	func_trace();
-	g_chg_type  = chg_type;
 #if 1
 	if(TYPE_ADAPTER == chg_type){
 		
 		printk(KERN_INFO"chg type is TYPE_ADAPTER\n");
-		//gpio_direction_output(120, 0);
-		//ce_enabled = 1;
+		set_typec_try_role(0);
 		val.intval = 1;
 		 /*set the DCIN Current = 2.4A*/
+		
+		g_last_real_voltage = get_adc1_voltage();
+		required_iindpm = 0x17;
+		/*
 		ret = sgm41513_write_mask(g_bdi,SGM41513_REG00,
 					   SGM41513_REG00_IINDPM_MASK,
 					   SGM41513_REG00_IINDPM_SHIFT,
@@ -1977,17 +2055,23 @@
 		if (ret < 0){
 			printk(KERN_INFO"write REG_00 fault\n");
 		}
+		*/
 		g_bdi->charger.type = POWER_SUPPLY_PCAC__AC;
 		dump_sgm_regs(g_bdi->client);
 		sgm41513_charger_set_charger_config(g_bdi, &val);
 	}
 	
-	else {
-		//ret = get_typec_role();
-		//printk(KERN_INFO"chgage type is TYPE_PC %d\n", ret);
-		gpio_direction_output(120, 1);
-		ce_enabled = 0;
+	else if (TYPE_COMPUTER == chg_type) {
+		g_bdi->charger.type = POWER_SUPPLY_PCAC__PC;
 		
+		ret = sgm41513_read_mask(g_bdi, SGM41513_REG01,
+				SGM41513_REG01_OTG_CONFIG_MASK,
+				SGM41513_REG01_OTG_CONFIG_SHIFT, &otg_flag);
+		
+		if (ret == 0 && otg_flag != 0)
+		{
+			return;
+		}
 		 /*set the DCIN Current = 450mA*/
 		ret = sgm41513_write_mask(g_bdi,SGM41513_REG00,
 					   SGM41513_REG00_IINDPM_MASK,
@@ -1997,15 +2081,9 @@
 			printk(KERN_INFO"write REG_01 fault\n");
 		}
 
-		/*
-		voltage = get_adc1_voltage();
-		if (voltage > 3500) {
-			ret = sgm41513_write_mask(bdi,SGM41513_REG00, SGM41513_REG00_EN_HIZ_MASK, 
-				SGM41513_REG00_EN_HIZ_SHIFT, 0x1);
-		}
-		*/
-		g_bdi->charger.type = POWER_SUPPLY_PCAC__PC;
 		dump_sgm_regs(g_bdi->client);
+		val.intval = 1;
+		sgm41513_charger_set_charger_config(g_bdi, &val);
 	}
 		
 		//#ifdef CONFIG_CHARGER_SGM41513_EVB
@@ -2209,8 +2287,8 @@
 	struct delayed_work *charge_monitor_work = NULL;
 	union power_supply_propval val = {.intval = 4100};
 	//static u8 last_chg_method = 0;
-	u8 last_curr = -1;
-	u8 need_curr = -1;
+	u8 vbus_stat = -1;
+	u8 otg_flag = -1;
 
 	charge_monitor_work = container_of(work, struct delayed_work, work);
 	if(charge_monitor_work == NULL) {
@@ -2223,43 +2301,44 @@
 		return ;
 	}
 	
-	ret = sgm41513_read_mask(bdi,SGM41513_REG02,
-		SGM41513_REG02_ICHG_MASK,
-		SGM41513_REG02_ICHG_SHIFT,
-		&last_curr);
-
-	ret = get_adc2_voltage();
-	pr_err("%s voltage %d\n",__func__, ret);
-	if (ret >1284 || ret < 422){ // bellow 0 deg or above 60 deg, curr set to 0
-		need_curr = 0x0;
-		printk("cy: need 0\n");
-	} else if (ret > 1057) { // above 0 deg and bellow 15 deg, curr set to 500mA
-		need_curr = 0x1f;
-		printk("cy: need 1f\n");
-	} else if (ret > 623 && ret <= 1057) { // above 15 deg and bellow 45 dec, curr set to 2A
-		need_curr = 0x34;
-		printk("cy: need 34\n");
-	} else if (ret >= 422 && ret <= 623) { // above 45 deg and bellow 60 dec, curr set to 1A, max vol set to 4.1V
-		need_curr = 0x27;
-		printk("cy: need 27\n");
-		sgm41513_charger_set_voltage(bdi, &val);
-	}
-	else {
-		need_curr = -1;
-		printk("cy: unkown condition\n");
-	}
-	printk("cy: last_curr %d, need_curr %d\n",last_curr, need_curr);
-	if (need_curr != -1 && last_curr != need_curr)
+	if (notify_supply_change == 1)
 	{
-		ret = sgm41513_write_mask(bdi,SGM41513_REG02,
-			SGM41513_REG02_ICHG_MASK,
-			SGM41513_REG02_ICHG_SHIFT,
-			need_curr);
-		last_curr = need_curr;
+		notify_supply_change = 0;
+		power_supply_changed(&bdi->charger);
 	}
+
+	ret = sgm41513_read_mask(bdi, SGM41513_REG01,
+			SGM41513_REG01_OTG_CONFIG_MASK,
+			SGM41513_REG01_OTG_CONFIG_SHIFT, &otg_flag);
+	
+	if (ret == 0 && otg_flag != 0)
+	{
+		return;
+	}
+
+	if (required_iindpm != 0) 
+	{
+		ret = sgm41513_read_mask(bdi,SGM41513_REG08,
+			SGM41513_REG08_VBUS_STAT_MASK,
+			SGM41513_REG08_VBUS_STAT_SHIFT,
+			&vbus_stat);
+		if (ret == 0 && vbus_stat != 0)
+		{
+			ret = sgm41513_write_mask(bdi,SGM41513_REG00,
+				SGM41513_REG00_IINDPM_MASK,
+				SGM41513_REG00_IINDPM_SHIFT,
+				required_iindpm);
+			if (ret == 0 ) {
+				required_iindpm = 0;
+			}
+		}
+	}
+
+	set_charge_current(bdi);
+
 	dump_sgm_regs(bdi->client);
 OUT:	
-	schedule_delayed_work(&bdi->charge_monitor_work, 10*HZ);
+	schedule_delayed_work(&bdi->charge_monitor_work, required_iindpm == 0 ? (10 * HZ) : HZ/2);
 }
 
 static int sgm41513_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -2395,7 +2474,7 @@
 		INIT_DELAYED_WORK(&bdi->boostWorkStruct,sgm41513_boost_workstruct_callback);
 		INIT_DELAYED_WORK(&bdi->charge_monitor_work, charger_monitor_work_func);
 		
-		schedule_delayed_work(&bdi->charge_monitor_work,100);
+		//schedule_delayed_work(&bdi->charge_monitor_work,100);
 		//queue_delayed_work(bdi->boostQueue,&bdi->boostWorkStruct,20000);
 	#ifdef DBG_CHARGE
 		printk(KERN_INFO "setup_workqueue.\n");
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c
old mode 100644
new mode 100755
index 6d887bf..ed3c2aa
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_chg_identify.c
@@ -176,12 +176,15 @@
 void dwc_chg_Regcallback(usb_detect_callback	fn)
 {
 	USBHAL_DBG("dwc_chg_Regcallback");
+	usb_detect_callback org = detect_fn;
 	detect_fn = fn;
+	if (org != NULL) //thread is running, notify the status
+		detect_fn(g_plug_in);
 }
 int detected_charger(void)
 {
 #ifdef CONFIG_DWC_DEVICE_GPIO_CHARGER
-	return 1;
+	return usb_plugin;
 #endif
 	if(detect_fn == NULL)
 		return 1;
@@ -1043,10 +1046,10 @@
 /*GPIOºÍÍⲿÖжϺŸù¾ÝÏîĿʵ¼ÊÇé¿öÐÞ¸Ä
  *´Ë´¦Îª²Î¿¼´úÂë
  */
-#define USB_GPIO ZX29_GPIO_52
-#define USB_GPIO_FUNC_GPIO GPIO52_GPIO52
-#define USB_GPIO_FUNC_EXT_INT GPIO52_EXT_INT5
-#define USB_DT_INT  PCU_EX5_INT
+#define USB_GPIO ZX29_GPIO_125
+#define USB_GPIO_FUNC_GPIO GPIO125_GPIO125
+#define USB_GPIO_FUNC_EXT_INT GPIO125_EXT_INT14
+#define USB_DT_INT  PCU_EX14_INT
 
 int Usb_Detect_Val(void)
 {
@@ -1072,6 +1075,8 @@
     int irq_num;
     int retval;
 	int value;
+	int cnt=0;
+	int last_val = -1;
 	unsigned int gpio_enable = 0;
 	struct sched_param param = { .sched_priority = 2 };
 	param.sched_priority= 33;
@@ -1085,8 +1090,19 @@
 	//5.23
 	zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_GPIO);
 	gpio_direction_input(USB_GPIO);
-	msleep(5);
-	value = gpio_get_value(USB_GPIO);
+
+	while (cnt < 10)
+	{
+		msleep(10);
+		value = gpio_get_value(USB_GPIO);
+		if (last_val != value)
+		{
+			last_val = value;
+			cnt = 0;
+		}
+		else
+			cnt++;
+	}
 	printk("%s,value:%d\n", __func__,value);
 	zx29_gpio_config(USB_GPIO,USB_GPIO_FUNC_EXT_INT);
 	
@@ -1094,19 +1110,19 @@
 	{
 	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_FALLING);
 	  pcu_int_clear(USB_DT_INT);
-	  if(usb_plugin == 1){
-	 	 dwc_otg_disconnect();
-	  	dwc_otg_usb_chg_remove(); //not plug in;
-	  	usb_plugin = 0;
-	  }
+	  if(usb_plugin == 0){
+	  	dwc_otg_usb_chg_detect(); //plug in;
+	  	usb_plugin = 1;
+	  }	
 	}
 	else
 	{
 	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_RISING);
-	  pcu_int_clear(USB_DT_INT); 
-	  if(usb_plugin == 0){
-	  	dwc_otg_usb_chg_detect(); //plug in;
-	  	usb_plugin = 1;
+	  pcu_int_clear(USB_DT_INT);
+	  if(usb_plugin == 1){
+	 	 dwc_otg_disconnect();
+	  	dwc_otg_usb_chg_remove(); //not plug in;
+	  	usb_plugin = 0;
 	  }
 	}
 	printk(KERN_INFO"%s,value:%d,end\n", __func__,value);
@@ -1144,13 +1160,13 @@
 #if 1	
 	if(value == 1)
 	{
-	  usb_plugin = 0;
+	  dwc_otg_usb_chg_detect(); //plug in;
+	  usb_plugin = 1;
 	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_FALLING);
 	}
 	else
 	{
-	  dwc_otg_usb_chg_detect(); //plug in;
-	  usb_plugin = 1;
+	  usb_plugin = 0;
 	  zx29_gpio_set_inttype(USB_GPIO,IRQ_TYPE_EDGE_RISING);
 	}
 #endif	
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/class.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/class.c
old mode 100644
new mode 100755
index a9e7a13..47a9cef
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/class.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/class.c
@@ -753,8 +753,8 @@
 	struct typec_partner *partner;
 	int ret;
 
-	printk("cy: typec_register_partner\n");
-	dwc_otg_chg_inform_type(0);
+	printk("cy: typec_register_partner %d\n", desc->usb_pd);
+	//dwc_otg_chg_inform_type(0);
 	partner = kzalloc(sizeof(*partner), GFP_KERNEL);
 	if (!partner)
 		return ERR_PTR(-ENOMEM);
@@ -796,8 +796,8 @@
  */
 void typec_unregister_partner(struct typec_partner *partner)
 {
-	printk("cy: typec_unregister_partner\n");
-	dwc_otg_chg_inform_type(1);
+	//printk("cy: typec_unregister_partner\n");
+	//dwc_otg_chg_inform_type(1);
 
 	if (!IS_ERR_OR_NULL(partner))
 		device_unregister(&partner->dev);
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine.c
old mode 100644
new mode 100755
index 6e55798..0517f96
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine.c
@@ -1139,7 +1139,7 @@
 
 static inline bool pd_check_pd30_tx_ready(struct pd_port *pd_port)
 {
-	printk("cy: pd_check_pd30_tx_ready\n");
+	//printk("cy: pd_check_pd30_tx_ready\n");
 #ifdef CONFIG_USB_PD_PE_SINK
 	if (pd_port->pe_pd_state == PE_SNK_READY)
 		return pd_check_sink_tx_ok(pd_port);
@@ -1160,7 +1160,7 @@
 #else
 static inline bool pd_check_pd20_tx_ready(struct pd_port *pd_port)
 {
-	printk("cy: pd_check_pd20_tx_ready %d sink %d, src %d test %d\n", pd_port->pe_pd_state, PE_SNK_READY, PE_SRC_READY, PE_SNK_DISCOVERY);
+	//printk("cy: pd_check_pd20_tx_ready %d sink %d, src %d test %d\n", pd_port->pe_pd_state, PE_SNK_READY, PE_SRC_READY, PE_SNK_DISCOVERY);
 	switch (pd_port->pe_pd_state) {
 #ifdef CONFIG_USB_PD_PE_SINK
 	case PE_SNK_READY:
@@ -1199,7 +1199,7 @@
 static inline bool pd_check_tx_ready(struct pd_port *pd_port)
 {
 	/* VDM BUSY : Waiting for response */
-	printk("cy: pd_check_tx_ready %d\n", pd_port->pe_data.vdm_state_timer);
+	//printk("cy: pd_check_tx_ready %d\n", pd_port->pe_data.vdm_state_timer);
 	if (pd_port->pe_data.vdm_state_timer)
 		return false;
 
@@ -1258,12 +1258,12 @@
 
 	if (ret == 0) {
 		from_pe = PD_TCP_FROM_TCPM;
-		printk("cy: pd_try_get_active_event real try\n");
+		//printk("cy: pd_try_get_active_event real try\n");
 		ret = pd_try_get_deferred_tcp_event(pd_port);
 	}
 	else{
-		printk("cy: from_pe: %d, evt:%d, reaction:0x%x\n",
-			from_pe, ret, pd_port->pe_data.dpm_reaction_id);
+		//printk("cy: from_pe: %d, evt:%d, reaction:0x%x\n",
+			//from_pe, ret, pd_port->pe_data.dpm_reaction_id);
 	}
 
 #if DPM_DBG_ENABLE
@@ -1311,9 +1311,9 @@
 	if (pd_try_get_vdm_event(tcpc, pd_event))
 		return PE_NEW_EVT_VDM;
 
-	printk("cy: pd_try_get_next_event try lock\n");
+	//printk("cy: pd_try_get_next_event try lock\n");
 	mutex_lock(&pd_port->pd_lock);
-	printk("cy: pd_try_get_next_event lock ok\n");
+	//printk("cy: pd_try_get_next_event lock ok\n");
 	ret = pd_try_get_active_event(tcpc, pd_event);
 	mutex_unlock(&pd_port->pd_lock);
 
@@ -1356,11 +1356,11 @@
 	struct pd_event *pd_event = NULL;
 	pd_port = &tcpc->pd_port;
 	pd_event = pd_get_curr_pd_event(pd_port);
-	printk("cy: enter pd_policy_engine_run %08x\n", (int)pd_event);
+	//printk("cy: enter pd_policy_engine_run %08x\n", (int)pd_event);
 
-	printk("cy: pd_try_get_next_event begin\n");
+	//printk("cy: pd_try_get_next_event begin\n");
 	ret = pd_try_get_next_event(tcpc, pd_event);
-	printk("cy: pd_try_get_next_event end\n");
+	//printk("cy: pd_try_get_next_event end\n");
 	if (ret == PE_NEW_EVT_NULL) {
 		loop = false;
 		goto out;
@@ -1370,11 +1370,11 @@
 
 	pd_port->curr_is_vdm_evt = (ret == PE_NEW_EVT_VDM);
 
-	printk("cy: pd_handle_event\n");
+	//printk("cy: pd_handle_event\n");
 	pd_handle_event(pd_port, pd_event);
-	printk("cy: pd_handle_dpm_immediately\n");
+	//printk("cy: pd_handle_dpm_immediately\n");
 	pd_handle_dpm_immediately(pd_port, pd_event);
-	printk("cy: to unlock\n");
+	//printk("cy: to unlock\n");
 
 	mutex_unlock(&pd_port->pd_lock);
 out:
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine_snk.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine_snk.c
old mode 100644
new mode 100755
index f9ade6e..5e47afd
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine_snk.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/pd_policy_engine_snk.c
@@ -159,8 +159,11 @@
 	pe_power_ready_entry(pd_port);
 }
 
+extern int can_cc_hardreset(void);
 void pe_snk_hard_reset_entry(struct pd_port *pd_port)
 {
+	if( !can_cc_hardreset())
+		return;
 	pd_send_hard_reset(pd_port);
 }
 
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/rt_pd_manager.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/rt_pd_manager.c
old mode 100644
new mode 100755
index fe3d1cf..5158daa
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/rt_pd_manager.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/rt_pd_manager.c
@@ -85,19 +85,41 @@
                             enum power_supply_property psp,
                             union power_supply_propval *val)
 {
+	int ret;
 	if (psy == NULL)
 		return -1;
 	printk("cy: power_supply_get_property \n");
-	return psy->get_property(psy, psp, val);
+	ret = psy->get_property(psy, psp, val);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+		printk("cy: psp %d old value %d\n", psp, val->intval);
+		val->intval *= 1000;
+		break;
+	default:
+		break;
+	}
+	return ret;
 }
 
 static int power_supply_set_property(struct power_supply *psy,
                             enum power_supply_property psp,
                             const union power_supply_propval *val)
 {
+	union power_supply_propval real_val = {.intval = 0};
 	if (psy == NULL)
 		return -1;
 	printk("cy: power_supply_set_property\n");
+	
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
+	case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
+	case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX:
+		printk("cy: psp %d old value %d\n", psp, val->intval);
+		real_val.intval = val->intval / 1000;
+		return psy->set_property(psy, psp, &real_val);
+	default:
+		break;
+	}
 	return psy->set_property(psy, psp, val);
 }
 
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpc_rt1711h.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpc_rt1711h.c
index 2c18fe6..a654b89 100755
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpc_rt1711h.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpc_rt1711h.c
@@ -504,8 +504,8 @@
 #endif /* CONFIG_TCPC_VSAFE0V_DETECT_IC */
 
 #ifdef CONFIG_TYPEC_CAP_RA_DETACH
-	if (tcpc->tcpc_flags & TCPC_FLAGS_CHECK_RA_DETACHE)
-		rt_mask |= RT1711H_REG_M_RA_DETACH;
+	//if (tcpc->tcpc_flags & TCPC_FLAGS_CHECK_RA_DETACHE)
+		//rt_mask |= RT1711H_REG_M_RA_DETACH;
 #endif /* CONFIG_TYPEC_CAP_RA_DETACH */
 
 #ifdef CONFIG_TYPEC_CAP_LPM_WAKEUP_WATCHDOG
@@ -940,14 +940,14 @@
 		return ret;
 
 	*alert = (uint16_t) ret;
-	printk("cy: reg 10-11 %04x\n", (uint16_t) ret);
+	//printk("cy: reg 10-11 %04x\n", (uint16_t) ret);
 
 #ifdef CONFIG_TCPC_VSAFE0V_DETECT_IC
 	ret = rt1711_i2c_read8(tcpc, RT1711H_REG_RT_INT);
 	if (ret < 0)
 		return ret;
 
-	printk("cy: reg 10-11 %02x\n", (uint8_t) ret);
+	//printk("cy: reg 0x98 %02x\n", (uint8_t) ret);
 	v2 = (uint8_t) ret;
 	*alert |= v2 << 16;
 #endif
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_timer.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_timer.c
old mode 100644
new mode 100755
index f08cc2e..0cd3eb0
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_timer.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_timer.c
@@ -259,7 +259,8 @@
 DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_PS_TRANSITION, 450, 550),
 DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_SENDER_RESPONSE, 24, 30),
 DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_SINK_REQUEST, 100, 100),
-DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_SINK_WAIT_CAP, 310, 620),
+//DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_SINK_WAIT_CAP, 310, 620),
+DECL_TCPC_TIMEOUT(PD_TIMER_SINK_WAIT_CAP, 620),
 DECL_TCPC_TIMEOUT_RANGE(PD_TIMER_SOURCE_CAPABILITY, 100, 200),
 
 DECL_TCPC_TIMEOUT(PD_TIMER_SOURCE_START, 20),
diff --git a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_typec.c b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_typec.c
old mode 100644
new mode 100755
index 7480ce8..0ae8f4b
--- a/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_typec.c
+++ b/lynq/R307/ap/os/linux/linux-3.4.x/drivers/usb/typec/tcpc/tcpci_typec.c
@@ -660,8 +660,13 @@
 	typec_postpone_state_change(tcpc);
 }
 
+extern int can_cc_hardreset(void);
 static inline void typec_error_recovery_entry(struct tcpc_device *tcpc)
 {
+	if (!can_cc_hardreset())
+	{
+		return;
+	}
 	typec_cc_open_entry(tcpc, typec_errorrecovery);
 	tcpc_reset_typec_debounce_timer(tcpc);
 	tcpc_enable_timer(tcpc, TYPEC_TIMER_ERROR_RECOVERY);
@@ -832,6 +837,8 @@
 static inline bool typec_role_is_try_src(
 	struct tcpc_device *tcpc)
 {
+	if (tcpc->desc.role_def != 3)
+		return false;
 	if (tcpc->typec_role != TYPEC_ROLE_TRY_SRC)
 		return false;
 
@@ -1635,11 +1642,11 @@
 		TYPEC_NEW_STATE(typec_attachwait_snk);
 	else {
 		/* Advertise Rp level before Attached.SRC Ellisys 3.1.6359 */
-		printk("cy: typec_attach_wait_entry typec_local_rp_level %d\n", tcpc->typec_local_rp_level);
+		//printk("cy: typec_attach_wait_entry typec_local_rp_level %d\n", tcpc->typec_local_rp_level);
 		tcpci_set_cc(tcpc, tcpc->typec_local_rp_level);
-		printk("cy: typec_attach_wait_entry tcpci_set_cc finish\n");
+		//printk("cy: typec_attach_wait_entry tcpci_set_cc finish\n");
 		TYPEC_NEW_STATE(typec_attachwait_src);
-		printk("cy: typec_attach_wait_entry TYPEC_NEW_STATE finish\n");
+		//printk("cy: typec_attach_wait_entry TYPEC_NEW_STATE finish\n");
 	}
 
 	tcpc_enable_timer(tcpc, TYPEC_TIMER_CCDEBOUNCE);
@@ -1744,7 +1751,7 @@
 
 	tcpc->typec_cable_only = false;
 
-	printk("cy: typec_is_cc_attach typec_attach_old %d, cc_res %d, typec_local_cc %d\n", tcpc->typec_attach_old, cc_res, tcpc->typec_local_cc);
+	//printk("cy: typec_is_cc_attach typec_attach_old %d, cc_res %d, typec_local_cc %d\n", tcpc->typec_attach_old, cc_res, tcpc->typec_local_cc);
 #ifdef RICHTEK_PD_COMPLIANCE_FAKE_RA_DETACH
 	if (tcpc->typec_attach_old == TYPEC_ATTACHED_SRC
 		&& (cc_res == TYPEC_CC_VOLT_RA) &&
@@ -1818,7 +1825,7 @@
 		break;
 	}
 
-	printk("cy: typec_is_cc_attach ret %d\n", cc_attach);
+	//printk("cy: typec_is_cc_attach ret %d\n", cc_attach);
 	return cc_attach;
 }
 
@@ -2298,7 +2305,7 @@
 {
 	int ret = 0;
 
-	printk("cy: tcpc_typec_handle_timeout %d\n", timer_id);
+	//printk("cy: tcpc_typec_handle_timeout %d\n", timer_id);
 #ifdef CONFIG_TYPEC_CAP_TRY_STATE
 	if (timer_id == TYPEC_TRY_TIMER_DRP_TRY)
 		return typec_handle_drp_try_timeout(tcpc);
@@ -2431,7 +2438,7 @@
 #endif	/* CONFIG_TYPEC_CHECK_LEGACY_CABLE */
 	}
 
-	printk("cy: tcpc_typec_handle_timeout ret %d\n", ret);
+	//printk("cy: tcpc_typec_handle_timeout ret %d\n", ret);
 	return ret;
 }
 
diff --git a/lynq/R307/ap/project/zx297520v3/prj_cpe_min/config/normal/config.linux b/lynq/R307/ap/project/zx297520v3/prj_cpe_min/config/normal/config.linux
index 7b26567..d483a00 100755
--- a/lynq/R307/ap/project/zx297520v3/prj_cpe_min/config/normal/config.linux
+++ b/lynq/R307/ap/project/zx297520v3/prj_cpe_min/config/normal/config.linux
@@ -1459,7 +1459,7 @@
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 CONFIG_DWC_OTG_USB=y
 CONFIG_DWC_DEVICE_ONLY=y
-# CONFIG_DWC_DEVICE_GPIO_CHARGER is not set
+CONFIG_DWC_DEVICE_GPIO_CHARGER=y
 
 #
 # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may