diff options
Diffstat (limited to 'drivers/extcon')
| -rw-r--r-- | drivers/extcon/extcon-arizona.c | 107 | ||||
| -rw-r--r-- | drivers/extcon/extcon-max77693.c | 103 | ||||
| -rw-r--r-- | drivers/extcon/extcon-max8997.c | 54 | 
3 files changed, 165 insertions, 99 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index dc357a4051f..b2892797212 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -100,6 +100,55 @@ static const char *arizona_cable[] = {  	NULL,  }; +static void arizona_extcon_do_magic(struct arizona_extcon_info *info, +				    unsigned int magic) +{ +	struct arizona *arizona = info->arizona; +	int ret; + +	mutex_lock(&arizona->dapm->card->dapm_mutex); + +	arizona->hpdet_magic = magic; + +	/* Keep the HP output stages disabled while doing the magic */ +	if (magic) { +		ret = regmap_update_bits(arizona->regmap, +					 ARIZONA_OUTPUT_ENABLES_1, +					 ARIZONA_OUT1L_ENA | +					 ARIZONA_OUT1R_ENA, 0); +		if (ret != 0) +			dev_warn(arizona->dev, +				"Failed to disable headphone outputs: %d\n", +				 ret); +	} + +	ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, +				 magic); +	if (ret != 0) +		dev_warn(arizona->dev, "Failed to do magic: %d\n", +				 ret); + +	ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, +				 magic); +	if (ret != 0) +		dev_warn(arizona->dev, "Failed to do magic: %d\n", +			 ret); + +	/* Restore the desired state while not doing the magic */ +	if (!magic) { +		ret = regmap_update_bits(arizona->regmap, +					 ARIZONA_OUTPUT_ENABLES_1, +					 ARIZONA_OUT1L_ENA | +					 ARIZONA_OUT1R_ENA, arizona->hp_ena); +		if (ret != 0) +			dev_warn(arizona->dev, +				 "Failed to restore headphone outputs: %d\n", +				 ret); +	} + +	mutex_unlock(&arizona->dapm->card->dapm_mutex); +} +  static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)  {  	struct arizona *arizona = info->arizona; @@ -484,7 +533,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)  	struct arizona *arizona = info->arizona;  	int id_gpio = arizona->pdata.hpdet_id_gpio;  	int report = ARIZONA_CABLE_HEADPHONE; -	unsigned int val;  	int ret, reading;  	mutex_lock(&info->lock); @@ -539,28 +587,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)  		dev_err(arizona->dev, "Failed to report HP/line: %d\n",  			ret); -	mutex_lock(&arizona->dapm->card->dapm_mutex); - -	ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); -	if (ret != 0) { -		dev_err(arizona->dev, "Failed to read output enables: %d\n", -			ret); -		val = 0; -	} - -	if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { -		ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); -		if (ret != 0) -			dev_warn(arizona->dev, "Failed to undo magic: %d\n", -				 ret); - -		ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); -		if (ret != 0) -			dev_warn(arizona->dev, "Failed to undo magic: %d\n", -				 ret); -	} - -	mutex_unlock(&arizona->dapm->card->dapm_mutex); +	arizona_extcon_do_magic(info, 0);  done:  	if (id_gpio) @@ -606,13 +633,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)  	if (info->mic)  		arizona_stop_mic(info); -	ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); -	if (ret != 0) -		dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); - -	ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000); -	if (ret != 0) -		dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); +	arizona_extcon_do_magic(info, 0x4000);  	ret = regmap_update_bits(arizona->regmap,  				 ARIZONA_ACCESSORY_DETECT_MODE_1, @@ -653,7 +674,6 @@ err:  static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)  {  	struct arizona *arizona = info->arizona; -	unsigned int val;  	int ret;  	dev_dbg(arizona->dev, "Starting identification via HPDET\n"); @@ -665,30 +685,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)  	arizona_extcon_pulse_micbias(info); -	mutex_lock(&arizona->dapm->card->dapm_mutex); - -	ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); -	if (ret != 0) { -		dev_err(arizona->dev, "Failed to read output enables: %d\n", -			ret); -		val = 0; -	} - -	if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { -		ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, -					 0x4000); -		if (ret != 0) -			dev_warn(arizona->dev, "Failed to do magic: %d\n", -				 ret); - -		ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, -					 0x4000); -		if (ret != 0) -			dev_warn(arizona->dev, "Failed to do magic: %d\n", -				 ret); -	} - -	mutex_unlock(&arizona->dapm->card->dapm_mutex); +	arizona_extcon_do_magic(info, 0x4000);  	ret = regmap_update_bits(arizona->regmap,  				 ARIZONA_ACCESSORY_DETECT_MODE_1, diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index b70e3815c45..8f3c947b002 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -32,6 +32,38 @@  #define	DEV_NAME			"max77693-muic"  #define	DELAY_MS_DEFAULT		20000		/* unit: millisecond */ +/* + * Default value of MAX77693 register to bring up MUIC device. + * If user don't set some initial value for MUIC device through platform data, + * extcon-max77693 driver use 'default_init_data' to bring up base operation + * of MAX77693 MUIC device. + */ +struct max77693_reg_data default_init_data[] = { +	{ +		/* STATUS2 - [3]ChgDetRun */ +		.addr = MAX77693_MUIC_REG_STATUS2, +		.data = STATUS2_CHGDETRUN_MASK, +	}, { +		/* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */ +		.addr = MAX77693_MUIC_REG_INTMASK1, +		.data = INTMASK1_ADC1K_MASK +			| INTMASK1_ADC_MASK, +	}, { +		/* INTMASK2 - Unmask [0]ChgTypM */ +		.addr = MAX77693_MUIC_REG_INTMASK2, +		.data = INTMASK2_CHGTYP_MASK, +	}, { +		/* INTMASK3 - Mask all of interrupts */ +		.addr = MAX77693_MUIC_REG_INTMASK3, +		.data = 0x0, +	}, { +		/* CDETCTRL2 */ +		.addr = MAX77693_MUIC_REG_CDETCTRL2, +		.data = CDETCTRL2_VIDRMEN_MASK +			| CDETCTRL2_DXOVPEN_MASK, +	}, +}; +  enum max77693_muic_adc_debounce_time {  	ADC_DEBOUNCE_TIME_5MS = 0,  	ADC_DEBOUNCE_TIME_10MS, @@ -1045,8 +1077,9 @@ static int max77693_muic_probe(struct platform_device *pdev)  {  	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);  	struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); -	struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;  	struct max77693_muic_info *info; +	struct max77693_reg_data *init_data; +	int num_init_data;  	int delay_jiffies;  	int ret;  	int i; @@ -1145,15 +1178,25 @@ static int max77693_muic_probe(struct platform_device *pdev)  		goto err_irq;  	} -	/* Initialize MUIC register by using platform data */ -	for (i = 0 ; i < muic_pdata->num_init_data ; i++) { -		enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; + +	/* Initialize MUIC register by using platform data or default data */ +	if (pdata->muic_data) { +		init_data = pdata->muic_data->init_data; +		num_init_data = pdata->muic_data->num_init_data; +	} else { +		init_data = default_init_data; +		num_init_data = ARRAY_SIZE(default_init_data); +	} + +	for (i = 0 ; i < num_init_data ; i++) { +		enum max77693_irq_source irq_src +				= MAX77693_IRQ_GROUP_NR;  		max77693_write_reg(info->max77693->regmap_muic, -				muic_pdata->init_data[i].addr, -				muic_pdata->init_data[i].data); +				init_data[i].addr, +				init_data[i].data); -		switch (muic_pdata->init_data[i].addr) { +		switch (init_data[i].addr) {  		case MAX77693_MUIC_REG_INTMASK1:  			irq_src = MUIC_INT1;  			break; @@ -1167,22 +1210,40 @@ static int max77693_muic_probe(struct platform_device *pdev)  		if (irq_src < MAX77693_IRQ_GROUP_NR)  			info->max77693->irq_masks_cur[irq_src] -				= muic_pdata->init_data[i].data; +				= init_data[i].data;  	} -	/* -	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB -	 * h/w path of COMP2/COMN1 on CONTROL1 register. -	 */ -	if (muic_pdata->path_uart) -		info->path_uart = muic_pdata->path_uart; -	else -		info->path_uart = CONTROL1_SW_UART; +	if (pdata->muic_data) { +		struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; -	if (muic_pdata->path_usb) -		info->path_usb = muic_pdata->path_usb; -	else +		/* +		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB +		 * h/w path of COMP2/COMN1 on CONTROL1 register. +		 */ +		if (muic_pdata->path_uart) +			info->path_uart = muic_pdata->path_uart; +		else +			info->path_uart = CONTROL1_SW_UART; + +		if (muic_pdata->path_usb) +			info->path_usb = muic_pdata->path_usb; +		else +			info->path_usb = CONTROL1_SW_USB; + +		/* +		 * Default delay time for detecting cable state +		 * after certain time. +		 */ +		if (muic_pdata->detcable_delay_ms) +			delay_jiffies = +				msecs_to_jiffies(muic_pdata->detcable_delay_ms); +		else +			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); +	} else {  		info->path_usb = CONTROL1_SW_USB; +		info->path_uart = CONTROL1_SW_UART; +		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); +	}  	/* Set initial path for UART */  	 max77693_muic_set_path(info, info->path_uart, true); @@ -1208,10 +1269,6 @@ static int max77693_muic_probe(struct platform_device *pdev)  	 * driver should notify cable state to upper layer.  	 */  	INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); -	if (muic_pdata->detcable_delay_ms) -		delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms); -	else -		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);  	schedule_delayed_work(&info->wq_detcable, delay_jiffies);  	return ret; diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index e636d950ad6..69641bcae32 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -712,29 +712,45 @@ static int max8997_muic_probe(struct platform_device *pdev)  		goto err_irq;  	} -	/* Initialize registers according to platform data */  	if (pdata->muic_pdata) { -		struct max8997_muic_platform_data *mdata = info->muic_pdata; +		struct max8997_muic_platform_data *muic_pdata +			= pdata->muic_pdata; -		for (i = 0; i < mdata->num_init_data; i++) { -			max8997_write_reg(info->muic, mdata->init_data[i].addr, -					mdata->init_data[i].data); +		/* Initialize registers according to platform data */ +		for (i = 0; i < muic_pdata->num_init_data; i++) { +			max8997_write_reg(info->muic, +					muic_pdata->init_data[i].addr, +					muic_pdata->init_data[i].data);  		} -	} -	/* -	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB -	 * h/w path of COMP2/COMN1 on CONTROL1 register. -	 */ -	if (pdata->muic_pdata->path_uart) -		info->path_uart = pdata->muic_pdata->path_uart; -	else -		info->path_uart = CONTROL1_SW_UART; +		/* +		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB +		 * h/w path of COMP2/COMN1 on CONTROL1 register. +		 */ +		if (muic_pdata->path_uart) +			info->path_uart = muic_pdata->path_uart; +		else +			info->path_uart = CONTROL1_SW_UART; -	if (pdata->muic_pdata->path_usb) -		info->path_usb = pdata->muic_pdata->path_usb; -	else +		if (muic_pdata->path_usb) +			info->path_usb = muic_pdata->path_usb; +		else +			info->path_usb = CONTROL1_SW_USB; + +		/* +		 * Default delay time for detecting cable state +		 * after certain time. +		 */ +		if (muic_pdata->detcable_delay_ms) +			delay_jiffies = +				msecs_to_jiffies(muic_pdata->detcable_delay_ms); +		else +			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); +	} else { +		info->path_uart = CONTROL1_SW_UART;  		info->path_usb = CONTROL1_SW_USB; +		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); +	}  	/* Set initial path for UART */  	 max8997_muic_set_path(info, info->path_uart, true); @@ -751,10 +767,6 @@ static int max8997_muic_probe(struct platform_device *pdev)  	 * driver should notify cable state to upper layer.  	 */  	INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); -	if (pdata->muic_pdata->detcable_delay_ms) -		delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms); -	else -		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);  	schedule_delayed_work(&info->wq_detcable, delay_jiffies);  	return 0;  |