Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230374
b: refs/heads/master
c: 474b9c8
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Dec 13, 2010
1 parent 53f11d4 commit e02cd9a
Show file tree
Hide file tree
Showing 7 changed files with 424 additions and 91 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: fdea0571ddca8e3f22448f66d72a034575abea28
refs/heads/master: 474b9c86b0c65e9ca6a77d8b7bf132c4d5993b9c
182 changes: 96 additions & 86 deletions trunk/sound/soc/codecs/wm8903.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ struct wm8903_priv {
int sysclk;
int irq;

/* Reference counts */
int fs;
int deemph;

/* Reference count */
int class_w_users;
int playback_active;
int capture_active;

struct completion wseq;

Expand All @@ -230,9 +231,6 @@ struct wm8903_priv {
int mic_short;
int mic_last_report;
int mic_delay;

struct snd_pcm_substream *master_substream;
struct snd_pcm_substream *slave_substream;
};

static int wm8903_volatile_register(unsigned int reg)
Expand Down Expand Up @@ -462,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 All @@ -474,6 +538,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);

static const char *hpf_mode_text[] = {
"Hi-fi", "Voice 1", "Voice 2", "Voice 3"
};

static const struct soc_enum hpf_mode =
SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);

static const char *osr_text[] = {
"Low power", "High performance"
};

static const struct soc_enum adc_osr =
SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);

static const struct soc_enum dac_osr =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);

static const char *drc_slope_text[] = {
"1", "1/2", "1/4", "1/8", "1/16", "0"
};
Expand Down Expand Up @@ -536,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 @@ -612,6 +686,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
6, 1, 0),

/* ADCs */
SOC_ENUM("ADC OSR", adc_osr),
SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
SOC_ENUM("HPF Mode", hpf_mode),
SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
Expand Down Expand Up @@ -641,14 +718,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
12, 0, digital_sidetone_tlv),

/* DAC */
SOC_ENUM("DAC OSR", dac_osr),
SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
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 @@ -1222,58 +1301,6 @@ static struct {
{ 0, 0 },
};

static int wm8903_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
struct snd_pcm_runtime *master_runtime;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
wm8903->playback_active++;
else
wm8903->capture_active++;

/* The DAI has shared clocks so if we already have a playback or
* capture going then constrain this substream to match it.
*/
if (wm8903->master_substream) {
master_runtime = wm8903->master_substream->runtime;

dev_dbg(codec->dev, "Constraining to %d bits\n",
master_runtime->sample_bits);

snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
master_runtime->sample_bits,
master_runtime->sample_bits);

wm8903->slave_substream = substream;
} else
wm8903->master_substream = substream;

return 0;
}

static void wm8903_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
wm8903->playback_active--;
else
wm8903->capture_active--;

if (wm8903->master_substream == substream)
wm8903->master_substream = wm8903->slave_substream;

wm8903->slave_substream = NULL;
}

static int wm8903_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
Expand All @@ -1298,11 +1325,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);

if (substream == wm8903->slave_substream) {
dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
return 0;
}

/* Enable sloping stopband filter for low sample rates */
if (fs <= 24000)
dac_digital1 |= WM8903_DAC_SB_FILT;
Expand All @@ -1320,19 +1342,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
}
}

/* Constraints should stop us hitting this but let's make sure */
if (wm8903->capture_active)
switch (sample_rates[dsp_config].rate) {
case 88200:
case 96000:
dev_err(codec->dev, "%dHz unsupported by ADC\n",
fs);
return -EINVAL;

default:
break;
}

dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
clock1 &= ~WM8903_SAMPLE_RATE_MASK;
clock1 |= sample_rates[dsp_config].value;
Expand Down Expand Up @@ -1428,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 Expand Up @@ -1571,8 +1583,6 @@ static irqreturn_t wm8903_irq(int irq, void *data)
SNDRV_PCM_FMTBIT_S24_LE)

static struct snd_soc_dai_ops wm8903_dai_ops = {
.startup = wm8903_startup,
.shutdown = wm8903_shutdown,
.hw_params = wm8903_hw_params,
.digital_mute = wm8903_digital_mute,
.set_fmt = wm8903_set_dai_fmt,
Expand Down
21 changes: 17 additions & 4 deletions trunk/sound/soc/codecs/wm8994.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,16 @@ static const struct soc_enum aif2dacl_src =
static const struct soc_enum aif2dacr_src =
SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);

static const char *osr_text[] = {
"Low Power", "High Performance",
};

static const struct soc_enum dac_osr =
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);

static const struct soc_enum adc_osr =
SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);

static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
Expand Down Expand Up @@ -780,13 +790,13 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,

SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
SOC_ENUM("AIF2ADCL Source", aif1adcl_src),
SOC_ENUM("AIF2ADCR Source", aif1adcr_src),
SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
SOC_ENUM("AIF2ADCR Source", aif2adcr_src),

SOC_ENUM("AIF1DACL Source", aif1dacl_src),
SOC_ENUM("AIF1DACR Source", aif1dacr_src),
SOC_ENUM("AIF2DACL Source", aif1dacl_src),
SOC_ENUM("AIF2DACR Source", aif1dacr_src),
SOC_ENUM("AIF2DACL Source", aif2dacl_src),
SOC_ENUM("AIF2DACR Source", aif2dacr_src),

SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
Expand Down Expand Up @@ -834,6 +844,9 @@ SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),

SOC_ENUM("ADC OSR", adc_osr),
SOC_ENUM("DAC OSR", dac_osr),

SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
Expand Down
4 changes: 4 additions & 0 deletions trunk/sound/soc/codecs/wm9081.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);

/* Set gain to the recommended value */
snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
WM9081_FLL_GAIN_MASK, 0);

/* Enable the FLL */
snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);

Expand Down
8 changes: 8 additions & 0 deletions trunk/sound/soc/samsung/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ config ASOC_SAMSUNG_SIMTEC_HERMES
select SND_SOC_TLV320AIC3X
select ASOC_SAMSUNG_SIMTEC

config ASOC_SAMSUNG_H1940_UDA1380
tristate "Audio support for the HP iPAQ H1940"
depends on ASOC_SAMSUNG && ARCH_H1940
select SND_S3C24XX_I2S
select SND_SOC_UDA1380
help
This driver provides audio support for HP iPAQ h1940 PDA.

config ASOC_SAMSUNG_RX1950_UDA1380
tristate "Audio support for the HP iPAQ RX1950"
depends on ASOC_SAMSUNG && MACH_RX1950
Expand Down
2 changes: 2 additions & 0 deletions trunk/sound/soc/samsung/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
snd-soc-h1940-uda1380-objs := h1940_uda1380.o
snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
snd-soc-smdk-wm8580-objs := smdk_wm8580.o
snd-soc-smdk-wm9713-objs := smdk_wm9713.o
Expand All @@ -43,6 +44,7 @@ obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
obj-$(CONFIG_ASOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
Expand Down
Loading

0 comments on commit e02cd9a

Please sign in to comment.