static int rt8973a_muic_cable_handler()

in extcon-rt8973a.c [296:405]


static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
					enum rt8973a_event_type event)
{
	static unsigned int prev_cable_type;
	unsigned int con_sw = DM_DP_SWITCH_UART;
	int ret, cable_type;
	unsigned int id;
	bool attached = false;

	switch (event) {
	case RT8973A_EVENT_ATTACH:
		cable_type = rt8973a_muic_get_cable_type(info);
		attached = true;
		break;
	case RT8973A_EVENT_DETACH:
		cable_type = prev_cable_type;
		attached = false;
		break;
	case RT8973A_EVENT_OVP:
	case RT8973A_EVENT_OTP:
		dev_warn(info->dev,
			"happen Over %s issue. Need to disconnect all cables\n",
			event == RT8973A_EVENT_OVP ? "Voltage" : "Temperature");
		cable_type = prev_cable_type;
		attached = false;
		break;
	default:
		dev_err(info->dev,
			"Cannot handle this event (event:%d)\n", event);
		return -EINVAL;
	}
	prev_cable_type = cable_type;

	switch (cable_type) {
	case RT8973A_MUIC_ADC_OTG:
		id = EXTCON_USB_HOST;
		con_sw = DM_DP_SWITCH_USB;
		break;
	case RT8973A_MUIC_ADC_TA:
		id = EXTCON_CHG_USB_DCP;
		con_sw = DM_DP_SWITCH_OPEN;
		break;
	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
		id = EXTCON_JIG;
		con_sw = DM_DP_SWITCH_USB;
		break;
	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
		id = EXTCON_JIG;
		con_sw = DM_DP_SWITCH_UART;
		break;
	case RT8973A_MUIC_ADC_USB:
		id = EXTCON_USB;
		con_sw = DM_DP_SWITCH_USB;
		break;
	case RT8973A_MUIC_ADC_OPEN:
		return 0;
	case RT8973A_MUIC_ADC_UNKNOWN_ACC_1:
	case RT8973A_MUIC_ADC_UNKNOWN_ACC_2:
	case RT8973A_MUIC_ADC_UNKNOWN_ACC_3:
	case RT8973A_MUIC_ADC_UNKNOWN_ACC_4:
	case RT8973A_MUIC_ADC_UNKNOWN_ACC_5:
		dev_warn(info->dev,
			"Unknown accessory type (adc:0x%x)\n", cable_type);
		return 0;
	case RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON:
	case RT8973A_MUIC_ADC_AUDIO_TYPE2:
		dev_warn(info->dev,
			"Audio device/button type (adc:0x%x)\n", cable_type);
		return 0;
	case RT8973A_MUIC_ADC_RESERVED_ACC_1:
	case RT8973A_MUIC_ADC_RESERVED_ACC_2:
	case RT8973A_MUIC_ADC_RESERVED_ACC_3:
	case RT8973A_MUIC_ADC_RESERVED_ACC_4:
	case RT8973A_MUIC_ADC_RESERVED_ACC_5:
	case RT8973A_MUIC_ADC_PHONE_POWERED_DEV:
		return 0;
	default:
		dev_err(info->dev,
			"Cannot handle this cable_type (adc:0x%x)\n",
			cable_type);
		return -EINVAL;
	}

	/* Change internal hardware path(DM_CON/DP_CON) */
	ret = rt8973a_muic_set_path(info, con_sw, attached);
	if (ret < 0)
		return ret;

	/* Change the state of external accessory */
	extcon_set_state_sync(info->edev, id, attached);
	if (id == EXTCON_USB)
		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
					attached);

	return 0;
}