* [PATCH 0/8] ASoC updates
@ 2008-12-10 19:58 Mark Brown
2008-12-10 20:01 ` [PATCH 1/8] ASoC: Work around warnings from some build environments Mark Brown
2008-12-10 20:34 ` [PATCH 0/8] ASoC updates Takashi Iwai
0 siblings, 2 replies; 10+ messages in thread
From: Mark Brown @ 2008-12-10 19:58 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
The following changes since commit f73f2a6a23e34de9cca9672f727694e5af00e6c7:
Takashi Iwai (1):
ALSA: ASoC - Fix symbol conflicts in omac-mcbsp.c
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-tiwai
Mark Brown (5):
ASoC: Work around warnings from some build environments
ASoC: Add codec registration API
ASoC: Convert WM8900 to do more work at I2C probe time
ASoC: Convert WM8903 driver to register at I2C probe time
ASoC: Stop WM8903 SYSCLK when suspending
Peter Ujfalusi (3):
ASoC: TWL4030: Add missing Carkit output
ASoC: TWL4030: Small cleanup
ASoC: TWL4030: Change the name for the DACs
include/sound/soc.h | 5 +
sound/soc/codecs/twl4030.c | 27 +++---
sound/soc/codecs/wm8900.c | 159 +++++++++++++++--------------
sound/soc/codecs/wm8900.h | 7 --
sound/soc/codecs/wm8903.c | 241 +++++++++++++++++++-------------------------
sound/soc/codecs/wm8903.h | 5 -
sound/soc/soc-core.c | 43 ++++++++
7 files changed, 247 insertions(+), 240 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/8] ASoC: Work around warnings from some build environments
2008-12-10 19:58 [PATCH 0/8] ASoC updates Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 2/8] ASoC: TWL4030: Add missing Carkit output Mark Brown
2008-12-10 20:34 ` [PATCH 0/8] ASoC updates Takashi Iwai
1 sibling, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
BUG() should be marked as not returning but for at least some
configurations (including some widely deployed compilers) that's either
not happening or being forgotten by the compiler. Add some extra return
statements to the affected paths.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 0b5bea3..b1f5cf7 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -392,6 +392,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
break;
default:
BUG();
+ return -EINVAL; /* Spurious warning from some compilers */
}
switch (w->shift) {
@@ -403,6 +404,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
break;
default:
BUG();
+ return -EINVAL; /* Spurious warning from some compilers */
}
if (event & SND_SOC_DAPM_PRE_PMU) {
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/8] ASoC: TWL4030: Add missing Carkit output
2008-12-10 20:01 ` [PATCH 1/8] ASoC: Work around warnings from some build environments Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 3/8] ASoC: TWL4030: Small cleanup Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Peter Ujfalusi
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
SND_SOC_DAPM_OUTPUT definition for carkitL/R was missing.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/twl4030.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 71ab534..13d5a12 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -761,6 +761,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("PREDRIVER"),
SND_SOC_DAPM_OUTPUT("HSOL"),
SND_SOC_DAPM_OUTPUT("HSOR"),
+ SND_SOC_DAPM_OUTPUT("CARKITL"),
+ SND_SOC_DAPM_OUTPUT("CARKITR"),
SND_SOC_DAPM_OUTPUT("HFL"),
SND_SOC_DAPM_OUTPUT("HFR"),
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/8] ASoC: TWL4030: Small cleanup
2008-12-10 20:01 ` [PATCH 2/8] ASoC: TWL4030: Add missing Carkit output Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 4/8] ASoC: TWL4030: Change the name for the DACs Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Peter Ujfalusi
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
The mux switch related texts fits to on line, no need to wrap
them.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/twl4030.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 13d5a12..b321928 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -192,8 +192,7 @@ 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", "Invalid", "DACR1"};
static const struct soc_enum twl4030_earpiece_enum =
SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
@@ -205,8 +204,7 @@ SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
/* PreDrive Left */
static const char *twl4030_predrivel_texts[] =
- {"Off", "DACL1", "DACL2", "Invalid",
- "DACR2"};
+ {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
static const struct soc_enum twl4030_predrivel_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
@@ -218,8 +216,7 @@ SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
/* PreDrive Right */
static const char *twl4030_predriver_texts[] =
- {"Off", "DACR1", "DACR2", "Invalid",
- "DACL2"};
+ {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
static const struct soc_enum twl4030_predriver_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/8] ASoC: TWL4030: Change the name for the DACs
2008-12-10 20:01 ` [PATCH 3/8] ASoC: TWL4030: Small cleanup Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 5/8] ASoC: Add codec registration API Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Peter Ujfalusi
From: Peter Ujfalusi <peter.ujfalusi@nokia.com>
To avoid confusion the names for the DACs changed:
DACL1 -> DAC Left1
...
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/twl4030.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index b321928..1377302 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -764,13 +764,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("HFR"),
/* DACs */
- SND_SOC_DAPM_DAC("DACR1", "Right Front Playback",
+ SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
TWL4030_REG_AVDAC_CTL, 0, 0),
- SND_SOC_DAPM_DAC("DACL1", "Left Front Playback",
+ SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
TWL4030_REG_AVDAC_CTL, 1, 0),
- SND_SOC_DAPM_DAC("DACR2", "Right Rear Playback",
+ SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
TWL4030_REG_AVDAC_CTL, 2, 0),
- SND_SOC_DAPM_DAC("DACL2", "Left Rear Playback",
+ SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
TWL4030_REG_AVDAC_CTL, 3, 0),
/* Analog PGAs */
@@ -816,10 +816,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
};
static const struct snd_soc_dapm_route intercon[] = {
- {"ARXL1_APGA", NULL, "DACL1"},
- {"ARXR1_APGA", NULL, "DACR1"},
- {"ARXL2_APGA", NULL, "DACL2"},
- {"ARXR2_APGA", NULL, "DACR2"},
+ {"ARXL1_APGA", NULL, "DAC Left1"},
+ {"ARXR1_APGA", NULL, "DAC Right1"},
+ {"ARXL2_APGA", NULL, "DAC Left2"},
+ {"ARXR2_APGA", NULL, "DAC Right2"},
/* Internal playback routings */
/* Earpiece */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/8] ASoC: Add codec registration API
2008-12-10 20:01 ` [PATCH 4/8] ASoC: TWL4030: Change the name for the DACs Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 6/8] ASoC: Convert WM8900 to do more work at I2C probe time Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
Another part of the backporting of Liam's ASoC v2 work. Using this is
more complicated than the other registration types since currently the
codec is instantiated during the probe of the ASoC device so we can't
currently readily wait for the codec to register.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
include/sound/soc.h | 5 +++++
sound/soc/soc-core.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index ce3661d..f86e455 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -161,6 +161,8 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
int snd_soc_register_platform(struct snd_soc_platform *platform);
void snd_soc_unregister_platform(struct snd_soc_platform *platform);
+int snd_soc_register_codec(struct snd_soc_codec *codec);
+void snd_soc_unregister_codec(struct snd_soc_codec *codec);
/* pcm <-> DAI connect */
void snd_soc_free_pcms(struct snd_soc_device *socdev);
@@ -247,6 +249,9 @@ struct snd_soc_codec {
char *name;
struct module *owner;
struct mutex mutex;
+ struct device *dev;
+
+ struct list_head list;
/* callbacks */
int (*set_bias_level)(struct snd_soc_codec *,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4d2db7c..b098c0b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -47,6 +47,7 @@ static DEFINE_MUTEX(client_mutex);
static LIST_HEAD(card_list);
static LIST_HEAD(dai_list);
static LIST_HEAD(platform_list);
+static LIST_HEAD(codec_list);
static int snd_soc_register_card(struct snd_soc_card *card);
static int snd_soc_unregister_card(struct snd_soc_card *card);
@@ -2224,6 +2225,48 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform)
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
+/**
+ * snd_soc_register_codec - Register a codec with the ASoC core
+ *
+ * @param codec codec to register
+ */
+int snd_soc_register_codec(struct snd_soc_codec *codec)
+{
+ if (!codec->name)
+ return -EINVAL;
+
+ /* The device should become mandatory over time */
+ if (!codec->dev)
+ printk(KERN_WARNING "No device for codec %s\n", codec->name);
+
+ INIT_LIST_HEAD(&codec->list);
+
+ mutex_lock(&client_mutex);
+ list_add(&codec->list, &codec_list);
+ snd_soc_instantiate_cards();
+ mutex_unlock(&client_mutex);
+
+ pr_debug("Registered codec '%s'\n", codec->name);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_codec);
+
+/**
+ * snd_soc_unregister_codec - Unregister a codec from the ASoC core
+ *
+ * @param codec codec to unregister
+ */
+void snd_soc_unregister_codec(struct snd_soc_codec *codec)
+{
+ mutex_lock(&client_mutex);
+ list_del(&codec->list);
+ mutex_unlock(&client_mutex);
+
+ pr_debug("Unregistered codec '%s'\n", codec->name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
+
static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/8] ASoC: Convert WM8900 to do more work at I2C probe time
2008-12-10 20:01 ` [PATCH 5/8] ASoC: Add codec registration API Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 7/8] ASoC: Convert WM8903 driver to register " Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
Redo the instantiation of the WM8900 to do most of the initialisation
work when the I2C driver probes rather than when the ASoC device is
instantiated, registering the codec with the ASoC core when done.
Also move all dynamic allocations into a single kmalloc() to simplify
error handling and rename the I2C driver to make output more sensible.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8900.c | 159 +++++++++++++++++++++++----------------------
sound/soc/codecs/wm8900.h | 7 --
2 files changed, 81 insertions(+), 85 deletions(-)
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index ebf58fb..6767de1 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -138,6 +138,10 @@
struct snd_soc_codec_device soc_codec_dev_wm8900;
struct wm8900_priv {
+ struct snd_soc_codec codec;
+
+ u16 reg_cache[WM8900_MAXREG];
+
u32 fll_in; /* FLL input frequency */
u32 fll_out; /* FLL output frequency */
};
@@ -1282,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
return 0;
}
-/*
- * initialise the WM8900 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8900_init(struct snd_soc_device *socdev)
+static struct snd_soc_codec *wm8900_codec;
+
+static int wm8900_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_codec *codec = socdev->codec;
- int ret = 0;
+ struct wm8900_priv *wm8900;
+ struct snd_soc_codec *codec;
unsigned int reg;
- struct i2c_client *i2c_client = socdev->codec->control_data;
+ int ret;
+
+ wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+ if (wm8900 == NULL)
+ return -ENOMEM;
+
+ codec = &wm8900->codec;
+ codec->private_data = wm8900;
+ codec->reg_cache = &wm8900->reg_cache[0];
+ codec->reg_cache_size = WM8900_MAXREG;
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
codec->name = "WM8900";
codec->owner = THIS_MODULE;
@@ -1299,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
codec->write = wm8900_write;
codec->dai = &wm8900_dai;
codec->num_dai = 1;
- codec->reg_cache_size = WM8900_MAXREG;
- codec->reg_cache = kmemdup(wm8900_reg_defaults,
- sizeof(wm8900_reg_defaults), GFP_KERNEL);
-
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ codec->control_data = i2c;
+ codec->set_bias_level = wm8900_set_bias_level;
+ codec->dev = &i2c->dev;
reg = wm8900_read(codec, WM8900_REG_ID);
if (reg != 0x8900) {
- dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
- reg);
- return -ENODEV;
- }
-
- codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
- if (codec->private_data == NULL) {
- ret = -ENOMEM;
- goto priv_err;
+ dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
+ ret = -ENODEV;
+ goto err;
}
/* Read back from the chip */
reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
reg = (reg >> 12) & 0xf;
- dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
+ dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
wm8900_reset(codec);
+ /* Turn the chip on */
+ wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
/* Latch the volume update bits */
wm8900_write(codec, WM8900_REG_LINVOL,
wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1351,52 +1362,43 @@ static int wm8900_init(struct snd_soc_device *socdev)
/* Set the DAC and mixer output bias */
wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
- /* Register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
- goto pcm_err;
- }
+ wm8900_dai.dev = &i2c->dev;
- /* Turn the chip on */
- codec->bias_level = SND_SOC_BIAS_OFF;
- wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ wm8900_codec = codec;
- wm8900_add_controls(codec);
- wm8900_add_widgets(codec);
+ ret = snd_soc_register_codec(codec);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+ goto err;
+ }
- ret = snd_soc_init_card(socdev);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "Failed to register card\n");
- goto card_err;
+ ret = snd_soc_register_dai(&wm8900_dai);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
+ goto err_codec;
}
- return ret;
-card_err:
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-pcm_err:
- kfree(codec->reg_cache);
-priv_err:
- kfree(codec->private_data);
return ret;
-}
-
-static struct i2c_client *wm8900_client;
-static int wm8900_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- wm8900_client = i2c;
- wm8900_dai.dev = &i2c->dev;
- return snd_soc_register_dai(&wm8900_dai);
+err_codec:
+ snd_soc_unregister_codec(codec);
+err:
+ kfree(wm8900);
+ wm8900_codec = NULL;
+ return ret;
}
static int wm8900_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_dai(&wm8900_dai);
+ snd_soc_unregister_codec(wm8900_codec);
+
+ wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
+
wm8900_dai.dev = NULL;
- wm8900_client = NULL;
+ kfree(wm8900_codec->private_data);
+ wm8900_codec = NULL;
+
return 0;
}
@@ -1408,7 +1410,7 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
static struct i2c_driver wm8900_i2c_driver = {
.driver = {
- .name = "WM8900 I2C codec",
+ .name = "WM8900",
.owner = THIS_MODULE,
},
.probe = wm8900_i2c_probe,
@@ -1422,30 +1424,36 @@ static int wm8900_probe(struct platform_device *pdev)
struct snd_soc_codec *codec;
int ret = 0;
- if (!wm8900_client) {
+ if (!wm8900_codec) {
dev_err(&pdev->dev, "I2C client not yet instantiated\n");
return -ENODEV;
}
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
+ codec = wm8900_codec;
socdev->codec = codec;
- codec->set_bias_level = wm8900_set_bias_level;
+ /* Register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register new PCMs\n");
+ goto pcm_err;
+ }
- codec->hw_write = (hw_write_t)i2c_master_send;
- codec->control_data = wm8900_client;
+ wm8900_add_controls(codec);
+ wm8900_add_widgets(codec);
+
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register card\n");
+ goto card_err;
+ }
- ret = wm8900_init(socdev);
- if (ret != 0)
- kfree(codec);
+ return ret;
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
return ret;
}
@@ -1453,14 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
static int wm8900_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->codec;
-
- if (codec->control_data)
- wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
- kfree(codec);
return 0;
}
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index 2249a44..fd15007 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,13 +52,6 @@
#define WM8900_DAC_CLKDIV_5_5 0x14
#define WM8900_DAC_CLKDIV_6 0x18
-#define WM8900_
-
-struct wm8900_setup_data {
- int i2c_bus;
- unsigned short i2c_address;
-};
-
extern struct snd_soc_dai wm8900_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8900;
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/8] ASoC: Convert WM8903 driver to register at I2C probe time
2008-12-10 20:01 ` [PATCH 6/8] ASoC: Convert WM8900 to do more work at I2C probe time Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
2008-12-10 20:01 ` [PATCH 8/8] ASoC: Stop WM8903 SYSCLK when suspending Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
The driver now registers the codec and DAI when probed as an I2C device.
Also convert the driver to use a single dynamic allocation to simplify
error handling.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 230 +++++++++++++++++++--------------------------
sound/soc/codecs/wm8903.h | 5 -
2 files changed, 97 insertions(+), 138 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index b1f5cf7..c80968f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -33,19 +33,6 @@
#include "wm8903.h"
-struct wm8903_priv {
- int sysclk;
-
- /* Reference counts */
- int charge_pump_users;
- int class_w_users;
- int playback_active;
- int capture_active;
-
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
-};
-
/* Register defaults at reset */
static u16 wm8903_reg_defaults[] = {
0x8903, /* R0 - SW Reset and ID */
@@ -223,6 +210,23 @@ static u16 wm8903_reg_defaults[] = {
0x0000, /* R172 - Analogue Output Bias 0 */
};
+struct wm8903_priv {
+ struct snd_soc_codec codec;
+ u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
+
+ int sysclk;
+
+ /* Reference counts */
+ int charge_pump_users;
+ int class_w_users;
+ int playback_active;
+ int capture_active;
+
+ struct snd_pcm_substream *master_substream;
+ struct snd_pcm_substream *slave_substream;
+};
+
+
static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg)
{
@@ -360,6 +364,8 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
static void wm8903_reset(struct snd_soc_codec *codec)
{
wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
+ memcpy(codec->reg_cache, wm8903_reg_defaults,
+ sizeof(wm8903_reg_defaults));
}
#define WM8903_OUTPUT_SHORT 0x8
@@ -1563,39 +1569,48 @@ static int wm8903_resume(struct platform_device *pdev)
return 0;
}
-/*
- * initialise the WM8903 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8903_init(struct snd_soc_device *socdev)
+static struct snd_soc_codec *wm8903_codec;
+
+static int wm8903_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_codec *codec = socdev->codec;
- struct i2c_client *i2c = codec->control_data;
- int ret = 0;
+ struct wm8903_priv *wm8903;
+ struct snd_soc_codec *codec;
+ int ret;
u16 val;
- val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
- if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
- dev_err(&i2c->dev,
- "Device with ID register %x is not a WM8903\n", val);
- return -ENODEV;
- }
+ wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
+ if (wm8903 == NULL)
+ return -ENOMEM;
+ codec = &wm8903->codec;
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ codec->dev = &i2c->dev;
codec->name = "WM8903";
codec->owner = THIS_MODULE;
codec->read = wm8903_read;
codec->write = wm8903_write;
+ codec->hw_write = (hw_write_t)i2c_master_send;
codec->bias_level = SND_SOC_BIAS_OFF;
codec->set_bias_level = wm8903_set_bias_level;
codec->dai = &wm8903_dai;
codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults);
- codec->reg_cache = kmemdup(wm8903_reg_defaults,
- sizeof(wm8903_reg_defaults),
- GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- dev_err(&i2c->dev, "Failed to allocate register cache\n");
- return -ENOMEM;
+ codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
+ codec->reg_cache = &wm8903->reg_cache[0];
+ codec->private_data = wm8903;
+
+ i2c_set_clientdata(i2c, codec);
+ codec->control_data = i2c;
+
+ val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
+ if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
+ dev_err(&i2c->dev,
+ "Device with ID register %x is not a WM8903\n", val);
+ return -ENODEV;
}
val = wm8903_read(codec, WM8903_REVISION_NUMBER);
@@ -1604,13 +1619,6 @@ static int wm8903_init(struct snd_soc_device *socdev)
wm8903_reset(codec);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(&i2c->dev, "failed to create pcms\n");
- goto pcm_err;
- }
-
/* SYSCLK is required for pretty much anything */
wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
@@ -1648,47 +1656,45 @@ static int wm8903_init(struct snd_soc_device *socdev)
val |= WM8903_DAC_MUTEMODE;
wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
- wm8903_add_controls(codec);
- wm8903_add_widgets(codec);
- ret = snd_soc_init_card(socdev);
- if (ret < 0) {
- dev_err(&i2c->dev, "wm8903: failed to register card\n");
- goto card_err;
+ wm8903_dai.dev = &i2c->dev;
+ wm8903_codec = codec;
+
+ ret = snd_soc_register_codec(codec);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+ goto err;
+ }
+
+ ret = snd_soc_register_dai(&wm8903_dai);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
+ goto err_codec;
}
return ret;
-card_err:
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-pcm_err:
- kfree(codec->reg_cache);
+err_codec:
+ snd_soc_unregister_codec(codec);
+err:
+ wm8903_codec = NULL;
+ kfree(wm8903);
return ret;
}
-static struct snd_soc_device *wm8903_socdev;
-
-static int wm8903_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8903_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_device *socdev = wm8903_socdev;
- struct snd_soc_codec *codec = socdev->codec;
- int ret;
+ struct snd_soc_codec *codec = i2c_get_clientdata(client);
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ snd_soc_unregister_dai(&wm8903_dai);
+ snd_soc_unregister_codec(codec);
- ret = wm8903_init(socdev);
- if (ret < 0)
- dev_err(&i2c->dev, "Device initialisation failed\n");
+ wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return ret;
-}
+ kfree(codec->private_data);
+
+ wm8903_codec = NULL;
+ wm8903_dai.dev = NULL;
-static int wm8903_i2c_remove(struct i2c_client *client)
-{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
return 0;
}
@@ -1712,75 +1718,37 @@ static struct i2c_driver wm8903_i2c_driver = {
static int wm8903_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct wm8903_setup_data *setup;
- struct snd_soc_codec *codec;
- struct wm8903_priv *wm8903;
- struct i2c_board_info board_info;
- struct i2c_adapter *adapter;
- struct i2c_client *i2c_client;
int ret = 0;
- setup = socdev->codec_data;
-
- if (!setup->i2c_address) {
- dev_err(&pdev->dev, "No codec address provided\n");
- return -ENODEV;
+ if (!wm8903_codec) {
+ dev_err(&pdev->dev, "I2C device not yet probed\n");
+ goto err;
}
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
+ socdev->codec = wm8903_codec;
- wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
- if (wm8903 == NULL) {
- ret = -ENOMEM;
- goto err_codec;
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to create pcms\n");
+ goto err;
}
- codec->private_data = wm8903;
- socdev->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+ wm8903_add_controls(socdev->codec);
+ wm8903_add_widgets(socdev->codec);
- wm8903_socdev = socdev;
-
- codec->hw_write = (hw_write_t)i2c_master_send;
- ret = i2c_add_driver(&wm8903_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- goto err_priv;
- } else {
- memset(&board_info, 0, sizeof(board_info));
- strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
- board_info.addr = setup->i2c_address;
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "Can't get I2C bus %d\n",
- setup->i2c_bus);
- ret = -ENODEV;
- goto err_adapter;
- }
-
- i2c_client = i2c_new_device(adapter, &board_info);
- i2c_put_adapter(adapter);
- if (i2c_client == NULL) {
- dev_err(&pdev->dev,
- "I2C driver registration failed\n");
- ret = -ENODEV;
- goto err_adapter;
- }
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "wm8903: failed to register card\n");
+ goto card_err;
}
return ret;
-err_adapter:
- i2c_del_driver(&wm8903_i2c_driver);
-err_priv:
- kfree(codec->private_data);
-err_codec:
- kfree(codec);
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+err:
return ret;
}
@@ -1795,10 +1763,6 @@ static int wm8903_remove(struct platform_device *pdev)
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
- i2c_unregister_device(socdev->codec->control_data);
- i2c_del_driver(&wm8903_i2c_driver);
- kfree(codec->private_data);
- kfree(codec);
return 0;
}
@@ -1813,13 +1777,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
static int __init wm8903_modinit(void)
{
- return snd_soc_register_dai(&wm8903_dai);
+ return i2c_add_driver(&wm8903_i2c_driver);
}
module_init(wm8903_modinit);
static void __exit wm8903_exit(void)
{
- snd_soc_unregister_dai(&wm8903_dai);
+ i2c_del_driver(&wm8903_i2c_driver);
}
module_exit(wm8903_exit);
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index cec622f..0ea27e2 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,11 +18,6 @@
extern struct snd_soc_dai wm8903_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8903;
-struct wm8903_setup_data {
- int i2c_bus;
- int i2c_address;
-};
-
#define WM8903_MCLK_DIV_2 1
#define WM8903_CLK_SYS 2
#define WM8903_BCLK 3
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/8] ASoC: Stop WM8903 SYSCLK when suspending
2008-12-10 20:01 ` [PATCH 7/8] ASoC: Convert WM8903 driver to register " Mark Brown
@ 2008-12-10 20:01 ` Mark Brown
0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2008-12-10 20:01 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Mark Brown
This will save some additional power.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
sound/soc/codecs/wm8903.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index c80968f..bde7454 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -997,6 +997,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (codec->bias_level == SND_SOC_BIAS_OFF) {
+ wm8903_write(codec, WM8903_CLOCK_RATES_2,
+ WM8903_CLK_SYS_ENA);
+
wm8903_run_sequence(codec, 0);
wm8903_sync_reg_cache(codec, codec->reg_cache);
@@ -1027,6 +1030,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF:
wm8903_run_sequence(codec, 32);
+ reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
+ reg &= ~WM8903_CLK_SYS_ENA;
+ wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
break;
}
@@ -1619,9 +1625,6 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
wm8903_reset(codec);
- /* SYSCLK is required for pretty much anything */
- wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
-
/* power on device */
wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/8] ASoC updates
2008-12-10 19:58 [PATCH 0/8] ASoC updates Mark Brown
2008-12-10 20:01 ` [PATCH 1/8] ASoC: Work around warnings from some build environments Mark Brown
@ 2008-12-10 20:34 ` Takashi Iwai
1 sibling, 0 replies; 10+ messages in thread
From: Takashi Iwai @ 2008-12-10 20:34 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel
At Wed, 10 Dec 2008 19:58:59 +0000,
Mark Brown wrote:
>
> The following changes since commit f73f2a6a23e34de9cca9672f727694e5af00e6c7:
> Takashi Iwai (1):
> ALSA: ASoC - Fix symbol conflicts in omac-mcbsp.c
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-tiwai
Pulled now. Thanks.
Takashi
> Mark Brown (5):
> ASoC: Work around warnings from some build environments
> ASoC: Add codec registration API
> ASoC: Convert WM8900 to do more work at I2C probe time
> ASoC: Convert WM8903 driver to register at I2C probe time
> ASoC: Stop WM8903 SYSCLK when suspending
>
> Peter Ujfalusi (3):
> ASoC: TWL4030: Add missing Carkit output
> ASoC: TWL4030: Small cleanup
> ASoC: TWL4030: Change the name for the DACs
>
> include/sound/soc.h | 5 +
> sound/soc/codecs/twl4030.c | 27 +++---
> sound/soc/codecs/wm8900.c | 159 +++++++++++++++--------------
> sound/soc/codecs/wm8900.h | 7 --
> sound/soc/codecs/wm8903.c | 241 +++++++++++++++++++-------------------------
> sound/soc/codecs/wm8903.h | 5 -
> sound/soc/soc-core.c | 43 ++++++++
> 7 files changed, 247 insertions(+), 240 deletions(-)
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-12-10 20:34 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-10 19:58 [PATCH 0/8] ASoC updates Mark Brown
2008-12-10 20:01 ` [PATCH 1/8] ASoC: Work around warnings from some build environments Mark Brown
2008-12-10 20:01 ` [PATCH 2/8] ASoC: TWL4030: Add missing Carkit output Mark Brown
2008-12-10 20:01 ` [PATCH 3/8] ASoC: TWL4030: Small cleanup Mark Brown
2008-12-10 20:01 ` [PATCH 4/8] ASoC: TWL4030: Change the name for the DACs Mark Brown
2008-12-10 20:01 ` [PATCH 5/8] ASoC: Add codec registration API Mark Brown
2008-12-10 20:01 ` [PATCH 6/8] ASoC: Convert WM8900 to do more work at I2C probe time Mark Brown
2008-12-10 20:01 ` [PATCH 7/8] ASoC: Convert WM8903 driver to register " Mark Brown
2008-12-10 20:01 ` [PATCH 8/8] ASoC: Stop WM8903 SYSCLK when suspending Mark Brown
2008-12-10 20:34 ` [PATCH 0/8] ASoC updates Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox