Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 257492
b: refs/heads/master
c: 6dffdea
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Jun 6, 2011
1 parent 8c6bc01 commit 47f455b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bd4f2acb8dfbff473f1abe805bca902720f653b4
refs/heads/master: 6dffdea70029f2e74c029eba3c24d07641fa4a77
82 changes: 53 additions & 29 deletions trunk/sound/soc/codecs/wm8915.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct wm8915_priv {
struct wm8915_pdata pdata;

int rx_rate[WM8915_AIFS];
int bclk_rate[WM8915_AIFS];

/* Platform dependant ReTune mobile configuration */
int num_retune_mobile_texts;
Expand Down Expand Up @@ -1562,6 +1563,50 @@ static int wm8915_reset(struct snd_soc_codec *codec)
return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
}

static const int bclk_divs[] = {
1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
};

static void wm8915_update_bclk(struct snd_soc_codec *codec)
{
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
int aif, best, cur_val, bclk_rate, bclk_reg, i;

/* Don't bother if we're in a low frequency idle mode that
* can't support audio.
*/
if (wm8915->sysclk < 64000)
return;

for (aif = 0; aif < WM8915_AIFS; aif++) {
switch (aif) {
case 0:
bclk_reg = WM8915_AIF1_BCLK;
break;
case 1:
bclk_reg = WM8915_AIF2_BCLK;
break;
}

bclk_rate = wm8915->bclk_rate[aif];

/* Pick a divisor for BCLK as close as we can get to ideal */
best = 0;
for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
if (cur_val < 0) /* BCLK table is sorted */
break;
best = i;
}
bclk_rate = wm8915->sysclk / bclk_divs[best];
dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);

snd_soc_update_bits(codec, bclk_reg,
WM8915_AIF1_BCLK_DIV_MASK, best);
}
}

static int wm8915_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
Expand Down Expand Up @@ -1714,10 +1759,6 @@ static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}

static const int bclk_divs[] = {
1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
};

static const int dsp_divs[] = {
48000, 32000, 16000, 8000
};
Expand All @@ -1728,17 +1769,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
int bits, i, bclk_rate, best, cur_val;
int bits, i, bclk_rate;
int aifdata = 0;
int bclk = 0;
int lrclk = 0;
int dsp = 0;
int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;

if (!wm8915->sysclk) {
dev_err(codec->dev, "SYSCLK not configured\n");
return -EINVAL;
}
int aifdata_reg, lrclk_reg, dsp_shift;

switch (dai->id) {
case 0:
Expand All @@ -1750,7 +1785,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
}
bclk_reg = WM8915_AIF1_BCLK;
dsp_shift = 0;
break;
case 1:
Expand All @@ -1762,7 +1796,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
}
bclk_reg = WM8915_AIF2_BCLK;
dsp_shift = WM8915_DSP2_DIV_SHIFT;
break;
default:
Expand All @@ -1776,6 +1809,9 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
return bclk_rate;
}

wm8915->bclk_rate[dai->id] = bclk_rate;
wm8915->rx_rate[dai->id] = params_rate(params);

/* Needs looking at for TDM */
bits = snd_pcm_format_width(params_format(params));
if (bits < 0)
Expand All @@ -1793,18 +1829,7 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
}
dsp |= i << dsp_shift;

/* Pick a divisor for BCLK as close as we can get to ideal */
best = 0;
for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
if (cur_val < 0) /* BCLK table is sorted */
break;
best = i;
}
bclk_rate = wm8915->sysclk / bclk_divs[best];
dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);
bclk |= best;
wm8915_update_bclk(codec);

lrclk = bclk_rate / params_rate(params);
dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
Expand All @@ -1814,14 +1839,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
WM8915_AIF1TX_WL_MASK |
WM8915_AIF1TX_SLOT_LEN_MASK,
aifdata);
snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
lrclk);
snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);

wm8915->rx_rate[dai->id] = params_rate(params);

return 0;
}

Expand Down Expand Up @@ -1882,6 +1904,8 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
return -EINVAL;
}

wm8915_update_bclk(codec);

snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
Expand Down

0 comments on commit 47f455b

Please sign in to comment.