Skip to content

Commit

Permalink
ASoC: Decouple DAPM from CODECs
Browse files Browse the repository at this point in the history
Decoupling Dynamic Audio Power Management (DAPM) from codec devices is
required when developing ASoC further. Such as for other ASoC components to
have DAPM widgets or when extending DAPM to handle cross-device paths.

This patch decouples DAPM related variables from struct snd_soc_codec and
moves them to new struct snd_soc_dapm_context that is used to encapsulate
DAPM context of a device. ASoC core and API of DAPM functions are modified
to use DAPM context instead of codec.

This patch does not change current functionality and a large part of changes
come because of structure and internal API changes.

Core implementation is from Liam Girdwood <lrg@slimlogic.co.uk> with some
minor core changes, codecs and machine driver conversions from
Jarkko Nikula <jhnikula@gmail.com>.

Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Manuel Lauss <manuel.lauss@googlemail.com>
Cc: Mike Frysinger <vapier.adi@gmail.com>
Cc: Cliff Cai <cliff.cai@analog.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Ryan Mallon <ryan@bluewatersys.com>
Cc: Timur Tabi <timur@freescale.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Jassi Brar <jassi.brar@samsung.com>
Cc: Daniel Gloeckner <dg@emlix.com>
Cc: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Liam Girdwood authored and Mark Brown committed Nov 6, 2010
1 parent 22e2fda commit ce6120c
Show file tree
Hide file tree
Showing 108 changed files with 1,239 additions and 1,064 deletions.
49 changes: 36 additions & 13 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
struct snd_soc_dapm_pin;
struct snd_soc_dapm_route;
struct snd_soc_dapm_context;

int dapm_reg_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
Expand Down Expand Up @@ -324,16 +325,16 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num);

/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
void snd_soc_dapm_free(struct snd_soc_codec *codec);
int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);

/* dapm events */
Expand All @@ -343,17 +344,21 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card);

/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm);

/* dapm audio pin control and status */
int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin);
int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin);
int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin);
int snd_soc_dapm_sync(struct snd_soc_codec *codec);
int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec,
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
const char *pin);
int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin);
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
const char *pin);

/* dapm widget types */
enum snd_soc_dapm_type {
Expand Down Expand Up @@ -425,6 +430,7 @@ struct snd_soc_dapm_widget {
char *sname; /* stream name */
struct snd_soc_codec *codec;
struct list_head list;
struct snd_soc_dapm_context *dapm;

/* dapm control */
short reg; /* negative reg = no direct dapm */
Expand Down Expand Up @@ -461,4 +467,21 @@ struct snd_soc_dapm_widget {
struct list_head power_list;
};

/* DAPM context */
struct snd_soc_dapm_context {
u32 pop_time;
struct list_head widgets;
struct list_head paths;
enum snd_soc_bias_level bias_level;
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */

struct device *dev; /* from parent - for debug */
struct snd_soc_codec *codec; /* parent codec */
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_dapm;
#endif
};

#endif
9 changes: 2 additions & 7 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ struct soc_enum;
struct snd_soc_ac97_ops;
struct snd_soc_jack;
struct snd_soc_jack_pin;
#include <sound/soc-dapm.h>

#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio;
Expand Down Expand Up @@ -436,7 +437,6 @@ struct snd_soc_codec {
/* runtime */
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
unsigned int active;
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
unsigned int cache_only:1; /* Suppress writes to hardware */
unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
unsigned int suspended:1; /* Codec is in suspend PM state */
Expand All @@ -452,12 +452,7 @@ struct snd_soc_codec {
void *reg_cache;

/* dapm */
u32 pop_time;
struct list_head dapm_widgets;
struct list_head dapm_paths;
enum snd_soc_bias_level bias_level;
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
struct snd_soc_dapm_context dapm;

#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root;
Expand Down
11 changes: 6 additions & 5 deletions sound/soc/atmel/playpaq_wm8510.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,28 @@ static const struct snd_soc_dapm_route intercon[] = {
static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int i;

/*
* Add DAPM widgets
*/
for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]);
snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]);



/*
* Setup audio path interconnects
*/
snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));



/* always connected pins */
snd_soc_dapm_enable_pin(codec, "Int Mic");
snd_soc_dapm_enable_pin(codec, "Ext Spk");
snd_soc_dapm_sync(codec);
snd_soc_dapm_enable_pin(dapm, "Int Mic");
snd_soc_dapm_enable_pin(dapm, "Ext Spk");
snd_soc_dapm_sync(dapm);



Expand Down
17 changes: 9 additions & 8 deletions sound/soc/atmel/sam9g20_wm8731.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;

printk(KERN_DEBUG
Expand All @@ -154,25 +155,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
}

/* Add specific widgets */
snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
/* Set up specific audio path interconnects */
snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));

/* not connected */
snd_soc_dapm_nc_pin(codec, "RLINEIN");
snd_soc_dapm_nc_pin(codec, "LLINEIN");
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
snd_soc_dapm_nc_pin(dapm, "LLINEIN");

