Skip to content

Commit

Permalink
Merge branch 'topic/asoc' into for-linus
Browse files Browse the repository at this point in the history
  • Loading branch information
Takashi Iwai committed Jan 6, 2009
2 parents 238c6d5 + 2f42357 commit 5439e72
Show file tree
Hide file tree
Showing 9 changed files with 447 additions and 78 deletions.
15 changes: 15 additions & 0 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .kcontrols = wcontrols, \
.num_kcontrols = 1}

/* path domain with event - event handler must return 0 for success */
#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
Expand Down Expand Up @@ -172,6 +176,12 @@
.get = snd_soc_dapm_get_enum_double, \
.put = snd_soc_dapm_put_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_value_enum_double, \
.get = snd_soc_dapm_get_value_enum_double, \
.put = snd_soc_dapm_put_value_enum_double, \
.private_value = (unsigned long)&xenum }

/* dapm stream operations */
#define SND_SOC_DAPM_STREAM_NOP 0x0
Expand Down Expand Up @@ -214,6 +224,10 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
Expand Down Expand Up @@ -247,6 +261,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_input = 0, /* input pin */
snd_soc_dapm_output, /* output pin */
snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */
snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */
snd_soc_dapm_mixer, /* mixes several analog signals together */
snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */
snd_soc_dapm_adc, /* analog to digital converter */
Expand Down
30 changes: 30 additions & 0 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,22 @@
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
{ .max = xmax, .texts = xtexts }
#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
.mask = xmask, .max = xmax, .texts = xtexts, .values = xvalues}
#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
#define SOC_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_enum_double, \
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_value_enum_double, \
.get = snd_soc_get_value_enum_double, \
.put = snd_soc_put_value_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
Expand Down Expand Up @@ -200,6 +211,12 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
Expand Down Expand Up @@ -406,6 +423,19 @@ struct soc_enum {
void *dapm;
};

/* semi enumerated kcontrol */
struct soc_value_enum {
unsigned short reg;
unsigned short reg2;
unsigned char shift_l;
unsigned char shift_r;
unsigned int max;
unsigned int mask;
const char **texts;
const unsigned int *values;
void *dapm;
};

#include <sound/soc-dai.h>

#endif
25 changes: 16 additions & 9 deletions sound/arm/pxa2xx-ac97-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,6 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
{
int ret;

ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
if (ret < 0)
goto err;

if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
Expand All @@ -339,27 +335,38 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
if (IS_ERR(ac97conf_clk)) {
ret = PTR_ERR(ac97conf_clk);
ac97conf_clk = NULL;
goto err_irq;
goto err_conf;
}
}

ac97_clk = clk_get(&dev->dev, "AC97CLK");
if (IS_ERR(ac97_clk)) {
ret = PTR_ERR(ac97_clk);
ac97_clk = NULL;
goto err_irq;
goto err_clk;
}

return clk_enable(ac97_clk);
ret = clk_enable(ac97_clk);
if (ret)
goto err_clk2;

ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
if (ret < 0)
goto err_irq;

return 0;

err_irq:
GCR |= GCR_ACLINK_OFF;
err_clk2:
clk_put(ac97_clk);
ac97_clk = NULL;
err_clk:
if (ac97conf_clk) {
clk_put(ac97conf_clk);
ac97conf_clk = NULL;
}
free_irq(IRQ_AC97, NULL);
err:
err_conf:
return ret;
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
Expand Down
118 changes: 55 additions & 63 deletions sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,39 +192,51 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)

/* Earpiece */
static const char *twl4030_earpiece_texts[] =
{"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
{"Off", "DACL1", "DACL2", "DACR1"};

static const struct soc_enum twl4030_earpiece_enum =
SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
static const unsigned int twl4030_earpiece_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_value_enum twl4030_earpiece_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_earpiece_texts),
twl4030_earpiece_texts);
twl4030_earpiece_texts,
twl4030_earpiece_values);

static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);

/* PreDrive Left */
static const char *twl4030_predrivel_texts[] =
{"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
{"Off", "DACL1", "DACL2", "DACR2"};

static const unsigned int twl4030_predrivel_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_enum twl4030_predrivel_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
static const struct soc_value_enum twl4030_predrivel_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predrivel_texts),
twl4030_predrivel_texts);
twl4030_predrivel_texts,
twl4030_predrivel_values);

static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);

/* PreDrive Right */
static const char *twl4030_predriver_texts[] =
{"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
{"Off", "DACR1", "DACR2", "DACL2"};

static const struct soc_enum twl4030_predriver_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
static const unsigned int twl4030_predriver_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_value_enum twl4030_predriver_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predriver_texts),
twl4030_predriver_texts);
twl4030_predriver_texts,
twl4030_predriver_values);

