int usb_cable_type_detect(unsigned int chgr_type) { struct i2c_client *client = charger->client; int success = 0; mutex_lock(&charger->usb_lock); if (chgr_type == CHARGER_NONE) { SMB_NOTICE("INOK=H\n"); if (wpc_en) { if (disable_DCIN) { SMB_NOTICE("enable wpc_pok, enable DCIN\n"); disable_DCIN = false; enable_irq_wake(gpio_to_irq(charger->wpc_pok_gpio)); enable_irq(gpio_to_irq(charger->wpc_pok_gpio)); gpio_set_value(charger->wpc_en1, 0); gpio_set_value(charger->wpc_en2, 0); } } success = bq27541_battery_callback(non_cable); touch_callback(non_cable); } else { SMB_NOTICE("INOK=L\n"); if (chgr_type == CHARGER_SDP) { SMB_NOTICE("Cable: SDP\n"); smb345_vflt_setting(); success = bq27541_battery_callback(usb_cable); touch_callback(usb_cable); } else { if (chgr_type == CHARGER_CDP) { SMB_NOTICE("Cable: CDP\n"); } else if (chgr_type == CHARGER_DCP) { SMB_NOTICE("Cable: DCP\n"); } else if (chgr_type == CHARGER_OTHER) { SMB_NOTICE("Cable: OTHER\n"); } else if (chgr_type == CHARGER_ACA) { SMB_NOTICE("Cable: ACA\n"); } else { SMB_NOTICE("Cable: TBD\n"); smb345_vflt_setting(); success = bq27541_battery_callback(usb_cable); touch_callback(usb_cable); goto done; } smb345_set_InputCurrentlimit(client, 1200); smb345_vflt_setting(); success = bq27541_battery_callback(ac_cable); touch_callback(ac_cable); if (wpc_en) { if (delayed_work_pending(&charger->wireless_set_current_work)) cancel_delayed_work(&charger->wireless_set_current_work); if (!disable_DCIN) { SMB_NOTICE("AC cable detect, disable wpc_pok, disable DCIN"); disable_DCIN = true; disable_irq(gpio_to_irq(charger->wpc_pok_gpio)); disable_irq_wake(gpio_to_irq(charger->wpc_pok_gpio)); gpio_set_value(charger->wpc_en1, 1); gpio_set_value(charger->wpc_en2, 1); mdelay(200); if (wireless_on) wireless_reset(); } } } } done: mutex_unlock(&charger->usb_lock); return success; }
/* workqueue function */ static int cable_type_detect(void) { struct i2c_client *client = charger->client; u8 retval; int success = 0; int ac_ok = GPIO_AC_OK; /* printk("cable_type_detect %d %lu %d %x jiffies=%lu %lu+\n", charger->old_cable_type, charger->time_of_1800mA_limit, gpio_get_value(gpio), time_after(charger->time_of_1800mA_limit+(4*HZ), jiffies ), jiffies, charger->time_of_1800mA_limit+(ADAPTER_PROTECT_DELAY*HZ)); */ mutex_lock(&charger->cable_lock); if ((charger->old_cable_type == ac_cable) && charger->time_of_1800mA_limit && gpio_get_value(ac_ok) && time_after(charger->time_of_1800mA_limit+ ADAPTER_PROTECT_DELAY, jiffies)) { smb347_set_InputCurrentlimit(client, 900); charger->test_1800mA_fail = 1; queue_delayed_work(smb347_wq, &charger->test_fail_clear_work, 1*HZ); } if (gpio_get_value(ac_ok)) { printk(KERN_INFO "INOK=H\n"); charger->cur_cable_type = non_cable; smb347_set_InputCurrentlimit(client, 900); success = bq27541_battery_callback(non_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(non_cable); #endif wake_unlock(&charger_wakelock); } else { printk(KERN_INFO "INOK=L\n"); /* cable type dection */ retval = smb347_read(client, smb347_STS_REG_E); SMB_NOTICE("Reg3F : 0x%02x\n", retval); if (retval & USBIN) { retval = smb347_read(client, smb347_STS_REG_D); SMB_NOTICE("Reg3E : 0x%02x\n", retval); if (retval & APSD_OK) { retval &= APSD_RESULT; if (retval == APSD_CDP) { printk(KERN_INFO "Cable: CDP\n"); charger->cur_cable_type = ac_cable; success = bq27541_battery_callback(ac_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(ac_cable); #endif } else if (retval == APSD_DCP) { printk(KERN_INFO "Cable: DCP\n"); charger->cur_cable_type = ac_cable; success = bq27541_battery_callback(ac_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(ac_cable); #endif } else if (retval == APSD_OTHER) { charger->cur_cable_type = ac_cable; success = bq27541_battery_callback(ac_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(ac_cable); #endif printk(KERN_INFO "Cable: OTHER\n"); } else if (retval == APSD_SDP) { printk(KERN_INFO "Cable: SDP\n"); charger->cur_cable_type = usb_cable; success = bq27541_battery_callback(usb_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(usb_cable); #endif } else { charger->cur_cable_type = unknow_cable; printk(KERN_INFO "Unkown Plug In Cable type !\n"); if(ac_cable == cable_state_detect) { charger->cur_cable_type = ac_cable; success = bq27541_battery_callback(ac_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(ac_cable); #endif printk(KERN_INFO "Change unknow type to ac\n"); } else if(usb_cable == cable_state_detect) { charger->cur_cable_type = usb_cable; success = bq27541_battery_callback(usb_cable); #ifdef TOUCH_CALLBACK_ENABLED touch_callback(usb_cable); #endif printk(KERN_INFO "Change unknow type to usb\n"); } } } else { charger->cur_cable_type = unknow_cable; printk(KERN_INFO "APSD not completed\n"); } } else { charger->cur_cable_type = unknow_cable; printk(KERN_INFO "USBIN=0\n"); } } if (charger->cur_cable_type == ac_cable && charger->old_cable_type != ac_cable && charger->test_1800mA_fail == 0) { wake_lock(&charger_wakelock); queue_delayed_work(smb347_wq, &charger->curr_limit_work, DELAY_FOR_CURR_LIMIT_RECONF*HZ); } charger->old_cable_type = charger->cur_cable_type; mutex_unlock(&charger->cable_lock); return success; }