コード例 #1
0
static int max8997_muic_handle_attach(struct max8997_muic_info *info,
		u8 status1, u8 status2)
{
	struct max8997_muic_data *mdata = info->muic_data;
	u8 adc, adclow, adcerr, chgtyp, vbvolt, chgdetrun;
	int ret = 0;
#ifdef CONFIG_USBHUB_USB3803
	/* setting usb hub in Diagnostic(hub) mode */
	usb3803_set_mode(USB_3803_MODE_HUB);
#endif /* CONFIG_USBHUB_USB3803 */

	adc = status1 & STATUS1_ADC_MASK;
	adclow = status1 & STATUS1_ADCLOW_MASK;
	adcerr = status1 & STATUS1_ADCERR_MASK;
	chgtyp = status2 & STATUS2_CHGTYP_MASK;
	vbvolt = status2 & STATUS2_VBVOLT_MASK;
	chgdetrun = status2 & STATUS2_CHGDETRUN_MASK;

	switch (info->cable_type) {
	case CABLE_TYPE_JIG_UART_OFF:
	case CABLE_TYPE_JIG_UART_OFF_VB:
		/* Workaround for Factory mode.
		 * Abandon adc interrupt of approximately +-100K range
		 * if previous cable status was JIG UART BOOT OFF.
		 */
		if (adc == (ADC_JIG_UART_OFF + 1) ||
				adc == (ADC_JIG_UART_OFF - 1)) {
			dev_warn(info->dev, "%s: abandon ADC\n", __func__);
			return 0;
		}

		if (adcerr) {
			dev_warn(info->dev, "%s: current state is jig_uart_off,"
				"just ignore\n", __func__);
			return 0;
		}

		if (adc != ADC_JIG_UART_OFF) {
			if (info->cable_type == CABLE_TYPE_JIG_UART_OFF_VB) {
				dev_info(info->dev, "%s: adc != JIG_UART_OFF, remove JIG UART/OFF/VB\n", __func__);
				info->cable_type = CABLE_TYPE_NONE;
				max8997_muic_set_charging_type(info, false);
			} else {
				dev_info(info->dev, "%s: adc != JIG_UART_OFF, remove JIG UART/BOOTOFF\n", __func__);
				info->cable_type = CABLE_TYPE_NONE;
			}
		}
		break;

	case CABLE_TYPE_DESKDOCK:
		if (adcerr || (adc != ADC_DESKDOCK)) {
			if (adcerr)
				dev_err(info->dev, "%s: ADC err occured(DESKDOCK)\n", __func__);
			else
				dev_warn(info->dev, "%s: ADC != DESKDOCK, remove DESKDOCK\n", __func__);

			info->cable_type = CABLE_TYPE_NONE;

			max8997_muic_set_charging_type(info, false);

			if (mdata->deskdock_cb)
				mdata->deskdock_cb(MAX8997_MUIC_DETACHED);

			if (adcerr)
				return 0;
		}
		break;

	case CABLE_TYPE_CARDOCK:
		if (adcerr || (adc != ADC_CARDOCK)) {
			if (adcerr)
				dev_err(info->dev, "%s: ADC err occured(CARDOCK)\n", __func__);
			else
				dev_warn(info->dev, "%s: ADC != CARDOCK, remove CARDOCK\n", __func__);

			info->cable_type = CABLE_TYPE_NONE;

			max8997_muic_set_charging_type(info, false);

			if (mdata->cardock_cb)
				mdata->cardock_cb(MAX8997_MUIC_DETACHED);

			if (adcerr)
				return 0;
		}
		break;

	default:
		break;
	}

	/* 1Kohm ID regiter detection (mHL)
	 * Old MUIC : ADC value:0x00 or 0x01, ADCLow:1
	 * New MUIC : ADC value is not set(Open), ADCLow:1, ADCError:1
	 */
	if (adclow && adcerr) {
		max8997_muic_attach_mhl(info, chgtyp);
		return 0;
	}

	switch (adc) {
	case ADC_GND:
#if defined(CONFIG_MACH_U1)
		/* This is for support old MUIC */
		if (adclow) {
			max8997_muic_attach_mhl(info, chgtyp);
			break;
		}
#endif

		if (chgtyp == CHGTYP_NO_VOLTAGE) {
			if (info->cable_type == CABLE_TYPE_OTG) {
				dev_info(info->dev,
						"%s: duplicated(OTG)\n",
						__func__);
				break;
			}

			info->cable_type = CABLE_TYPE_OTG;
			max8997_muic_set_usb_path(info, AP_USB_MODE);
			if (mdata->usb_cb && info->is_usb_ready)
				mdata->usb_cb(USB_OTGHOST_ATTACHED);
		} else if (chgtyp == CHGTYP_USB ||
				chgtyp == CHGTYP_DOWNSTREAM_PORT ||
				chgtyp == CHGTYP_DEDICATED_CHGR ||
				chgtyp == CHGTYP_500MA	||
				chgtyp == CHGTYP_1A) {
			dev_info(info->dev, "%s: OTG charging pump\n",
					__func__);
			ret = max8997_muic_set_charging_type(info, false);
		}
		break;
	case ADC_MHL:
#if defined(CONFIG_MACH_U1)
		/* This is for support old MUIC */
		max8997_muic_attach_mhl(info, chgtyp);
#endif
		break;
	case ADC_JIG_UART_OFF:
		max8997_muic_handle_jig_uart(info, vbvolt);
		break;
	case ADC_JIG_USB_OFF:
	case ADC_JIG_USB_ON:
		if (vbvolt & STATUS2_VBVOLT_MASK)
			ret = max8997_muic_attach_usb_type(info, adc);
		break;
	case ADC_DESKDOCK:
	case ADC_CARDOCK:
		max8997_muic_attach_dock_type(info, adc);
		if (chgtyp == CHGTYP_USB ||
				chgtyp == CHGTYP_DOWNSTREAM_PORT ||
				chgtyp == CHGTYP_DEDICATED_CHGR ||
				chgtyp == CHGTYP_500MA	||
				chgtyp == CHGTYP_1A)
			ret = max8997_muic_set_charging_type(info, false);
		else if (chgtyp == CHGTYP_NO_VOLTAGE && !chgdetrun)
			ret = max8997_muic_set_charging_type(info, true);
		break;
	case ADC_CEA936ATYPE1_CHG:
	case ADC_CEA936ATYPE2_CHG:
	case ADC_OPEN:
		switch (chgtyp) {
		case CHGTYP_USB:
			if (adc == ADC_CEA936ATYPE1_CHG
					|| adc == ADC_CEA936ATYPE2_CHG)
				break;
			if (mdata->is_mhl_attached
					&& mdata->is_mhl_attached() &&
					info->cable_type == CABLE_TYPE_MHL) {
				dev_info(info->dev, "%s: MHL(charging)\n",
						__func__);
				info->cable_type = CABLE_TYPE_MHL_VB;
				ret = max8997_muic_set_charging_type(info,
						false);
				return ret;
			}
			ret = max8997_muic_attach_usb_type(info, adc);
			break;
		case CHGTYP_DOWNSTREAM_PORT:
		case CHGTYP_DEDICATED_CHGR:
		case CHGTYP_500MA:
		case CHGTYP_1A:
			dev_info(info->dev, "%s:TA\n", __func__);
			info->cable_type = CABLE_TYPE_TA;
#ifdef CONFIG_USBHUB_USB3803
			/* setting usb hub in default mode (standby) */
			usb3803_set_mode(USB_3803_MODE_STANDBY);
#endif  /* CONFIG_USBHUB_USB3803 */
			ret = max8997_muic_set_charging_type(info, false);
			if (ret)
				info->cable_type = CABLE_TYPE_NONE;
			break;
		default:
			break;
		}
		break;
	default:
		dev_warn(info->dev, "%s: unsupported adc=0x%x\n", __func__,
				adc);
		break;
	}
	return ret;
}
コード例 #2
0
static int max8997_muic_handle_attach(struct max8997_muic_info *info,
		u8 status1, u8 status2)
{
	struct max8997_muic_data *mdata = info->muic_data;
	u8 adc, adclow, adcerr, chgtyp, vbvolt, chgdetrun;
	int ret = 0;

	adc = status1 & STATUS1_ADC_MASK;
	adclow = status1 & STATUS1_ADCLOW_MASK;
	adcerr = status1 & STATUS1_ADCERR_MASK;
	chgtyp = status2 & STATUS2_CHGTYP_MASK;
	vbvolt = status2 & STATUS2_VBVOLT_MASK;
	chgdetrun = status2 & STATUS2_CHGDETRUN_MASK;

	/* Workaround for Factory mode.
	 * Abandon adc interrupt of approximately +-100K range
	 * if previous cable status was JIG UART BOOT OFF.
	 */
	if (info->cable_type == CABLE_TYPE_JIG_UART_OFF ||
			info->cable_type == CABLE_TYPE_JIG_UART_OFF_VB) {
		if (adc == (ADC_JIG_UART_OFF + 1) ||
				adc == (ADC_JIG_UART_OFF - 1)) {
			dev_warn(info->dev, "%s: abandon ADC\n", __func__);
			return 0;
		}
	}

	/* 1Kohm ID regiter detection (mHL)
	 * Old MUIC : ADC value:0x00 or 0x01, ADCLow:1
	 * New MUIC : ADC value is not set(Open), ADCLow:1, ADCError:1
	 */
	if (adclow && adcerr) {
		max8997_muic_attach_mhl(info, chgtyp);
		return 0;
	}

	switch (adc) {
	case ADC_GND:
		if (adclow) {
			max8997_muic_attach_mhl(info, chgtyp);
			break;
		}

		if (chgtyp == CHGTYP_NO_VOLTAGE) {
			if (info->cable_type == CABLE_TYPE_OTG) {
				dev_info(info->dev,
						"%s: duplicated(OTG)\n",
						__func__);
				break;
			}

			info->cable_type = CABLE_TYPE_OTG;
			max8997_muic_set_usb_path(info, AP_USB_MODE);
			if (mdata->usb_cb && info->is_usb_ready)
				mdata->usb_cb(USB_OTGHOST_ATTACHED);
		} else if (chgtyp == CHGTYP_USB ||
				chgtyp == CHGTYP_DOWNSTREAM_PORT ||
				chgtyp == CHGTYP_DEDICATED_CHGR ||
				chgtyp == CHGTYP_500MA	||
				chgtyp == CHGTYP_1A) {
			dev_info(info->dev, "%s: OTG charging pump\n",
					__func__);
			ret = max8997_muic_set_charging_type(info, false);
		}
		break;
	case ADC_MHL:
		max8997_muic_attach_mhl(info, chgtyp);
		break;
	case ADC_JIG_UART_OFF:
		max8997_muic_handle_jig_uart(info, vbvolt);
		break;
	case ADC_JIG_USB_OFF:
	case ADC_JIG_USB_ON:
		ret = max8997_muic_attach_usb_type(info, adc);
		break;
	case ADC_DESKDOCK:
	case ADC_CARDOCK:
		max8997_muic_attach_dock_type(info, adc);
		if (chgtyp == CHGTYP_USB ||
				chgtyp == CHGTYP_DOWNSTREAM_PORT ||
				chgtyp == CHGTYP_DEDICATED_CHGR ||
				chgtyp == CHGTYP_500MA	||
				chgtyp == CHGTYP_1A)
			ret = max8997_muic_set_charging_type(info, false);
		else if (chgtyp == CHGTYP_NO_VOLTAGE && !chgdetrun)
			ret = max8997_muic_set_charging_type(info, true);
		break;
	case ADC_CEA936ATYPE1_CHG:
	case ADC_CEA936ATYPE2_CHG:
	case ADC_OPEN:
		switch (chgtyp) {
		case CHGTYP_USB:
			if (adc == ADC_CEA936ATYPE1_CHG
					|| adc == ADC_CEA936ATYPE2_CHG)
				break;
			if (mdata->is_mhl_attached
					&& mdata->is_mhl_attached() &&
					info->cable_type == CABLE_TYPE_MHL) {
				dev_info(info->dev, "%s: MHL(charging)\n",
						__func__);
				info->cable_type = CABLE_TYPE_MHL_VB;
				ret = max8997_muic_set_charging_type(info,
						false);
				return ret;
			}
			ret = max8997_muic_attach_usb_type(info, adc);
			break;
		case CHGTYP_DOWNSTREAM_PORT:
		case CHGTYP_DEDICATED_CHGR:
		case CHGTYP_500MA:
		case CHGTYP_1A:
			dev_info(info->dev, "%s:TA\n", __func__);
			info->cable_type = CABLE_TYPE_TA;
			ret = max8997_muic_set_charging_type(info, false);
			if (ret)
				info->cable_type = CABLE_TYPE_NONE;
			break;
		default:
			break;
		}
		break;
	default:
		dev_warn(info->dev, "%s: unsupported adc=0x%x\n", __func__,
				adc);
		break;
	}
	return ret;
}