Unverified Commit d83039b5 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: es8328: error handling and resume fixes

Merge series from Hsieh Hung-En <hungen3108@gmail.com>:

This series fixes some issues and improves robustness in the es8328
driver.
parents 0f625fc2 8232e607
Loading
Loading
Loading
Loading
+73 −43
Original line number Diff line number Diff line
@@ -163,12 +163,11 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
	if (es8328->deemph == deemph)
		return 0;

	es8328->deemph = deemph;
	ret = es8328_set_deemph(component);
	if (ret < 0)
		return ret;

	es8328->deemph = deemph;

	return 1;
}

@@ -530,7 +529,9 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
			return ret;

		es8328->playback_fs = params_rate(params);
		es8328_set_deemph(component);
		ret = es8328_set_deemph(component);
		if (ret < 0)
			return ret;
	} else {
		ret = snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
						    ES8328_ADCCONTROL4_ADCWL_MASK,
@@ -591,21 +592,26 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
{
	struct snd_soc_component *component = codec_dai->component;
	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
	int ret;
	u8 dac_mode = 0;
	u8 adc_mode = 0;

	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBP_CFP:
		/* Master serial port mode, with BCLK generated automatically */
		snd_soc_component_update_bits(component, ES8328_MASTERMODE,
		ret = snd_soc_component_update_bits(component, ES8328_MASTERMODE,
						    ES8328_MASTERMODE_MSC,
						    ES8328_MASTERMODE_MSC);
		if (ret < 0)
			return ret;
		es8328->provider = true;
		break;
	case SND_SOC_DAIFMT_CBC_CFC:
		/* Slave serial port mode */
		snd_soc_component_update_bits(component, ES8328_MASTERMODE,
		ret = snd_soc_component_update_bits(component, ES8328_MASTERMODE,
						    ES8328_MASTERMODE_MSC, 0);
		if (ret < 0)
			return ret;
		es8328->provider = false;
		break;
	default:
@@ -634,10 +640,17 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF)
		return -EINVAL;

	snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
			ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode);
	snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
			ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
	ret = snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
					    ES8328_DACCONTROL1_DACFORMAT_MASK,
					    dac_mode);
	if (ret < 0)
		return ret;

	ret = snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
					    ES8328_ADCCONTROL4_ADCFORMAT_MASK,
					    adc_mode);
	if (ret < 0)
		return ret;

	return 0;
}
@@ -646,6 +659,7 @@ static int es8328_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
	int ret;

	switch (level) {
	case SND_SOC_BIAS_ON:
@@ -653,43 +667,56 @@ static int es8328_set_bias_level(struct snd_soc_component *component,

	case SND_SOC_BIAS_PREPARE:
		/* VREF, VMID=2x50k, digital enabled */
		snd_soc_component_write(component, ES8328_CHIPPOWER, 0);
		snd_soc_component_update_bits(component, ES8328_CONTROL1,
		ret = snd_soc_component_write(component, ES8328_CHIPPOWER, 0);
		if (ret < 0)
			return ret;

		ret = snd_soc_component_update_bits(component, ES8328_CONTROL1,
						    ES8328_CONTROL1_VMIDSEL_MASK |
						    ES8328_CONTROL1_ENREF,
						    ES8328_CONTROL1_VMIDSEL_50k |
						    ES8328_CONTROL1_ENREF);
		if (ret < 0)
			return ret;
		break;

	case SND_SOC_BIAS_STANDBY:
		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
			snd_soc_component_update_bits(component, ES8328_CONTROL1,
			ret = snd_soc_component_update_bits(component, ES8328_CONTROL1,
							    ES8328_CONTROL1_VMIDSEL_MASK |
							    ES8328_CONTROL1_ENREF,
							    ES8328_CONTROL1_VMIDSEL_5k |
							    ES8328_CONTROL1_ENREF);
			if (ret < 0)
				return ret;

			/* Charge caps */
			msleep(100);
		}

		snd_soc_component_write(component, ES8328_CONTROL2,
		ret = snd_soc_component_write(component, ES8328_CONTROL2,
					      ES8328_CONTROL2_OVERCURRENT_ON |
					      ES8328_CONTROL2_THERMAL_SHUTDOWN_ON);
		if (ret < 0)
			return ret;

		/* VREF, VMID=2*500k, digital stopped */
		snd_soc_component_update_bits(component, ES8328_CONTROL1,
		ret = snd_soc_component_update_bits(component, ES8328_CONTROL1,
						    ES8328_CONTROL1_VMIDSEL_MASK |
						    ES8328_CONTROL1_ENREF,
						    ES8328_CONTROL1_VMIDSEL_500k |
						    ES8328_CONTROL1_ENREF);
		if (ret < 0)
			return ret;
		break;

	case SND_SOC_BIAS_OFF:
		snd_soc_component_update_bits(component, ES8328_CONTROL1,
		ret = snd_soc_component_update_bits(component, ES8328_CONTROL1,
						    ES8328_CONTROL1_VMIDSEL_MASK |
						    ES8328_CONTROL1_ENREF,
						    0);
		if (ret < 0)
			return ret;
		break;
	}
	return 0;
@@ -744,12 +771,9 @@ static int es8328_suspend(struct snd_soc_component *component)

static int es8328_resume(struct snd_soc_component *component)
{
	struct regmap *regmap = dev_get_regmap(component->dev, NULL);
	struct es8328_priv *es8328;
	struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
	int ret;

	es8328 = snd_soc_component_get_drvdata(component);

	ret = clk_prepare_enable(es8328->clk);
	if (ret) {
		dev_err(component->dev, "unable to enable clock\n");
@@ -760,17 +784,23 @@ static int es8328_resume(struct snd_soc_component *component)
					es8328->supplies);
	if (ret) {
		dev_err(component->dev, "unable to enable regulators\n");
		return ret;
		goto err_clk;
	}

	regcache_mark_dirty(regmap);
	ret = regcache_sync(regmap);
	regcache_mark_dirty(es8328->regmap);
	ret = regcache_sync(es8328->regmap);
	if (ret) {
		dev_err(component->dev, "unable to sync regcache\n");
		return ret;
		goto err_regulators;
	}

	return 0;

err_regulators:
	regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), es8328->supplies);
err_clk:
	clk_disable_unprepare(es8328->clk);
	return ret;
}

static int es8328_component_probe(struct snd_soc_component *component)