static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);

/* Headset Left */
static const char *twl4030_hsol_texts[] =
Expand Down Expand Up @@ -300,28 +312,35 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);

/* Left analog microphone selection */
static const char *twl4030_analoglmic_texts[] =
{"Off", "Main mic", "Headset mic", "Invalid", "AUXL",
"Invalid", "Invalid", "Invalid", "Carkit mic"};
{"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};

static const unsigned int twl4030_analoglmic_values[] =
{0x0, 0x1, 0x2, 0x4, 0x8};

static const struct soc_enum twl4030_analoglmic_enum =
SOC_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0,
static const struct soc_value_enum twl4030_analoglmic_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
ARRAY_SIZE(twl4030_analoglmic_texts),
twl4030_analoglmic_texts);
twl4030_analoglmic_texts,
twl4030_analoglmic_values);

static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
SOC_DAPM_ENUM("Route", twl4030_analoglmic_enum);
SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum);

/* Right analog microphone selection */
static const char *twl4030_analogrmic_texts[] =
{"Off", "Sub mic", "Invalid", "Invalid", "AUXR"};
{"Off", "Sub mic", "AUXR"};

static const struct soc_enum twl4030_analogrmic_enum =
SOC_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0,
static const unsigned int twl4030_analogrmic_values[] =
{0x0, 0x1, 0x4};

static const struct soc_value_enum twl4030_analogrmic_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
ARRAY_SIZE(twl4030_analogrmic_texts),
twl4030_analogrmic_texts);
twl4030_analogrmic_texts,
twl4030_analogrmic_values);

static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
SOC_DAPM_ENUM("Route", twl4030_analogrmic_enum);
SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum);

/* TX1 L/R Analog/Digital microphone selection */
static const char *twl4030_micpathtx1_texts[] =
Expand All @@ -347,28 +366,6 @@ static const struct soc_enum twl4030_micpathtx2_enum =
static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);

/*
* This function filters out the non valid mux settings, named as "Invalid"
* in the enum texts.
* Just refuse to set an invalid mux mode.
*/
static int twl4030_enum_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
int ret = 0;
int val;

val = w->value >> e->shift_l;
if (!strcmp("Invalid", e->texts[val])) {
printk(KERN_WARNING "Invalid MUX setting on 0x%02x (%d)\n",
e->reg, val);
ret = -1;
}

return ret;
}

static int micpath_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
Expand Down Expand Up @@ -737,16 +734,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {

/* Output MUX controls */
/* Earpiece */
SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_control, twl4030_enum_event,
SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_control),
/* PreDrivL/R */
SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_control, twl4030_enum_event,
SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_control, twl4030_enum_event,
SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_control),
SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_control),
/* HeadsetL/R */
SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_control),
Expand Down Expand Up @@ -789,12 +783,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_POST_REG),

/* Analog input muxes with power switch for the physical ADCL/R */
SND_SOC_DAPM_MUX_E("Analog Left Capture Route",
TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control,
twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_MUX_E("Analog Right Capture Route",
TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control,
twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control),
SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control),

SND_SOC_DAPM_PGA("Analog Left Amplifier",
TWL4030_REG_ANAMICL, 4, 0, NULL, 0),
Expand Down
19 changes: 16 additions & 3 deletions sound/soc/davinci/davinci-evm.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "davinci-pcm.h"
#include "davinci-i2s.h"

#define EVM_CODEC_CLOCK 22579200

#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
Expand All @@ -37,6 +36,21 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int ret = 0;
unsigned sysclk;

/* ASP1 on DM355 EVM is clocked by an external oscillator */
if (machine_is_davinci_dm355_evm())
sysclk = 27000000;

/* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
else if (machine_is_davinci_evm())
sysclk = 12288000;

else
return -EINVAL;

/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
Expand All @@ -49,8 +63,7 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
return ret;

/* set the codec system clock */
ret = snd_soc_dai_set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK,
SND_SOC_CLOCK_OUT);
ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
if (ret < 0)
return ret;

Expand Down
1 change: 1 addition & 0 deletions sound/soc/omap/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config SND_OMAP_SOC_N810
tristate "SoC Audio support for Nokia N810"
depends on SND_OMAP_SOC && MACH_NOKIA_N810
select SND_OMAP_SOC_MCBSP
select OMAP_MUX
select SND_SOC_TLV320AIC3X
help
Say Y if you want to add support for SoC audio on Nokia N810.
Expand Down
Loading

0 comments on commit 5439e72

Please sign in to comment.