Пример #1
0
static ssize_t port_store(
		struct device *dev, struct device_attribute *attr,
		const char *buf, size_t size)
{
	if (!strncmp(buf, "disable_cp", 10)) {
		hub_port = (0x1 << 2) | hub_port ;
		pr_debug("usb3803 port disable cp\n");
	} else if (!strncmp(buf, "disable_wimax", 13)) {
		hub_port = (0x1 << 1) | hub_port ;
		pr_debug("usb3803 port disable wimaxb\n");
	} else if (!strncmp(buf, "disable_ap", 10)) {
		hub_port = (0x1 << 3) | hub_port ;
		pr_debug("usb3803 port disable ap\n");
	} else if (!strncmp(buf, "enable_cp", 9)) {
		hub_port = ~(0x1 << 2) & hub_port ;
		pr_debug("usb3803 port enable cp\n");
	} else if (!strncmp(buf, "enable_wimax", 12)) {
		hub_port = ~(0x1 << 1) & hub_port ;
		pr_debug("usb3803 port enable wimaxb\n");
	} else if (!strncmp(buf, "enable_ap", 9)) {
		hub_port = ~(0x1 << 3) & hub_port ;
		pr_debug("usb3803 port enable ap\n");
	}

	if(current_mode == USB_3803_MODE_HUB)
		usb3803_set_mode(USB_3803_MODE_HUB);
	pr_debug("usb3803 mode setting (%s)\n", buf);

	return size;
}
Пример #2
0
static ssize_t mode_store(
		struct device *dev, struct device_attribute *attr,
		const char *buf, size_t size)
{
	if(!strncmp(buf, "hub", 3)) {
		usb3803_set_mode(USB_3803_MODE_HUB);
		pr_debug("usb3803 mode set to hub\n");
	} else if(!strncmp(buf, "bypass", 6)) {
		usb3803_set_mode(USB_3803_MODE_BYPASS);
		pr_debug("usb3803 mode set to bypass\n");
	} else if(!strncmp(buf, "standby", 7)) {
		usb3803_set_mode(USB_3803_MODE_STANDBY);
		pr_debug("usb3803 mode set to standby\n");
	}
	return size;
}
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;
}
static int max8997_muic_handle_detach(struct max8997_muic_info *info)
{
	struct i2c_client *client = info->muic;
	struct max8997_muic_data *mdata = info->muic_data;
	enum cable_type prev_ct = CABLE_TYPE_NONE;
	int ret = 0;

#if defined(CONFIG_SEC_MODEM_M0_TD)
	gpio_set_value(GPIO_AP_CP_INT1, 0);
#endif

	/*
	 * MAX8996/8997-MUIC bug:
	 *
	 * Auto-switching COMN/P is not restored automatically when detached and
	 * remains undetermined state. UART(UT1, UR2) will be short (because TA
	 * D+/D- is short) if charger(TA) insertion is followed right after the
	 * JIG off. Reset CONTROL1 is needed when detaching cable.
	 */
	max8997_write_reg(client, MAX8997_MUIC_REG_CTRL1, 0x00);

	if (info->cable_type == CABLE_TYPE_MHL) {

		/* Enable Factory Accessory Detection State Machine */
		max8997_update_reg(client, MAX8997_MUIC_REG_CTRL2,
				(1 << CTRL2_ACCDET_SHIFT), CTRL2_ACCDET_MASK);
	}

#ifdef CONFIG_USBHUB_USB3803
	/* setting usb hub in default mode (standby) */
	usb3803_set_mode(USB_3803_MODE_STANDBY);
#endif  /* CONFIG_USBHUB_USB3803 */
	info->previous_key = DOCK_KEY_NONE;

	if (info->cable_type == CABLE_TYPE_NONE) {
		dev_info(info->dev, "%s: duplicated(NONE)\n", __func__);
		return 0;
	}
#if 0
	if (mdata->jig_uart_cb)
		mdata->jig_uart_cb(UART_PATH_AP);
#endif
	if (mdata->is_mhl_attached && mdata->is_mhl_attached()
			&& info->cable_type == CABLE_TYPE_MHL) {
		dev_info(info->dev, "%s: MHL attached. Do Nothing\n",
				__func__);
		return 0;
	}

	switch (info->cable_type) {
	case CABLE_TYPE_OTG:
		dev_info(info->dev, "%s: OTG\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;

		if (mdata->usb_cb && info->is_usb_ready)
			mdata->usb_cb(USB_OTGHOST_DETACHED);
		break;
	case CABLE_TYPE_USB:
	case CABLE_TYPE_JIG_USB_OFF:
	case CABLE_TYPE_JIG_USB_ON:
		dev_info(info->dev, "%s: USB(0x%x)\n", __func__,
				info->cable_type);
		prev_ct = info->cable_type;
		info->cable_type = CABLE_TYPE_NONE;

		ret = max8997_muic_set_charging_type(info, false);
		if (ret) {
			info->cable_type = prev_ct;
			break;
		}

		if (mdata->sw_path == CP_USB_MODE)
			return 0;

		if (mdata->usb_cb && info->is_usb_ready)
			mdata->usb_cb(USB_CABLE_DETACHED);
		break;
	case CABLE_TYPE_DESKDOCK:
		dev_info(info->dev, "%s: DESKDOCK\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;

		ret = max8997_muic_set_charging_type(info, false);
		if (ret) {
			info->cable_type = CABLE_TYPE_DESKDOCK;
			break;
		}

		if (mdata->deskdock_cb)
			mdata->deskdock_cb(MAX8997_MUIC_DETACHED);
		break;
	case CABLE_TYPE_CARDOCK:
		dev_info(info->dev, "%s: CARDOCK\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;

		ret = max8997_muic_set_charging_type(info, false);
		if (ret) {
			info->cable_type = CABLE_TYPE_CARDOCK;
			break;
		}

		if (mdata->cardock_cb)
			mdata->cardock_cb(MAX8997_MUIC_DETACHED);
		break;
	case CABLE_TYPE_TA:
		dev_info(info->dev, "%s: TA\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		ret = max8997_muic_set_charging_type(info, false);
		if (ret)
			info->cable_type = CABLE_TYPE_TA;
		break;
	case CABLE_TYPE_JIG_UART_ON:
		dev_info(info->dev, "%s: JIG UART/BOOTON\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		break;
	case CABLE_TYPE_JIG_UART_OFF:
		dev_info(info->dev, "%s: JIG UART/BOOTOFF\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		break;
	case CABLE_TYPE_JIG_UART_OFF_VB:
		dev_info(info->dev, "%s: JIG UART/OFF/VB\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		ret = max8997_muic_set_charging_type(info, false);
		if (ret)
			info->cable_type = CABLE_TYPE_JIG_UART_OFF_VB;
		break;
	case CABLE_TYPE_MHL:
		dev_info(info->dev, "%s: MHL\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		break;
	case CABLE_TYPE_MHL_VB:
		dev_info(info->dev, "%s: MHL VBUS\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;
		max8997_muic_set_charging_type(info, false);

		if (mdata->is_mhl_attached && mdata->is_mhl_attached()) {
			if (mdata->mhl_cb && info->is_mhl_ready)
				mdata->mhl_cb(MAX8997_MUIC_DETACHED);
		}
		break;
	case CABLE_TYPE_UNKNOWN:
		dev_info(info->dev, "%s: UNKNOWN\n", __func__);
		info->cable_type = CABLE_TYPE_NONE;

		ret = max8997_muic_set_charging_type(info, false);
		if (ret)
			info->cable_type = CABLE_TYPE_UNKNOWN;
		break;
	default:
		dev_info(info->dev, "%s:invalid cable type %d\n",
				__func__, info->cable_type);
		break;
	}
	return ret;
}