diff options
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/wm2000.c | 59 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 105 |
2 files changed, 87 insertions, 77 deletions
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index a75c3766aede..0418fa11e6bd 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -99,8 +99,9 @@ static void wm2000_reset(struct wm2000_priv *wm2000) } static int wm2000_poll_bit(struct i2c_client *i2c, - unsigned int reg, u8 mask, int timeout) + unsigned int reg, u8 mask) { + int timeout = 4000; int val; val = wm2000_read(i2c, reg); @@ -119,7 +120,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c, static int wm2000_power_up(struct i2c_client *i2c, int analogue) { struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - int ret, timeout; + int ret; BUG_ON(wm2000->anc_mode != ANC_OFF); @@ -140,13 +141,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) /* Wait for ANC engine to become ready */ if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, - WM2000_ANC_ENG_IDLE, 1)) { + WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, "ANC engine failed to reset\n"); return -ETIMEDOUT; } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_BOOT_COMPLETE, 1)) { + WM2000_STATUS_BOOT_COMPLETE)) { dev_err(&i2c->dev, "ANC engine failed to initialise\n"); return -ETIMEDOUT; } @@ -173,16 +174,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) dev_dbg(&i2c->dev, "Download complete\n"); if (analogue) { - timeout = 248; - wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4); + wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4); wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_MOUSE_ENABLE | WM2000_MODE_THERMAL_ENABLE); } else { - timeout = 10; - wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_MOUSE_ENABLE | WM2000_MODE_THERMAL_ENABLE); @@ -201,9 +199,8 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_MOUSE_ACTIVE, timeout)) { - dev_err(&i2c->dev, "Timed out waiting for device after %dms\n", - timeout * 10); + WM2000_STATUS_MOUSE_ACTIVE)) { + dev_err(&i2c->dev, "Timed out waiting for device\n"); return -ETIMEDOUT; } @@ -218,28 +215,25 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) static int wm2000_power_down(struct i2c_client *i2c, int analogue) { struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - int timeout; if (analogue) { - timeout = 248; - wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4); + wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4); wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_POWER_DOWN); } else { - timeout = 10; wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_POWER_DOWN); } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) { + WM2000_STATUS_POWER_DOWN_COMPLETE)) { dev_err(&i2c->dev, "Timeout waiting for ANC power down\n"); return -ETIMEDOUT; } if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, - WM2000_ANC_ENG_IDLE, 1)) { + WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); return -ETIMEDOUT; } @@ -268,13 +262,13 @@ static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue) } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_ANC_DISABLED, 10)) { + WM2000_STATUS_ANC_DISABLED)) { dev_err(&i2c->dev, "Timeout waiting for ANC disable\n"); return -ETIMEDOUT; } if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, - WM2000_ANC_ENG_IDLE, 1)) { + WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); return -ETIMEDOUT; } @@ -311,7 +305,7 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_MOUSE_ACTIVE, 10)) { + WM2000_STATUS_MOUSE_ACTIVE)) { dev_err(&i2c->dev, "Timed out waiting for MOUSE\n"); return -ETIMEDOUT; } @@ -325,38 +319,32 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) { struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - int timeout; BUG_ON(wm2000->anc_mode != ANC_ACTIVE); if (analogue) { - timeout = 248; - wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4); + wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4); wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_STANDBY_ENTRY); } else { - timeout = 10; - wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_STANDBY_ENTRY); } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_ANC_DISABLED, timeout)) { + WM2000_STATUS_ANC_DISABLED)) { dev_err(&i2c->dev, "Timed out waiting for ANC disable after 1ms\n"); return -ETIMEDOUT; } - if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE, - 1)) { + if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, - "Timed out waiting for standby after %dms\n", - timeout * 10); + "Timed out waiting for standby\n"); return -ETIMEDOUT; } @@ -374,23 +362,19 @@ static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) { struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - int timeout; BUG_ON(wm2000->anc_mode != ANC_STANDBY); wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0); if (analogue) { - timeout = 248; - wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4); + wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4); wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_MOUSE_ENABLE); } else { - timeout = 10; - wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_MOUSE_ENABLE); @@ -400,9 +384,8 @@ static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, - WM2000_STATUS_MOUSE_ACTIVE, timeout)) { - dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n", - timeout * 10); + WM2000_STATUS_MOUSE_ACTIVE)) { + dev_err(&i2c->dev, "Timed out waiting for MOUSE\n"); return -ETIMEDOUT; } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 993639d694ce..aa8c98b628da 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -46,6 +46,39 @@ #define WM8994_NUM_DRC 3 #define WM8994_NUM_EQ 3 +static struct { + unsigned int reg; + unsigned int mask; +} wm8994_vu_bits[] = { + { WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, + { WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, + { WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU }, + { WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU }, + { WM8994_SPEAKER_VOLUME_LEFT, WM8994_SPKOUT_VU }, + { WM8994_SPEAKER_VOLUME_RIGHT, WM8994_SPKOUT_VU }, + { WM8994_LEFT_OUTPUT_VOLUME, WM8994_HPOUT1_VU }, + { WM8994_RIGHT_OUTPUT_VOLUME, WM8994_HPOUT1_VU }, + { WM8994_LEFT_OPGA_VOLUME, WM8994_MIXOUT_VU }, + { WM8994_RIGHT_OPGA_VOLUME, WM8994_MIXOUT_VU }, + + { WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU }, + { WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU }, + { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU }, + { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU }, + { WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU }, + { WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU }, + { WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU }, + { WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU }, + { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU }, + { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, + { WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU }, + { WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, + { WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU }, + { WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU }, + { WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU }, + { WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU }, +}; + static int wm8994_drc_base[] = { WM8994_AIF1_DRC1_1, WM8994_AIF1_DRC2_1, @@ -989,6 +1022,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; struct wm8994 *control = codec->control_data; int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; + int i; int dac; int adc; int val; @@ -1047,6 +1081,13 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, WM8994_AIF1DAC2L_ENA); break; + case SND_SOC_DAPM_POST_PMU: + for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) + snd_soc_write(codec, wm8994_vu_bits[i].reg, + snd_soc_read(codec, + wm8994_vu_bits[i].reg)); + break; + case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, @@ -1072,6 +1113,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; + int i; int dac; int adc; int val; @@ -1122,6 +1164,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, WM8994_AIF2DACR_ENA); break; + case SND_SOC_DAPM_POST_PMU: + for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) + snd_soc_write(codec, wm8994_vu_bits[i].reg, + snd_soc_read(codec, + wm8994_vu_bits[i].reg)); + break; + case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, @@ -1190,17 +1239,19 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (wm8994->aif1clk_enable) { - aif1clk_ev(w, kcontrol, event); + aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU); snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, WM8994_AIF1CLK_ENA_MASK, WM8994_AIF1CLK_ENA); + aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU); wm8994->aif1clk_enable = 0; } if (wm8994->aif2clk_enable) { - aif2clk_ev(w, kcontrol, event); + aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU); snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, WM8994_AIF2CLK_ENA_MASK, WM8994_AIF2CLK_ENA); + aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU); wm8994->aif2clk_enable = 0; } break; @@ -1221,15 +1272,17 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMD: if (wm8994->aif1clk_disable) { + aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD); snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, WM8994_AIF1CLK_ENA_MASK, 0); - aif1clk_ev(w, kcontrol, event); + aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD); wm8994->aif1clk_disable = 0; } if (wm8994->aif2clk_disable) { + aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD); snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, WM8994_AIF2CLK_ENA_MASK, 0); - aif2clk_ev(w, kcontrol, event); + aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD); wm8994->aif2clk_disable = 0; } break; @@ -1527,9 +1580,11 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), @@ -3879,39 +3934,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) pm_runtime_put(codec->dev); - /* Latch volume updates (right only; we always do left then right). */ - snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, - WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); - snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, - WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); - snd_soc_update_bits(codec, WM8994_AIF1_DAC2_LEFT_VOLUME, - WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); - snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME, - WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); - snd_soc_update_bits(codec, WM8994_AIF2_DAC_LEFT_VOLUME, - WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); - snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME, - WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); - snd_soc_update_bits(codec, WM8994_AIF1_ADC1_LEFT_VOLUME, - WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); - snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, - WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); - snd_soc_update_bits(codec, WM8994_AIF1_ADC2_LEFT_VOLUME, - WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); - snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME, - WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); - snd_soc_update_bits(codec, WM8994_AIF2_ADC_LEFT_VOLUME, - WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); - snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME, - WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); - snd_soc_update_bits(codec, WM8994_DAC1_LEFT_VOLUME, - WM8994_DAC1_VU, WM8994_DAC1_VU); - snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME, - WM8994_DAC1_VU, WM8994_DAC1_VU); - snd_soc_update_bits(codec, WM8994_DAC2_LEFT_VOLUME, - WM8994_DAC2_VU, WM8994_DAC2_VU); - snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME, - WM8994_DAC2_VU, WM8994_DAC2_VU); + /* Latch volume update bits */ + for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) + snd_soc_update_bits(codec, wm8994_vu_bits[i].reg, + wm8994_vu_bits[i].mask, + wm8994_vu_bits[i].mask); /* Set the low bit of the 3D stereo depth so TLV matches */ snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2, |