aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8903.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r--sound/soc/codecs/wm8903.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 43e3d760766..0218d6ce055 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1268,9 +1268,9 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1268 aif1 |= 0x2; 1268 aif1 |= 0x2;
1269 break; 1269 break;
1270 case SND_SOC_DAIFMT_RIGHT_J: 1270 case SND_SOC_DAIFMT_RIGHT_J:
1271 aif1 |= 0x1;
1272 break; 1271 break;
1273 case SND_SOC_DAIFMT_LEFT_J: 1272 case SND_SOC_DAIFMT_LEFT_J:
1273 aif1 |= 0x1;
1274 break; 1274 break;
1275 default: 1275 default:
1276 return -EINVAL; 1276 return -EINVAL;
@@ -1457,6 +1457,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1457 int fs = params_rate(params); 1457 int fs = params_rate(params);
1458 int bclk; 1458 int bclk;
1459 int bclk_div; 1459 int bclk_div;
1460 int real_bclk_div;
1460 int i; 1461 int i;
1461 int dsp_config; 1462 int dsp_config;
1462 int clk_config; 1463 int clk_config;
@@ -1493,7 +1494,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1493 clock1 |= sample_rates[dsp_config].value; 1494 clock1 |= sample_rates[dsp_config].value;
1494 1495
1495 aif1 &= ~WM8903_AIF_WL_MASK; 1496 aif1 &= ~WM8903_AIF_WL_MASK;
1496 bclk = 2 * fs; 1497 bclk = 4 * fs;
1497 switch (params_format(params)) { 1498 switch (params_format(params)) {
1498 case SNDRV_PCM_FORMAT_S16_LE: 1499 case SNDRV_PCM_FORMAT_S16_LE:
1499 bclk *= 16; 1500 bclk *= 16;
@@ -1561,27 +1562,22 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1561 * higher than the target (we need to ensure that there enough 1562 * higher than the target (we need to ensure that there enough
1562 * BCLKs to clock out the samples). 1563 * BCLKs to clock out the samples).
1563 */ 1564 */
1564 bclk_div = 0;
1565 best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
1566 i = 1;
1567 while (i < ARRAY_SIZE(bclk_divs)) {
1568 cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
1569 if (cur_val < 0) /* BCLK table is sorted */
1570 break;
1571 bclk_div = i;
1572 best_val = cur_val;
1573 i++;
1574 }
1575 1565
1576 aif2 &= ~WM8903_BCLK_DIV_MASK; 1566 aif2 &= ~WM8903_BCLK_DIV_MASK;
1577 aif3 &= ~WM8903_LRCLK_RATE_MASK; 1567 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1578 1568
1579 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", 1569 bclk_div = real_bclk_div = 0;
1580 bclk_divs[bclk_div].ratio / 10, bclk, 1570 cur_val = clk_sys;
1581 (clk_sys * 10) / bclk_divs[bclk_div].ratio); 1571 best_val = clk_sys;
1582 1572 while(!(best_val % fs) &&
1583 aif2 |= bclk_divs[bclk_div].div; 1573 (cur_val >= bclk)){
1584 aif3 |= bclk / fs; 1574 real_bclk_div = bclk_div;
1575 bclk_div++;
1576 cur_val = best_val;
1577 best_val /= 2;
1578 }
1579 aif2 |= (real_bclk_div ? 1<<real_bclk_div : 0);
1580 aif3 |= cur_val / fs;
1585 1581
1586 wm8903->fs = params_rate(params); 1582 wm8903->fs = params_rate(params);
1587 wm8903_set_deemph(codec); 1583 wm8903_set_deemph(codec);
@@ -1761,6 +1757,11 @@ static struct snd_soc_dai_driver wm8903_dai = {
1761 1757
1762static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state) 1758static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
1763{ 1759{
1760 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1761
1762 if (wm8903->irq)
1763 disable_irq(wm8903->irq);
1764
1764 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1765 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1765 1766
1766 return 0; 1767 return 0;
@@ -1768,11 +1769,15 @@ static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
1768 1769
1769static int wm8903_resume(struct snd_soc_codec *codec) 1770static int wm8903_resume(struct snd_soc_codec *codec)
1770{ 1771{
1772 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1771 int i; 1773 int i;
1772 u16 *reg_cache = codec->reg_cache; 1774 u16 *reg_cache = codec->reg_cache;
1773 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), 1775 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
1774 GFP_KERNEL); 1776 GFP_KERNEL);
1775 1777
1778 if (wm8903->irq)
1779 enable_irq(wm8903->irq);
1780
1776 /* Bring the codec back up to standby first to minimise pop/clicks */ 1781 /* Bring the codec back up to standby first to minimise pop/clicks */
1777 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1782 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1778 1783
@@ -2046,8 +2051,13 @@ static int wm8903_probe(struct snd_soc_codec *codec)
2046/* power down chip */ 2051/* power down chip */
2047static int wm8903_remove(struct snd_soc_codec *codec) 2052static int wm8903_remove(struct snd_soc_codec *codec)
2048{ 2053{
2054 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
2055
2049 wm8903_free_gpio(codec); 2056 wm8903_free_gpio(codec);
2050 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 2057 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
2058 if (wm8903->irq)
2059 free_irq(wm8903->irq, codec);
2060
2051 return 0; 2061 return 0;
2052} 2062}
2053 2063