diff options
| author | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
|---|---|---|
| committer | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
| commit | c74a7469f97c0f40b46e82ee979f9fb1bb6e847c (patch) | |
| tree | f2690a1a916b73ef94657fbf0e0141ae57701825 /sound/soc/codecs/tas6424.c | |
| parent | 6f15a7de86c8cf2dc09fc9e6d07047efa40ef809 (diff) | |
| parent | 500775074f88d9cf5416bed2ca19592812d62c41 (diff) | |
Merge drm/drm-next into drm-intel-next-queued
We need a backmerge to get DP_DPCD_REV_14 before we push other
i915 changes to dinq that could break compilation.
Signed-off-by: Rodrigo Vivi <[email protected]>
Diffstat (limited to 'sound/soc/codecs/tas6424.c')
| -rw-r--r-- | sound/soc/codecs/tas6424.c | 72 | 
1 files changed, 69 insertions, 3 deletions
| diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 4f3a16c520a2..14999b999fd3 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -16,6 +16,7 @@  #include <linux/slab.h>  #include <linux/regulator/consumer.h>  #include <linux/delay.h> +#include <linux/gpio/consumer.h>  #include <sound/pcm.h>  #include <sound/pcm_params.h> @@ -43,6 +44,8 @@ struct tas6424_data {  	unsigned int last_fault1;  	unsigned int last_fault2;  	unsigned int last_warn; +	struct gpio_desc *standby_gpio; +	struct gpio_desc *mute_gpio;  };  /* @@ -61,6 +64,8 @@ static const struct snd_kcontrol_new tas6424_snd_controls[] = {  		       TAS6424_CH3_VOL_CTRL, 0, 0xff, 0, dac_tlv),  	SOC_SINGLE_TLV("Speaker Driver CH4 Playback Volume",  		       TAS6424_CH4_VOL_CTRL, 0, 0xff, 0, dac_tlv), +	SOC_SINGLE_STROBE("Auto Diagnostics Switch", TAS6424_DC_DIAG_CTRL1, +			  TAS6424_LDGBYPASS_SHIFT, 1),  };  static int tas6424_dac_event(struct snd_soc_dapm_widget *w, @@ -249,10 +254,16 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,  static int tas6424_mute(struct snd_soc_dai *dai, int mute)  {  	struct snd_soc_component *component = dai->component; +	struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);  	unsigned int val;  	dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute); +	if (tas6424->mute_gpio) { +		gpiod_set_value_cansleep(tas6424->mute_gpio, mute); +		return 0; +	} +  	if (mute)  		val = TAS6424_ALL_STATE_MUTE;  	else @@ -287,6 +298,12 @@ static int tas6424_power_on(struct snd_soc_component *component)  {  	struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);  	int ret; +	u8 chan_states; +	int no_auto_diags = 0; +	unsigned int reg_val; + +	if (!regmap_read(tas6424->regmap, TAS6424_DC_DIAG_CTRL1, ®_val)) +		no_auto_diags = reg_val & TAS6424_LDGBYPASS_MASK;  	ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),  				    tas6424->supplies); @@ -303,12 +320,25 @@ static int tas6424_power_on(struct snd_soc_component *component)  		return ret;  	} -	snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE); +	if (tas6424->mute_gpio) { +		gpiod_set_value_cansleep(tas6424->mute_gpio, 0); +		/* +		 * channels are muted via the mute pin.  Don't also mute +		 * them via the registers so that subsequent register +		 * access is not necessary to un-mute the channels +		 */ +		chan_states = TAS6424_ALL_STATE_PLAY; +	} else { +		chan_states = TAS6424_ALL_STATE_MUTE; +	} +	snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, chan_states);  	/* any time we come out of HIZ, the output channels automatically run DC -	 * load diagnostics, wait here until this completes +	 * load diagnostics if autodiagnotics are enabled. wait here until this +	 * completes.  	 */ -	msleep(230); +	if (!no_auto_diags) +		msleep(230);  	return 0;  } @@ -627,6 +657,38 @@ static int tas6424_i2c_probe(struct i2c_client *client,  		return ret;  	} +	/* +	 * Get control of the standby pin and set it LOW to take the codec +	 * out of the stand-by mode. +	 * Note: The actual pin polarity is taken care of in the GPIO lib +	 * according the polarity specified in the DTS. +	 */ +	tas6424->standby_gpio = devm_gpiod_get_optional(dev, "standby", +						      GPIOD_OUT_LOW); +	if (IS_ERR(tas6424->standby_gpio)) { +		if (PTR_ERR(tas6424->standby_gpio) == -EPROBE_DEFER) +			return -EPROBE_DEFER; +		dev_info(dev, "failed to get standby GPIO: %ld\n", +			PTR_ERR(tas6424->standby_gpio)); +		tas6424->standby_gpio = NULL; +	} + +	/* +	 * Get control of the mute pin and set it HIGH in order to start with +	 * all the output muted. +	 * Note: The actual pin polarity is taken care of in the GPIO lib +	 * according the polarity specified in the DTS. +	 */ +	tas6424->mute_gpio = devm_gpiod_get_optional(dev, "mute", +						      GPIOD_OUT_HIGH); +	if (IS_ERR(tas6424->mute_gpio)) { +		if (PTR_ERR(tas6424->mute_gpio) == -EPROBE_DEFER) +			return -EPROBE_DEFER; +		dev_info(dev, "failed to get nmute GPIO: %ld\n", +			PTR_ERR(tas6424->mute_gpio)); +		tas6424->mute_gpio = NULL; +	} +  	for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++)  		tas6424->supplies[i].supply = tas6424_supply_names[i];  	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies), @@ -671,6 +733,10 @@ static int tas6424_i2c_remove(struct i2c_client *client)  	cancel_delayed_work_sync(&tas6424->fault_check_work); +	/* put the codec in stand-by */ +	if (tas6424->standby_gpio) +		gpiod_set_value_cansleep(tas6424->standby_gpio, 1); +  	ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),  				     tas6424->supplies);  	if (ret < 0) { |