USB charger: Fix the bug that cause USB Reset continually.

This commit is contained in:
wlf
2014-03-22 17:53:49 +08:00
parent c94512d406
commit 78546c0544
5 changed files with 57 additions and 12 deletions

View File

@@ -2640,8 +2640,8 @@ void dwc_pcd_reset(dwc_otg_pcd_t *pcd)
{
dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
dwc_otg_disable_global_interrupts(core_if);
dwc_otg_core_init(core_if);
dwc_otg_pcd_reinit(pcd);
msleep(100);
dwc_otg_core_dev_init(core_if);
dwc_otg_enable_global_interrupts(core_if);
}

View File

@@ -1518,9 +1518,9 @@ static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
/* if usb not connect before ,then start connect */
if( _pcd->vbus_status == USB_BC_TYPE_DISCNT ) {
printk("*******************vbus detect*********************\n");
if( pldata->bc_detect_cb != NULL )
pldata->bc_detect_cb( _pcd->vbus_status = usb_battery_charger_detect(1) );
else
// if( pldata->bc_detect_cb != NULL )
// pldata->bc_detect_cb( _pcd->vbus_status = usb_battery_charger_detect(1) );
// else
_pcd->vbus_status = USB_BC_TYPE_SDP;
if(_pcd->conn_en){
goto connect;
@@ -1540,10 +1540,13 @@ static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
*/
dwc_otg_msc_unlock(_pcd);
_pcd->conn_status++;
if( pldata->bc_detect_cb != NULL )
pldata->bc_detect_cb( _pcd->vbus_status = USB_BC_TYPE_DCP );
else
if( pldata->bc_detect_cb != NULL ){
rk_usb_charger_status = USB_BC_TYPE_DCP;
pldata->bc_detect_cb( _pcd->vbus_status = USB_BC_TYPE_DCP );
}else{
_pcd->vbus_status = USB_BC_TYPE_DCP;
rk_usb_charger_status = USB_BC_TYPE_DCP;
}
/* fail to connect, suspend usb phy and disable clk */
if( pldata->phy_status == USB_PHY_ENABLED ){
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);

29
drivers/usb/dwc_otg_310/usbdev_bc.c Normal file → Executable file
View File

@@ -23,6 +23,7 @@
uoc_field_t *pBC_UOC_FIELDS = NULL;
static void *pGRF_BASE = NULL;
int rk_usb_charger_status = USB_BC_TYPE_DISCNT;
/****** GET REGISTER FIELD INFO FROM Device Tree ******/
@@ -223,7 +224,33 @@ EXPORT_SYMBOL(usb_battery_charger_detect);
int dwc_otg_check_dpdm(bool wait)
{
return usb_battery_charger_detect(wait);
static struct device_node *np = NULL;
if(!np)
np = of_find_node_by_name(NULL, "usb_bc");
if(!np)
return -1;
if(!pGRF_BASE) {
pGRF_BASE = get_grf_base(np);
}
if(of_device_is_compatible(np,"rockchip,ctrl")) {
if(!pBC_UOC_FIELDS)
uoc_init_rk(np);
if(!BC_GET(RK_BC_BVALID))
rk_usb_charger_status = USB_BC_TYPE_DISCNT;
}else if(of_device_is_compatible(np,"synopsys,phy")) {
if(!pBC_UOC_FIELDS)
uoc_init_synop(np);
if(!BC_GET(SYNOP_BC_BVALID))
rk_usb_charger_status = USB_BC_TYPE_DISCNT;
}else if(of_device_is_compatible(np,"inno,phy")) {
if(!pBC_UOC_FIELDS)
uoc_init_inno(np);
}
return rk_usb_charger_status;
}
EXPORT_SYMBOL(dwc_otg_check_dpdm);

View File

@@ -38,6 +38,7 @@
#define USB_REMOTE_WAKEUP (6)
#define USB_IRQ_WAKEUP (7)
extern int rk_usb_charger_status;
/* rk3188 platform data */
extern struct dwc_otg_platform_data usb20otg_pdata_rk3188;
extern struct dwc_otg_platform_data usb20host_pdata_rk3188;
@@ -96,6 +97,7 @@ struct dwc_otg_control_usb {
struct gpio *otg_gpios;
struct clk* hclk_usb_peri;
struct delayed_work usb_det_wakeup_work;
struct delayed_work usb_charger_det_work;
struct wake_lock usb_wakelock;
int remote_wakeup;
int usb_irq_wakeup;

View File

@@ -534,6 +534,10 @@ inline static void do_wakeup(struct work_struct *work)
// rk28_send_wakeup_key();
}
static void usb_battery_charger_detect_work(struct work_struct *work)
{
rk_usb_charger_status = usb_battery_charger_detect(0);
}
/********** handler for bvalid irq **********/
static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
{
@@ -549,6 +553,10 @@ static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
wake_lock_timeout(&control_usb->usb_wakelock, WAKE_LOCK_TIMEOUT);
schedule_delayed_work(&control_usb->usb_det_wakeup_work, HZ/10);
}
rk_usb_charger_status = USB_BC_TYPE_SDP;
schedule_delayed_work(&control_usb->usb_charger_det_work, HZ/10);
return IRQ_HANDLED;
}
@@ -634,7 +642,7 @@ static int otg_irq_detect_init(struct platform_device *pdev)
}
}
}
#if 0
/*register otg_id irq*/
irq = platform_get_irq_byname(pdev, "otg_id");
if(irq > 0){
@@ -694,7 +702,7 @@ static int otg_irq_detect_init(struct platform_device *pdev)
}
}
}
#endif
return ret;
}
@@ -829,6 +837,7 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
control_usb->usb_irq_wakeup = of_property_read_bool(np,
"rockchip,usb_irq_wakeup");
INIT_DELAYED_WORK(&control_usb->usb_charger_det_work, usb_battery_charger_detect_work);
/* disable for debug
hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
if (IS_ERR(hclk_usb_peri)) {
@@ -894,11 +903,15 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
}
gpio_direction_output(control_usb->otg_gpios->gpio, 0);
/* disable for debug
if(usb20otg_get_status(USB_STATUS_BVABLID)){
rk_usb_charger_status = USB_BC_TYPE_SDP;
schedule_delayed_work(&control_usb->usb_charger_det_work, HZ/10);
}
ret = otg_irq_detect_init(pdev);
if (ret < 0)
goto err2;
*/
return 0;
err2: