diff options
Diffstat (limited to 'sound/soc/codecs/es8328.c')
| -rw-r--r-- | sound/soc/codecs/es8328.c | 183 |
1 files changed, 105 insertions, 78 deletions
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index f3c97da798dc..9838fe42cb6f 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -142,7 +142,7 @@ static int es8328_set_deemph(struct snd_soc_component *component) static int es8328_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = es8328->deemph; @@ -152,7 +152,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol, static int es8328_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component); unsigned int deemph = ucontrol->value.integer.value[0]; int ret; @@ -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; } @@ -233,7 +232,6 @@ static const struct snd_kcontrol_new es8328_right_line_controls = /* Left Mixer */ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { - SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0), SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0), SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0), SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0), @@ -243,7 +241,6 @@ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0), SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0), - SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0), SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0), }; @@ -336,10 +333,10 @@ static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, ES8328_DACPOWER_LDAC_OFF, 1), - SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER("Left Mixer", ES8328_DACCONTROL17, 7, 0, &es8328_left_mixer_controls[0], ARRAY_SIZE(es8328_left_mixer_controls)), - SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER("Right Mixer", ES8328_DACCONTROL20, 7, 0, &es8328_right_mixer_controls[0], ARRAY_SIZE(es8328_right_mixer_controls)), @@ -408,29 +405,14 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = { { "Mic Bias", NULL, "Mic Bias Gen" }, - { "Left Line Mux", "Line 1", "LINPUT1" }, - { "Left Line Mux", "Line 2", "LINPUT2" }, - { "Left Line Mux", "PGA", "Left PGA Mux" }, - { "Left Line Mux", "Differential", "Differential Mux" }, - - { "Right Line Mux", "Line 1", "RINPUT1" }, - { "Right Line Mux", "Line 2", "RINPUT2" }, - { "Right Line Mux", "PGA", "Right PGA Mux" }, - { "Right Line Mux", "Differential", "Differential Mux" }, - - { "Left Out 1", NULL, "Left DAC" }, - { "Right Out 1", NULL, "Right DAC" }, - { "Left Out 2", NULL, "Left DAC" }, - { "Right Out 2", NULL, "Right DAC" }, - - { "Left Mixer", "Playback Switch", "Left DAC" }, + { "Left Mixer", NULL, "Left DAC" }, { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, { "Left Mixer", "Right Playback Switch", "Right DAC" }, { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, { "Right Mixer", "Left Playback Switch", "Left DAC" }, { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, - { "Right Mixer", "Playback Switch", "Right DAC" }, + { "Right Mixer", NULL, "Right DAC" }, { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, { "DAC DIG", NULL, "DAC STM" }, @@ -478,6 +460,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component); + int ret; int i; int reg; int wl; @@ -511,9 +494,12 @@ static int es8328_hw_params(struct snd_pcm_substream *substream, es8328->mclkdiv2 = 0; } - snd_soc_component_update_bits(component, ES8328_MASTERMODE, - ES8328_MASTERMODE_MCLKDIV2, - es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0); + ret = snd_soc_component_update_bits(component, ES8328_MASTERMODE, + ES8328_MASTERMODE_MCLKDIV2, + es8328->mclkdiv2 ? + ES8328_MASTERMODE_MCLKDIV2 : 0); + if (ret < 0) + return ret; switch (params_width(params)) { case 16: @@ -536,18 +522,28 @@ static int es8328_hw_params(struct snd_pcm_substream *substream, } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_soc_component_update_bits(component, ES8328_DACCONTROL1, - ES8328_DACCONTROL1_DACWL_MASK, - wl << ES8328_DACCONTROL1_DACWL_SHIFT); + ret = snd_soc_component_update_bits(component, ES8328_DACCONTROL1, + ES8328_DACCONTROL1_DACWL_MASK, + wl << ES8328_DACCONTROL1_DACWL_SHIFT); + if (ret < 0) + return ret; es8328->playback_fs = params_rate(params); - es8328_set_deemph(component); - } else - snd_soc_component_update_bits(component, ES8328_ADCCONTROL4, - ES8328_ADCCONTROL4_ADCWL_MASK, - wl << ES8328_ADCCONTROL4_ADCWL_SHIFT); + ret = es8328_set_deemph(component); + if (ret < 0) + return ret; + } else { + ret = snd_soc_component_update_bits(component, ES8328_ADCCONTROL4, + ES8328_ADCCONTROL4_ADCWL_MASK, + wl << ES8328_ADCCONTROL4_ADCWL_SHIFT); + if (ret < 0) + return ret; + } - return snd_soc_component_update_bits(component, reg, ES8328_RATEMASK, ratio); + ret = snd_soc_component_update_bits(component, reg, ES8328_RATEMASK, ratio); + if (ret < 0) + return ret; + return 0; } static int es8328_set_sysclk(struct snd_soc_dai *codec_dai, @@ -596,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, - ES8328_MASTERMODE_MSC, - ES8328_MASTERMODE_MSC); + 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, - ES8328_MASTERMODE_MSC, 0); + ret = snd_soc_component_update_bits(component, ES8328_MASTERMODE, + ES8328_MASTERMODE_MSC, 0); + if (ret < 0) + return ret; es8328->provider = false; break; default: @@ -639,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; } @@ -650,49 +658,65 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, 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: break; 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, - ES8328_CONTROL1_VMIDSEL_MASK | - ES8328_CONTROL1_ENREF, - ES8328_CONTROL1_VMIDSEL_50k | - ES8328_CONTROL1_ENREF); + 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_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { - snd_soc_component_update_bits(component, ES8328_CONTROL1, - ES8328_CONTROL1_VMIDSEL_MASK | - ES8328_CONTROL1_ENREF, - ES8328_CONTROL1_VMIDSEL_5k | - ES8328_CONTROL1_ENREF); + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { + 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, - ES8328_CONTROL2_OVERCURRENT_ON | - ES8328_CONTROL2_THERMAL_SHUTDOWN_ON); + 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, - ES8328_CONTROL1_VMIDSEL_MASK | - ES8328_CONTROL1_ENREF, - ES8328_CONTROL1_VMIDSEL_500k | - ES8328_CONTROL1_ENREF); + 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, - ES8328_CONTROL1_VMIDSEL_MASK | - ES8328_CONTROL1_ENREF, - 0); + 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; @@ -747,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"); @@ -763,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) |
