static int max77693_muic_get_cable_type()

in extcon-max77693.c [309:448]


static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
		enum max77693_muic_cable_group group, bool *attached)
{
	int cable_type = 0;
	int adc;
	int adc1k;
	int adclow;
	int vbvolt;
	int chg_type;

	switch (group) {
	case MAX77693_CABLE_GROUP_ADC:
		/*
		 * Read ADC value to check cable type and decide cable state
		 * according to cable type
		 */
		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
		adc >>= MAX77693_STATUS1_ADC_SHIFT;

		/*
		 * Check current cable state/cable type and store cable type
		 * (info->prev_cable_type) for handling cable when cable is
		 * detached.
		 */
		if (adc == MAX77693_MUIC_ADC_OPEN) {
			*attached = false;

			cable_type = info->prev_cable_type;
			info->prev_cable_type = MAX77693_MUIC_ADC_OPEN;
		} else {
			*attached = true;

			cable_type = info->prev_cable_type = adc;
		}
		break;
	case MAX77693_CABLE_GROUP_ADC_GND:
		/*
		 * Read ADC value to check cable type and decide cable state
		 * according to cable type
		 */
		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
		adc >>= MAX77693_STATUS1_ADC_SHIFT;

		/*
		 * Check current cable state/cable type and store cable type
		 * (info->prev_cable_type/_gnd) for handling cable when cable
		 * is detached.
		 */
		if (adc == MAX77693_MUIC_ADC_OPEN) {
			*attached = false;

			cable_type = info->prev_cable_type_gnd;
			info->prev_cable_type_gnd = MAX77693_MUIC_ADC_OPEN;
		} else {
			*attached = true;

			adclow = info->status[0] & MAX77693_STATUS1_ADCLOW_MASK;
			adclow >>= MAX77693_STATUS1_ADCLOW_SHIFT;
			adc1k = info->status[0] & MAX77693_STATUS1_ADC1K_MASK;
			adc1k >>= MAX77693_STATUS1_ADC1K_SHIFT;

			vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
			vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;

			/**
			 * [0x1|VBVolt|ADCLow|ADC1K]
			 * [0x1|     0|     0|    0] USB_HOST
			 * [0x1|     1|     0|    0] USB_HSOT_VB
			 * [0x1|     0|     1|    0] Audio Video cable with load
			 * [0x1|     0|     1|    1] MHL without charging cable
			 * [0x1|     1|     1|    1] MHL with charging cable
			 */
			cable_type = ((0x1 << 8)
					| (vbvolt << 2)
					| (adclow << 1)
					| adc1k);

			info->prev_cable_type = adc;
			info->prev_cable_type_gnd = cable_type;
		}

		break;
	case MAX77693_CABLE_GROUP_CHG:
		/*
		 * Read charger type to check cable type and decide cable state
		 * according to type of charger cable.
		 */
		chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
		chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;

		if (chg_type == MAX77693_CHARGER_TYPE_NONE) {
			*attached = false;

			cable_type = info->prev_chg_type;
			info->prev_chg_type = MAX77693_CHARGER_TYPE_NONE;
		} else {
			*attached = true;

			/*
			 * Check current cable state/cable type and store cable
			 * type(info->prev_chg_type) for handling cable when
			 * charger cable is detached.
			 */
			cable_type = info->prev_chg_type = chg_type;
		}

		break;
	case MAX77693_CABLE_GROUP_VBVOLT:
		/*
		 * Read ADC value to check cable type and decide cable state
		 * according to cable type
		 */
		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
		adc >>= MAX77693_STATUS1_ADC_SHIFT;
		chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
		chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;

		if (adc == MAX77693_MUIC_ADC_OPEN
				&& chg_type == MAX77693_CHARGER_TYPE_NONE)
			*attached = false;
		else
			*attached = true;

		/*
		 * Read vbvolt field, if vbvolt is 1,
		 * this cable is used for charging.
		 */
		vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
		vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;

		cable_type = vbvolt;
		break;
	default:
		dev_err(info->dev, "Unknown cable group (%d)\n", group);
		cable_type = -EINVAL;
		break;
	}

	return cable_type;
}