extcon: sm5502: Change internal hardware switch according to cable type
This patch changes internal hardware DP_CON/DM_CON switch according to cable type. The SM5502 MUIC device can set hardware switch as following: - OPEN (not connected state) / USB / UART / AUDIO Also, this patch set VBUSIN switch according to cable type. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
This commit is contained in:
		
					parent
					
						
							
								e1954452f5
							
						
					
				
			
			
				commit
				
					
						a75fed2ee6
					
				
			
		
					 2 changed files with 96 additions and 5 deletions
				
			
		|  | @ -228,6 +228,61 @@ static const struct regmap_config sm5502_muic_regmap_config = { | |||
| 	.max_register	= SM5502_REG_END, | ||||
| }; | ||||
| 
 | ||||
| /* Change DM_CON/DP_CON/VBUSIN switch according to cable type */ | ||||
| static int sm5502_muic_set_path(struct sm5502_muic_info *info, | ||||
| 				unsigned int con_sw, unsigned int vbus_sw, | ||||
| 				bool attached) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!attached) { | ||||
| 		con_sw	= DM_DP_SWITCH_OPEN; | ||||
| 		vbus_sw	= VBUSIN_SWITCH_OPEN; | ||||
| 	} | ||||
| 
 | ||||
| 	switch (con_sw) { | ||||
| 	case DM_DP_SWITCH_OPEN: | ||||
| 	case DM_DP_SWITCH_USB: | ||||
| 	case DM_DP_SWITCH_AUDIO: | ||||
| 	case DM_DP_SWITCH_UART: | ||||
| 		ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1, | ||||
| 					 SM5502_REG_MANUAL_SW1_DP_MASK | | ||||
| 					 SM5502_REG_MANUAL_SW1_DM_MASK, | ||||
| 					 con_sw); | ||||
| 		if (ret < 0) { | ||||
| 			dev_err(info->dev, | ||||
| 				"cannot update DM_CON/DP_CON switch\n"); | ||||
| 			return ret; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n", | ||||
| 				con_sw); | ||||
| 		return -EINVAL; | ||||
| 	}; | ||||
| 
 | ||||
