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;
}
Exemple #2
0
/* 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;
}