Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230370
b: refs/heads/master
c: 69fff9b
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Dec 11, 2010
1 parent c88acbc commit e2c1188
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 9 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: f2c1fe090093ed62271473342f093df53c4f8a59
refs/heads/master: 69fff9bbbc4d214ed22c8f89681af3871a128e35
82 changes: 74 additions & 8 deletions trunk/sound/soc/codecs/wm8903.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ struct wm8903_priv {
int sysclk;
int irq;

int fs;
int deemph;

/* Reference count */
int class_w_users;

Expand Down Expand Up @@ -457,6 +460,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }


static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };

static int wm8903_set_deemph(struct snd_soc_codec *codec)
{
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int val, i, best;

/* If we're using deemphasis select the nearest available sample
* rate.
*/
if (wm8903->deemph) {
best = 1;
for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
if (abs(wm8903_deemph[i] - wm8903->fs) <
abs(wm8903_deemph[best] - wm8903->fs))
best = i;
}

val = best << WM8903_DEEMPH_SHIFT;
} else {
best = 0;
val = 0;
}

dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
best, wm8903_deemph[best]);

return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
WM8903_DEEMPH_MASK, val);
}

static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);

ucontrol->value.enumerated.item[0] = wm8903->deemph;

return 0;
}

static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int deemph = ucontrol->value.enumerated.item[0];
int ret = 0;

if (deemph > 1)
return -EINVAL;

mutex_lock(&codec->mutex);
if (wm8903->deemph != deemph) {
wm8903->deemph = deemph;

wm8903_set_deemph(codec);

ret = 1;
}
mutex_unlock(&codec->mutex);

return ret;
}

/* ALSA can only do steps of .01dB */
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);

Expand Down Expand Up @@ -548,13 +617,6 @@ static const char *mute_mode_text[] = {
static const struct soc_enum mute_mode =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);

static const char *dac_deemphasis_text[] = {
"Disabled", "32kHz", "44.1kHz", "48kHz"
};

static const struct soc_enum dac_deemphasis =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);

static const char *companding_text[] = {
"ulaw", "alaw"
};
Expand Down Expand Up @@ -662,9 +724,10 @@ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
SOC_ENUM("DAC Soft Mute Rate", soft_mute),
SOC_ENUM("DAC Mute Mode", mute_mode),
SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
SOC_ENUM("DAC De-emphasis", dac_deemphasis),
SOC_ENUM("DAC Companding Mode", dac_companding),
SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
wm8903_get_deemph, wm8903_put_deemph),

/* Headphones */
SOC_DOUBLE_R("Headphone Switch",
Expand Down Expand Up @@ -1374,6 +1437,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
aif2 |= bclk_divs[bclk_div].div;
aif3 |= bclk / fs;

wm8903->fs = params_rate(params);
wm8903_set_deemph(codec);

snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
Expand Down

0 comments on commit e2c1188

Please sign in to comment.