#ifdef ENABLE_MIC_INPUT
snd_soc_dapm_enable_pin(codec, "Int Mic");
snd_soc_dapm_enable_pin(dapm, "Int Mic");
#else
snd_soc_dapm_nc_pin(codec, "Int Mic");
snd_soc_dapm_nc_pin(dapm, "Int Mic");
#endif

/* always connected */
snd_soc_dapm_enable_pin(codec, "Ext Spk");
snd_soc_dapm_enable_pin(dapm, "Ext Spk");

snd_soc_dapm_sync(codec);
snd_soc_dapm_sync(dapm);

return 0;
}
Expand Down
13 changes: 7 additions & 6 deletions sound/soc/atmel/snd-soc-afeb9260.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;

/* Add afeb9260 specific widgets */
snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));

/* Set up afeb9260 specific audio path audio_map */
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));

snd_soc_dapm_enable_pin(codec, "Headphone Jack");
snd_soc_dapm_enable_pin(codec, "Line In");
snd_soc_dapm_enable_pin(codec, "Mic Jack");
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
snd_soc_dapm_enable_pin(dapm, "Line In");
snd_soc_dapm_enable_pin(dapm, "Mic Jack");

snd_soc_dapm_sync(codec);
snd_soc_dapm_sync(dapm);

return 0;
}
Expand Down
9 changes: 5 additions & 4 deletions sound/soc/codecs/88pm860x-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
break;

case SND_SOC_BIAS_STANDBY:
if (codec->bias_level == SND_SOC_BIAS_OFF) {
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Enable Audio PLL & Audio section */
data = AUDIO_PLL | AUDIO_SECTION_RESET
| AUDIO_SECTION_ON;
Expand All @@ -1185,7 +1185,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
break;
}
codec->bias_level = level;
codec->dapm.bias_level = level;
return 0;
}

Expand Down Expand Up @@ -1346,6 +1346,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
static int pm860x_probe(struct snd_soc_codec *codec)
{
struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
int i, ret;

pm860x->codec = codec;
Expand Down Expand Up @@ -1374,9 +1375,9 @@ static int pm860x_probe(struct snd_soc_codec *codec)

snd_soc_add_controls(codec, pm860x_snd_controls,
ARRAY_SIZE(pm860x_snd_controls));
snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets,
snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
ARRAY_SIZE(pm860x_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
return 0;

out_codec:
Expand Down
5 changes: 3 additions & 2 deletions sound/soc/codecs/ad1836.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ static struct snd_soc_dai_driver ad1836_dai = {
static int ad1836_probe(struct snd_soc_codec *codec)
{
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;

codec->control_data = ad1836->control_data;
Expand Down Expand Up @@ -252,9 +253,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)

snd_soc_add_controls(codec, ad1836_snd_controls,
ARRAY_SIZE(ad1836_snd_controls));
snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
ARRAY_SIZE(ad1836_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));

return ret;
}
Expand Down
5 changes: 3 additions & 2 deletions sound/soc/codecs/ad193x.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;

codec->control_data = ad193x->control_data;
Expand Down Expand Up @@ -385,9 +386,9 @@ static int ad193x_probe(struct snd_soc_codec *codec)

snd_soc_add_controls(codec, ad193x_snd_controls,
ARRAY_SIZE(ad193x_snd_controls));
snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets,
snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
ARRAY_SIZE(ad193x_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));

return ret;
}
Expand Down
9 changes: 5 additions & 4 deletions sound/soc/codecs/ak4535.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,11 @@ static const struct snd_soc_dapm_route audio_map[] = {

static int ak4535_add_widgets(struct snd_soc_codec *codec)
{
snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets,
ARRAY_SIZE(ak4535_dapm_widgets));
struct snd_soc_dapm_context *dapm = &codec->dapm;

snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
ARRAY_SIZE(ak4535_dapm_widgets));
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));

return 0;
}
Expand Down Expand Up @@ -399,7 +400,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
ak4535_write(codec, AK4535_PM1, i & (~0x80));
break;
}
codec->bias_level = level;
codec->dapm.bias_level = level;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/codecs/ak4642.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/soc-dapm.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>

Expand Down
9 changes: 5 additions & 4 deletions sound/soc/codecs/ak4671.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,11 @@ static const struct snd_soc_dapm_route intercon[] = {

static int ak4671_add_widgets(struct snd_soc_codec *codec)
{
snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
ARRAY_SIZE(ak4671_dapm_widgets));
struct snd_soc_dapm_context *dapm = &codec->dapm;

snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
ARRAY_SIZE(ak4671_dapm_widgets));
snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));

return 0;
}
Expand Down Expand Up @@ -602,7 +603,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
break;
}
codec->bias_level = level;
codec->dapm.bias_level = level;
return 0;
}

Expand Down
Loading

0 comments on commit ce6120c

Please sign in to comment.