| 	switch (vbus_sw) { | ||||
| 	case VBUSIN_SWITCH_OPEN: | ||||
| 	case VBUSIN_SWITCH_VBUSOUT: | ||||
| 	case VBUSIN_SWITCH_MIC: | ||||
| 	case VBUSIN_SWITCH_VBUSOUT_WITH_USB: | ||||
| 		ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1, | ||||
| 					 SM5502_REG_MANUAL_SW1_VBUSIN_MASK, | ||||
| 					 vbus_sw); | ||||
| 		if (ret < 0) { | ||||
| 			dev_err(info->dev, | ||||
| 				"cannot update VBUSIN switch\n"); | ||||
| 			return ret; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		dev_err(info->dev, "Unknown VBUS switch type (%d)\n", vbus_sw); | ||||
| 		return -EINVAL; | ||||
| 	}; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Return cable type of attached or detached accessories */ | ||||
| static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info) | ||||
| { | ||||
|  | @ -329,7 +384,10 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, | |||
| 	static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND; | ||||
| 	const char **cable_names = info->edev->supported_cable; | ||||
| 	unsigned int cable_type = SM5502_MUIC_ADC_GROUND; | ||||
| 	unsigned int con_sw = DM_DP_SWITCH_OPEN; | ||||
| 	unsigned int vbus_sw = VBUSIN_SWITCH_OPEN; | ||||
| 	unsigned int idx = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!cable_names) | ||||
| 		return 0; | ||||
|  | @ -344,14 +402,18 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, | |||
| 	switch (cable_type) { | ||||
| 	case SM5502_MUIC_ADC_OPEN_USB: | ||||
| 		idx	= EXTCON_CABLE_USB; | ||||
| 		con_sw	= DM_DP_SWITCH_USB; | ||||
| 		vbus_sw	= VBUSIN_SWITCH_VBUSOUT_WITH_USB; | ||||
| 		break; | ||||
| 	case SM5502_MUIC_ADC_OPEN_TA: | ||||
| 		idx	= EXTCON_CABLE_TA; | ||||
| 		con_sw	= DM_DP_SWITCH_OPEN; | ||||
| 		vbus_sw	= VBUSIN_SWITCH_VBUSOUT; | ||||
| 		break; | ||||
| 	case SM5502_MUIC_ADC_OPEN_USB_OTG: | ||||
| 		idx	= EXTCON_CABLE_USB_HOST; | ||||
| 		break; | ||||
| 	case SM5502_MUIC_ADC_GROUND: | ||||
| 		con_sw	= DM_DP_SWITCH_USB; | ||||
| 		vbus_sw	= VBUSIN_SWITCH_OPEN; | ||||
| 		break; | ||||
| 	default: | ||||
| 		dev_dbg(info->dev, | ||||
|  | @ -359,6 +421,12 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, | |||
| 		return 0; | ||||
| 	}; | ||||
| 
 | ||||
| 	/* Change internal hardware path(DM_CON/DP_CON, VBUSIN) */ | ||||
| 	ret = sm5502_muic_set_path(info, con_sw, vbus_sw, attached); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/* Change the state of external accessory */ | ||||
| 	extcon_set_cable_state(info->edev, cable_names[idx], attached); | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -223,6 +223,29 @@ enum sm5502_reg { | |||
| #define SM5502_REG_DEV_TYPE2_TTY_MASK			(0x1 << SM5502_REG_DEV_TYPE2_TTY_SHIFT) | ||||
| #define SM5502_REG_DEV_TYPE2_AV_CABLE_MASK		(0x1 << SM5502_REG_DEV_TYPE2_AV_CABLE_SHIFT) | ||||
| 
 | ||||
| #define SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT	0 | ||||
| #define SM5502_REG_MANUAL_SW1_DP_SHIFT		2 | ||||
| #define SM5502_REG_MANUAL_SW1_DM_SHIFT		5 | ||||
| #define SM5502_REG_MANUAL_SW1_VBUSIN_MASK	(0x3 << SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT) | ||||
| #define SM5502_REG_MANUAL_SW1_DP_MASK		(0x7 << SM5502_REG_MANUAL_SW1_DP_SHIFT) | ||||
| #define SM5502_REG_MANUAL_SW1_DM_MASK		(0x7 << SM5502_REG_MANUAL_SW1_DM_SHIFT) | ||||
| #define VBUSIN_SWITCH_OPEN			0x0 | ||||
| #define VBUSIN_SWITCH_VBUSOUT			0x1 | ||||
| #define VBUSIN_SWITCH_MIC			0x2 | ||||
| #define VBUSIN_SWITCH_VBUSOUT_WITH_USB		0x3 | ||||
| #define DM_DP_CON_SWITCH_OPEN			0x0 | ||||
| #define DM_DP_CON_SWITCH_USB			0x1 | ||||
| #define DM_DP_CON_SWITCH_AUDIO			0x2 | ||||
| #define DM_DP_CON_SWITCH_UART			0x3 | ||||
| #define DM_DP_SWITCH_OPEN			((DM_DP_CON_SWITCH_OPEN <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \ | ||||
| 						| (DM_DP_CON_SWITCH_OPEN <<SM5502_REG_MANUAL_SW1_DM_SHIFT)) | ||||
| #define DM_DP_SWITCH_USB			((DM_DP_CON_SWITCH_USB <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \ | ||||
| 						| (DM_DP_CON_SWITCH_USB <<SM5502_REG_MANUAL_SW1_DM_SHIFT)) | ||||
| #define DM_DP_SWITCH_AUDIO			((DM_DP_CON_SWITCH_AUDIO <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \ | ||||
| 						| (DM_DP_CON_SWITCH_AUDIO <<SM5502_REG_MANUAL_SW1_DM_SHIFT)) | ||||
| #define DM_DP_SWITCH_UART			((DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \ | ||||
| 						| (DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DM_SHIFT)) | ||||
| 
 | ||||
| /* SM5502 Interrupts */ | ||||
| enum sm5502_irq { | ||||
| 	/* INT1 */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chanwoo Choi
				Chanwoo Choi