summaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/Kconfig5
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c9
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c1
-rw-r--r--sound/soc/codecs/max98088.c24
-rw-r--r--sound/soc/codecs/stac9766.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c6
-rw-r--r--sound/soc/codecs/tpa6130a2.c4
-rw-r--r--sound/soc/codecs/uda134x.c1
-rw-r--r--sound/soc/codecs/wm8350.c9
-rw-r--r--sound/soc/codecs/wm8523.c10
-rw-r--r--sound/soc/codecs/wm8580.c10
-rw-r--r--sound/soc/codecs/wm8731.c2
-rw-r--r--sound/soc/codecs/wm8741.c10
-rw-r--r--sound/soc/codecs/wm8753.c226
-rw-r--r--sound/soc/codecs/wm8776.c1
-rw-r--r--sound/soc/codecs/wm8904.c42
-rw-r--r--sound/soc/codecs/wm8940.c1
-rw-r--r--sound/soc/codecs/wm8955.c34
-rw-r--r--sound/soc/codecs/wm8960.c4
-rw-r--r--sound/soc/codecs/wm8961.c4
-rw-r--r--sound/soc/codecs/wm8962.c52
-rw-r--r--sound/soc/codecs/wm8971.c1
-rw-r--r--sound/soc/codecs/wm8994.c6
-rw-r--r--sound/soc/codecs/wm9081.c1
-rw-r--r--sound/soc/codecs/wm9090.c18
-rw-r--r--sound/soc/codecs/wm_hubs.c2
-rw-r--r--sound/soc/davinci/davinci-evm.c40
-rw-r--r--sound/soc/davinci/davinci-i2s.c15
-rw-r--r--sound/soc/davinci/davinci-mcasp.c13
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c2
-rw-r--r--sound/soc/davinci/davinci-vcif.c16
-rw-r--r--sound/soc/ep93xx/simone.c18
-rw-r--r--sound/soc/fsl/efika-audio-fabric.c1
-rw-r--r--sound/soc/fsl/mpc5200_dma.c1
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c1
-rw-r--r--sound/soc/fsl/p1022_ds.c1
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c1
-rw-r--r--sound/soc/imx/eukrea-tlv320.c8
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c221
-rw-r--r--sound/soc/imx/imx-ssi.c57
-rw-r--r--sound/soc/imx/imx-ssi.h4
-rw-r--r--sound/soc/imx/phycore-ac97.c33
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c17
-rw-r--r--sound/soc/nuc900/nuc900-audio.h2
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c11
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/omap-mcbsp.c8
-rw-r--r--sound/soc/omap/omap3pandora.c1
-rw-r--r--sound/soc/omap/osk5912.c11
-rw-r--r--sound/soc/pxa/Kconfig1
-rw-r--r--sound/soc/pxa/corgi.c5
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/poodle.c5
-rw-r--r--sound/soc/pxa/spitz.c5
-rw-r--r--sound/soc/pxa/tosa.c5
-rw-r--r--sound/soc/s3c24xx/Kconfig1
-rw-r--r--sound/soc/s3c24xx/rx1950_uda1380.c20
-rw-r--r--sound/soc/s3c24xx/smdk_spdif.c4
-rw-r--r--sound/soc/s6000/s6000-i2s.c2
-rw-r--r--sound/soc/s6000/s6000-pcm.c2
-rw-r--r--sound/soc/s6000/s6105-ipcam.c2
-rw-r--r--sound/soc/sh/fsi.c25
-rw-r--r--sound/soc/sh/ssi.c2
-rw-r--r--sound/soc/soc-core.c23
-rw-r--r--sound/soc/soc-dapm.c7
66 files changed, 580 insertions, 503 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index e720d5e6f04..bee3c94f58b 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC
config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
- depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
+ depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
+ AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731
help
@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
config SND_AT32_SOC_PLAYPAQ
tristate "SoC Audio support for PlayPaq with WM8510"
- depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
+ depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC
select SND_SOC_WM8510
help
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 293569dfd0e..e521ada8054 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -222,9 +222,9 @@ static int __init at91sam9g20ek_init(void)
}
pllb = clk_get(NULL, "pllb");
- if (IS_ERR(mclk)) {
+ if (IS_ERR(pllb)) {
printk(KERN_ERR "ASoC: Failed to get PLLB\n");
- ret = PTR_ERR(mclk);
+ ret = PTR_ERR(pllb);
goto err_mclk;
}
ret = clk_set_parent(mclk, pllb);
@@ -240,6 +240,7 @@ static int __init at91sam9g20ek_init(void)
if (!at91sam9g20ek_snd_device) {
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
ret = -ENOMEM;
+ goto err_mclk;
}
platform_set_drvdata(at91sam9g20ek_snd_device,
@@ -248,11 +249,13 @@ static int __init at91sam9g20ek_init(void)
ret = platform_device_add(at91sam9g20ek_snd_device);
if (ret) {
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- platform_device_put(at91sam9g20ek_snd_device);
+ goto err_device_add;
}
return ret;
+err_device_add:
+ platform_device_put(at91sam9g20ek_snd_device);
err_mclk:
clk_put(mclk);
mclk = NULL;
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index e3d283561c1..86e0f8586dc 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -167,7 +167,6 @@ static int __init afeb9260_soc_init(void)
return 0;
err1:
- platform_device_del(afeb9260_snd_device);
platform_device_put(afeb9260_snd_device);
return err;
}
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bc22ee93a75..6447dbb2f12 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -28,6 +28,11 @@
#include <sound/max98088.h>
#include "max98088.h"
+enum max98088_type {
+ MAX98088,
+ MAX98089,
+};
+
struct max98088_cdata {
unsigned int rate;
unsigned int fmt;
@@ -35,7 +40,7 @@ struct max98088_cdata {
};
struct max98088_priv {
- u8 reg_cache[M98088_REG_CNT];
+ enum max98088_type devtype;
void *control_data;
struct max98088_pdata *pdata;
unsigned int sysclk;
@@ -1582,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
static void max98088_sync_cache(struct snd_soc_codec *codec)
{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -1593,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec)
/* write back cached values if they're writeable and
* different from the hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (!max98088_access[i].writable)
continue;
- if (max98088->reg_cache[i] == max98088_reg[i])
+ if (reg_cache[i] == max98088_reg[i])
continue;
- snd_soc_write(codec, i, max98088->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -1945,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
int ret = 0;
codec->cache_sync = 1;
- memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg));
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
if (ret != 0) {
@@ -2013,7 +2017,10 @@ err_access:
static int max98088_remove(struct snd_soc_codec *codec)
{
+ struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+
max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ kfree(max98088->eq_texts);
return 0;
}
@@ -2040,6 +2047,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
if (max98088 == NULL)
return -ENOMEM;
+ max98088->devtype = id->driver_data;
+
i2c_set_clientdata(i2c, max98088);
max98088->control_data = i2c;
max98088->pdata = i2c->dev.platform_data;
@@ -2059,7 +2068,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client)
}
static const struct i2c_device_id max98088_i2c_id[] = {
- { "max98088", 0 },
+ { "max98088", MAX98088 },
+ { "max98089", MAX98089 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 00d67cc8e20..061f9e5a497 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -383,6 +383,7 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
.reg_cache_size = sizeof(stac9766_reg),
.reg_word_size = sizeof(u16),
.reg_cache_step = 2,
+ .reg_cache_default = stac9766_reg,
};
static __devinit int stac9766_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index fc687790188..77b8f9ae29b 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1176,7 +1176,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_gpio);
int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
{
u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
- u8 val, bit = gpio ? 2: 1;
+ u8 val = 0, bit = gpio ? 2 : 1;
aic3x_read(codec, reg, &val);
return (val >> bit) & 1;
@@ -1204,7 +1204,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
int aic3x_headset_detected(struct snd_soc_codec *codec)
{
- u8 val;
+ u8 val = 0;
aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
return (val >> 4) & 1;
}
@@ -1212,7 +1212,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
int aic3x_button_pressed(struct snd_soc_codec *codec)
{
- u8 val;
+ u8 val = 0;
aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
return (val >> 5) & 1;
}
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index ee4fb201de6..d2c24309567 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -78,8 +78,10 @@ static int tpa6130a2_i2c_write(int reg, u8 value)
if (data->power_state) {
val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
- if (val < 0)
+ if (val < 0) {
dev_err(&tpa6130a2_client->dev, "Write failed\n");
+ return val;
+ }
}
/* Either powered on or off, we save the context */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 7540a509a6f..464f0cfa4c7 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
.resume = uda134x_soc_resume,
.reg_cache_size = sizeof(uda134x_reg),
.reg_word_size = sizeof(u8),
+ .reg_cache_default = uda134x_reg,
.reg_cache_step = 1,
.read = uda134x_read_reg_cache,
.write = uda134x_write,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index f4f1fba38eb..7611add7f8c 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
}
/* MCLK direction */
- if (dir == WM8350_MCLK_DIR_OUT)
+ if (dir == SND_SOC_CLOCK_OUT)
wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
WM8350_MCLK_DIR);
else
@@ -1586,6 +1586,13 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
+ /* Make sure AIF tristating is disabled by default */
+ wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
+
+ /* Make sure we've got a sane companding setup too */
+ wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
+ WM8350_DAC_COMP | WM8350_LOOPBACK);
+
/* Make sure jack detect is disabled to start off with */
wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
WM8350_JDL_ENA | WM8350_JDR_ENA);
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 712ef7c76f9..deca79ea2b4 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -41,7 +41,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
/* codec private data */
struct wm8523_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8523_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
unsigned int sysclk;
unsigned int rate_constraint_list[WM8523_NUM_RATES];
@@ -146,7 +145,6 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
return -EINVAL;
}
- return 0;
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&wm8523->rate_constraint);
@@ -315,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
switch (level) {
@@ -345,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
/* Sync back default/cached values */
for (i = WM8523_AIF_CTRL1;
i < WM8523_MAX_REGISTER; i++)
- snd_soc_write(codec, i, wm8523->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
msleep(100);
@@ -415,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
codec->hw_write = (hw_write_t)i2c_master_send;
@@ -471,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
- wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
+ reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
+ reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index a2e0ed59b37..8725d4e7543 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -161,7 +161,7 @@
static const u16 wm8580_reg[] = {
0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+ 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
paifa |= 0x8;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
- paifa |= 0x10;
- paifb |= WM8580_AIF_LENGTH_24;
+ paifa |= 0x0;
+ paifb |= WM8580_AIF_LENGTH_32;
break;
default:
return -EINVAL;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 631385802eb..e725c09a3e7 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -526,7 +526,7 @@ static int wm8731_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
/* Disable bypass path by default */
- snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
+ snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
snd_soc_add_controls(codec, wm8731_snd_controls,
ARRAY_SIZE(wm8731_snd_controls));
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 90e31e9aa6f..aea60ef8aba 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -41,7 +41,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
/* codec private data */
struct wm8741_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8741_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
unsigned int sysclk;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec)
static int wm8741_probe(struct snd_soc_codec *codec)
{
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret = 0;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU */
- wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
- wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
+ reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
+ reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
+ reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
snd_soc_add_controls(codec, wm8741_snd_controls,
ARRAY_SIZE(wm8741_snd_controls));
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8f679a13f2b..87caae59e93 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
* are using 2 wire for device control, so we cache them instead.
*/
static const u16 wm8753_reg[] = {
- 0x0008, 0x0000, 0x000a, 0x000a,
- 0x0033, 0x0000, 0x0007, 0x00ff,
- 0x00ff, 0x000f, 0x000f, 0x007b,
- 0x0000, 0x0032, 0x0000, 0x00c3,
- 0x00c3, 0x00c0, 0x0000, 0x0000,
+ 0x0000, 0x0008, 0x0000, 0x000a,
+ 0x000a, 0x0033, 0x0000, 0x0007,
+ 0x00ff, 0x00ff, 0x000f, 0x000f,
+ 0x007b, 0x0000, 0x0032, 0x0000,
+ 0x00c3, 0x00c3, 0x00c0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0055,
- 0x0005, 0x0050, 0x0055, 0x0050,
- 0x0055, 0x0050, 0x0055, 0x0079,
- 0x0079, 0x0079, 0x0079, 0x0079,
0x0000, 0x0000, 0x0000, 0x0000,
- 0x0097, 0x0097, 0x0000, 0x0004,
- 0x0000, 0x0083, 0x0024, 0x01ba,
- 0x0000, 0x0083, 0x0024, 0x01ba,
- 0x0000, 0x0000, 0x0000
+ 0x0055, 0x0005, 0x0050, 0x0055,
+ 0x0050, 0x0055, 0x0050, 0x0055,
+ 0x0079, 0x0079, 0x0079, 0x0079,
+ 0x0079, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0097, 0x0097, 0x0000,
+ 0x0004, 0x0000, 0x0083, 0x0024,
+ 0x01ba, 0x0000, 0x0083, 0x0024,
+ 0x01ba, 0x0000, 0x0000, 0x0000
};
/* codec private data */
@@ -88,57 +88,10 @@ struct wm8753_priv {
enum snd_soc_control_type control_type;
unsigned int sysclk;
unsigned int pcmclk;
- u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
int dai_func;
};
-/*
- * read wm8753 register cache
- */
-static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
- return -1;
- return cache[reg - 1];
-}
-
-/*
- * write wm8753 register cache
- */
-static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- u16 *cache = codec->reg_cache;
- if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
- return;
- cache[reg - 1] = value;
-}
-
-/*
- * write to the WM8753 register space
- */
-static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u8 data[2];
-
- /* data is
- * D15..D9 WM8753 register offset
- * D8...D0 register data
- */
- data[0] = (reg << 1) | ((value >> 8) & 0x0001);
- data[1] = value & 0x00ff;
-
- wm8753_write_reg_cache(codec, reg, value);
- if (codec->hw_write(codec->control_data, data, 2) == 2)
- return 0;
- else
- return -EIO;
-}
-
-#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
+#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
/*
* WM8753 Controls
@@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
return 0;
@@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+ int mode = snd_soc_read(codec, WM8753_IOCTL);
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
if (pll_id == WM8753_PLL1) {
offset = 0;
enable = 0x10;
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
} else {
offset = 4;
enable = 0x8;
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
}
if (!freq_in || !freq_out) {
/* disable PLL */
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
- wm8753_write(codec, WM8753_CLOCK, reg);
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
+ snd_soc_write(codec, WM8753_CLOCK, reg);
return 0;
} else {
u16 value = 0;
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
/* set up N and K PLL divisor ratios */
/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
- wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
/* bits 8:0 = PLL_K[17:9] */
value = (pll_div.k & 0x03fe00) >> 9;
- wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
/* bits 8:0 = PLL_K[8:0] */
value = pll_div.k & 0x0001ff;
- wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
+ snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
/* set PLL as input and enable */
- wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+ snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
(pll_div.div2 << 3));
- wm8753_write(codec, WM8753_CLOCK, reg | enable);
+ snd_soc_write(codec, WM8753_CLOCK, reg | enable);
}
return 0;
}
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_PCM, voice);
return 0;
}
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
+ u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
/* bit size */
switch (params_format(params)) {
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
/* sample rate */
if (params_rate(params) * 384 == wm8753->pcmclk)
srate |= 0x80;
- wm8753_write(codec, WM8753_SRATE1, srate);
+ snd_soc_write(codec, WM8753_SRATE1, srate);
- wm8753_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_PCM, voice);
return 0;
}
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
u16 voice, ioctl;
- voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
+ voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_PCM, voice);
- wm8753_write(codec, WM8753_IOCTL, ioctl);
+ snd_soc_write(codec, WM8753_PCM, voice);
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
return 0;
}
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
switch (div_id) {
case WM8753_PCMDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
- wm8753_write(codec, WM8753_CLOCK, reg | div);
+ reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
+ snd_soc_write(codec, WM8753_CLOCK, reg | div);
break;
case WM8753_BCLKDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
- wm8753_write(codec, WM8753_SRATE2, reg | div);
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
break;
case WM8753_VXCLKDIV:
- reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
- wm8753_write(codec, WM8753_SRATE2, reg | div);
+ reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
+ snd_soc_write(codec, WM8753_SRATE2, reg | div);
break;
default:
return -EINVAL;
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
return 0;
}
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
u16 ioctl, hifi;
- hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
- ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
+ hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
+ ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
- wm8753_write(codec, WM8753_IOCTL, ioctl);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_IOCTL, ioctl);
return 0;
}
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
- u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
+ u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
+ u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
int coeff;
/* is digital filter coefficient valid ? */
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
return coeff;
}
- wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+ snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
coeff_div[coeff].usb);
/* bit size */
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
break;
}
- wm8753_write(codec, WM8753_HIFI, hifi);
+ snd_soc_write(codec, WM8753_HIFI, hifi);
return 0;
}
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as pcmclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock);
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as pcmclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock);
if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
u16 clock;
/* set clk source as mclk */
- clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
- wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
+ clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+ snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
return -EINVAL;
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int wm8753_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+ u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
* make sure we check if they are not both active when we mute */
if (mute && wm8753->dai_func == 1) {
if (!codec->active)
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
} else {
if (mute)
- wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
else
- wm8753_write(codec, WM8753_DAC, mute_reg);
+ snd_soc_write(codec, WM8753_DAC, mute_reg);
}
return 0;
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
static int wm8753_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
+ u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
switch (level) {
case SND_SOC_BIAS_ON:
/* set vmid to 50k and unmute dac */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
break;
case SND_SOC_BIAS_PREPARE:
/* set vmid to 5k for quick power up */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
break;
case SND_SOC_BIAS_STANDBY:
/* mute dac and set vmid to 500k, enable VREF */
- wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+ snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
break;
case SND_SOC_BIAS_OFF:
- wm8753_write(codec, WM8753_PWR1, 0x0001);
+ snd_soc_write(codec, WM8753_PWR1, 0x0001);
break;
}
codec->bias_level = level;
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
else
dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
}
- wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
+ snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
}
static void wm8753_work(struct work_struct *work)
@@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int wm8753_resume(struct snd_soc_codec *codec)
{
+ u16 *reg_cache = codec->reg_cache;
int i;
- u8 data[2];
- u16 *cache = codec->reg_cache;
/* Sync reg_cache with the hardware */
- for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
- if (i + 1 == WM8753_RESET)
+ for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
+ if (i == WM8753_RESET)
continue;
/* No point in writing hardware default values back */
- if (cache[i] == wm8753_reg[i])
+ if (reg_cache[i] == wm8753_reg[i])
continue;
- data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
- data[1] = cache[i] & 0x00ff;
- codec->hw_write(codec->control_data, data, 2);
+ snd_soc_write(codec, i, reg_cache[i]);
}
wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork)
static int wm8753_probe(struct snd_soc_codec *codec)
{
struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, reg;
+ int ret;
INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
@@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
msecs_to_jiffies(caps_charge));
/* set the update bits */
- reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
- wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
- wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LADC);
- wm8753_write(codec, WM8753_LADC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RADC);
- wm8753_write(codec, WM8753_RADC, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
- wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
- wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
- wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
- wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
- wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
- reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
- wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
+ snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
snd_soc_add_controls(codec, wm8753_snd_controls,
ARRAY_SIZE(wm8753_snd_controls));
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 04182c464e3..0132a27140a 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -34,7 +34,6 @@
/* codec private data */
struct wm8776_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8776_CACHEREGNUM];
int sysclk[2];
};
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 33be84e506e..1ec12eff062 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
/* codec private data */
struct wm8904_priv {
- u16 reg_cache[WM8904_MAX_REGISTER + 1];
-
enum wm8904_type devtype;
void *control_data;
@@ -818,7 +816,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- return wm8904->deemph;
+ ucontrol->value.enumerated.item[0] = wm8904->deemph;
+ return 0;
}
static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -2093,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
static void wm8904_sync_cache(struct snd_soc_codec *codec)
{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -2104,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
/* Sync back cached values if they're different from the
* hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (!wm8904_access[i].writable)
continue;
- if (wm8904->reg_cache[i] == wm8904_reg[i])
+ if (reg_cache[i] == wm8904_reg[i])
continue;
- snd_soc_write(codec, i, wm8904->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -2370,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
{
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
codec->cache_sync = 1;
@@ -2436,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
- wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
- wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
+ reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
+ reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
+ reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
WM8904_HPOUTLZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
WM8904_HPOUTRZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
WM8904_LINEOUTLZC;
- wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
+ reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
WM8904_LINEOUTRZC;
- wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
+ reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
/* Apply configuration from the platform data. */
if (wm8904->pdata) {
@@ -2456,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
if (!pdata->gpio_cfg[i])
continue;
- wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
+ reg_cache[WM8904_GPIO_CONTROL_1 + i]
= pdata->gpio_cfg[i] & 0xffff;
}
/* Zero is the default value for these anyway */
for (i = 0; i < WM8904_MIC_REGS; i++)
- wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
+ reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
= pdata->mic_cfg[i];
}
/* Set Class W by default - this will be managed by the Class
* G widget at runtime where bypass paths are available.
*/
- wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
+ reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
/* Use normal bias source */
- wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
+ reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -2498,6 +2498,8 @@ static int wm8904_remove(struct snd_soc_codec *codec)
wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
+ kfree(wm8904->retune_mobile_texts);
+ kfree(wm8904->drc_texts);
return 0;
}
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 2cb16f895c4..23086e2c976 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -768,6 +768,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8940);
wm8940->control_data = i2c;
+ wm8940->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8940, &wm8940_dai, 1);
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index f89ad6c9a80..2ac35b0be86 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
struct wm8955_priv {
enum snd_soc_control_type control_type;
- u16 reg_cache[WM8955_MAX_REGISTER + 1];
-
unsigned int mclk_rate;
int deemph;
@@ -380,7 +378,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- return wm8955->deemph;
+ ucontrol->value.enumerated.item[0] = wm8955->deemph;
+ return 0;
}
static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
@@ -767,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
switch (level) {
@@ -799,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
/* Sync back cached values if they're
* different from the hardware default.
*/
- for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
if (i == WM8955_RESET)
continue;
- if (wm8955->reg_cache[i] == wm8955_reg[i])
+ if (reg_cache[i] == wm8955_reg[i])
continue;
- snd_soc_write(codec, i, wm8955->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
/* Enable VREF and VMID */
@@ -901,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec)
{
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
+ u16 *reg_cache = codec->reg_cache;
int ret, i;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
@@ -933,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec)
}
/* Change some default settings - latch VU and enable ZC */
- wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
- wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
- wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
- wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
- wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
- wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
- wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
+ reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
+ reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
+ reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
+ reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
+ reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
+ reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
+ reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
/* Also enable adaptive bass boost by default */
- wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
+ reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
/* Set platform data values */
if (pdata) {
if (pdata->out2_speaker)
- wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
+ reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|= WM8955_ROUT2INV;
if (pdata->monoin_diff)
- wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
+ reg_cache[WM8955_MONO_OUT_MIX_1]
|= WM8955_DMEN;
}
@@ -1002,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8955);
+ wm8955->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8955, &wm8955_dai, 1);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8d5efb333c3..ff6ff2f529d 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- return wm8960->deemph;
+ ucontrol->value.enumerated.item[0] = wm8960->deemph;
+ return 0;
}
static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
@@ -1012,6 +1013,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8960);
+ wm8960->control_type = SND_SOC_I2C;
wm8960->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 4f326f60410..8340485c985 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -711,7 +711,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
if (fs <= 24000)
reg |= WM8961_DACSLOPE;
else
- reg &= WM8961_DACSLOPE;
+ reg &= ~WM8961_DACSLOPE;
snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
return 0;
@@ -736,7 +736,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
freq /= 2;
} else {
dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
- reg &= WM8961_MCLKDIV;
+ reg &= ~WM8961_MCLKDIV;
}
snd_soc_write(codec, WM8961_CLOCKING1, reg);
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 894d0cd3aa9..7c421cc837b 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
struct wm8962_priv {
struct snd_soc_codec *codec;
- u16 reg_cache[WM8962_MAX_REGISTER + 1];
-
int sysclk;
int sysclk_rate;
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int ret;
/* Apply the update (if any) */
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int ret;
/* Apply the update (if any) */
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = wm8962->reg_cache;
+ u16 *reg_cache = codec->reg_cache;
int reg;
switch (w->shift) {
@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
static void wm8962_sync_cache(struct snd_soc_codec *codec)
{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int i;
if (!codec->cache_sync)
@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec)
/* Sync back cached values if they're different from the
* hardware default.
*/
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (i == WM8962_SOFTWARE_RESET)
continue;
- if (wm8962->reg_cache[i] == wm8962_reg[i])
+ if (reg_cache[i] == wm8962_reg[i])
continue;
- snd_soc_write(codec, i, wm8962->reg_cache[i]);
+ snd_soc_write(codec, i, reg_cache[i]);
}
codec->cache_sync = 0;
@@ -3339,7 +3334,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
int mask;
int active;
- mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+ mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
active &= ~mask;
@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect);
#ifdef CONFIG_PM
static int wm8962_resume(struct snd_soc_codec *codec)
{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
u16 *reg_cache = codec->reg_cache;
int i;
/* Restore the registers */
- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
switch (i) {
case WM8962_SOFTWARE_RESET:
continue;
@@ -3500,8 +3494,11 @@ static ssize_t wm8962_beep_set(struct device *dev,
{
struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
long int time;
+ int ret;
- strict_strtol(buf, 10, &time);
+ ret = strict_strtol(buf, 10, &time);
+ if (ret != 0)
+ return ret;
input_event(wm8962->beep, EV_SND, SND_TONE, time);
@@ -3702,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
dev);
+ u16 *reg_cache = codec->reg_cache;
int i, trigger, irq_pol;
wm8962->codec = codec;
@@ -3801,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
/* Put the speakers into mono mode? */
if (pdata->spk_mono)
- wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2]
+ reg_cache[WM8962_CLASS_D_CONTROL_2]
|= WM8962_SPK_MONO;
/* Micbias setup, detection enable and detection
@@ -3816,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec)
}
/* Latch volume update bits */
- wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
- wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
- wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
- wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
- wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
- wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
- wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
- wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
- wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
- wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
+ reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
+ reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
+ reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
+ reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
+ reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
+ reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
+ reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
+ reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
+ reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
+ reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
wm8962_add_widgets(codec);
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 63f6dbf5d07..9f18db6e167 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
if (wm8971 == NULL)
return -ENOMEM;
+ wm8971->control_type = SND_SOC_I2C;
i2c_set_clientdata(i2c, wm8971);
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 0db59c3aa5d..4d3e6f1ac58 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm8994);
+ codec->reg_cache = &wm8994->reg_cache;
+
wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec;
@@ -4059,6 +4061,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
+ kfree(wm8994->retune_mobile_texts);
+ kfree(wm8994->drc_texts);
kfree(wm8994);
return 0;
@@ -4071,6 +4075,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.resume = wm8994_resume,
.read = wm8994_read,
.write = wm8994_write,
+ .readable_register = wm8994_readable,
+ .volatile_register = wm8994_volatile,
.set_bias_level = wm8994_set_bias_level,
};
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index ecc7c37180c..a486670966b 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1335,6 +1335,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm9081);
+ wm9081->control_type = SND_SOC_I2C;
wm9081->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 99c046ba46b..6e5f64f627c 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -141,7 +141,6 @@ static const u16 wm9090_reg_defaults[] = {
/* This struct is used to save the context */
struct wm9090_priv {
struct mutex mutex;
- u16 reg_cache[WM9090_MAX_REGISTER + 1];
struct wm9090_platform_data pdata;
void *control_data;
};
@@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
static int wm9090_probe(struct snd_soc_codec *codec)
{
struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+ u16 *reg_cache = codec->reg_cache;
int ret;
codec->control_data = wm9090->control_data;
@@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec)
/* Configure some defaults; they will be written out when we
* bring the bias up.
*/
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
+ reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
| WM9090_IN1A_ZC;
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
+ reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
| WM9090_IN1B_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
+ reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
| WM9090_IN2A_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
+ reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
| WM9090_IN2B_ZC;
- wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
+ reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
- wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
+ reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
- wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
+ reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
- wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
+ reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 19ca782ac97..0e24092722c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch",
SOC_DOUBLE_R("Speaker ZC Switch",
WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
spkboost_tlv),
SOC_ENUM("Speaker Reference", speaker_ref),
SOC_ENUM("Speaker Mode", speaker_mode),
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 2b07b17a6b2..bc9e6b0b3f6 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
}
/* davinci-evm digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link evm_dai = {
+static struct snd_soc_dai_link dm6446_evm_dai = {
.name = "TLV320AIC3X",
.stream_name = "AIC3X",
- .cpu_dai_name = "davinci-mcasp.0",
+ .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "tlv320aic3x-hifi",
- .codec_name = "tlv320aic3x-codec.0-001a",
+ .codec_name = "tlv320aic3x-codec.1-001b",
+ .platform_name = "davinci-pcm-audio",
+ .init = evm_aic3x_init,
+ .ops = &evm_ops,
+};
+
+static struct snd_soc_dai_link dm355_evm_dai = {
+ .name = "TLV320AIC3X",
+ .stream_name = "AIC3X",
+ .cpu_dai_name = "davinci-mcbsp.1",
+ .codec_dai_name = "tlv320aic3x-hifi",
+ .codec_name = "tlv320aic3x-codec.1-001b",
.platform_name = "davinci-pcm-audio",
.init = evm_aic3x_init,
.ops = &evm_ops,
@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = {
#ifdef CONFIG_SND_DM365_AIC3X_CODEC
.name = "TLV320AIC3X",
.stream_name = "AIC3X",
- .cpu_dai_name = "davinci-i2s",
+ .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "tlv320aic3x-hifi",
.init = evm_aic3x_init,
- .codec_name = "tlv320aic3x-codec.0-001a",
+ .codec_name = "tlv320aic3x-codec.1-0018",
.ops = &evm_ops,
#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
.name = "Voice Codec - CQ93VC",
@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
.ops = &evm_ops,
};
-/* davinci dm6446, dm355 evm audio machine driver */
-static struct snd_soc_card snd_soc_card_evm = {
- .name = "DaVinci EVM",
- .dai_link = &evm_dai,
+/* davinci dm6446 evm audio machine driver */
+static struct snd_soc_card dm6446_snd_soc_card_evm = {
+ .name = "DaVinci DM6446 EVM",
+ .dai_link = &dm6446_evm_dai,
+ .num_links = 1,
+};
+
+/* davinci dm355 evm audio machine driver */
+static struct snd_soc_card dm355_snd_soc_card_evm = {
+ .name = "DaVinci DM355 EVM",
+ .dai_link = &dm355_evm_dai,
.num_links = 1,
};
@@ -261,10 +279,10 @@ static int __init evm_init(void)
int ret;
if (machine_is_davinci_evm()) {
- evm_snd_dev_data = &snd_soc_card_evm;
+ evm_snd_dev_data = &dm6446_snd_soc_card_evm;
index = 0;
} else if (machine_is_davinci_dm355_evm()) {
- evm_snd_dev_data = &snd_soc_card_evm;
+ evm_snd_dev_data = &dm355_snd_soc_card_evm;
index = 1;
} else if (machine_is_davinci_dm365_evm()) {
evm_snd_dev_data = &dm365_snd_soc_card_evm;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index d46b545d41f..9e0e565e6ed 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
snd_pcm_format_t fmt;
unsigned element_cnt = 1;
- dai->capture_dma_data = dev->dma_params;
- dai->playback_dma_data = dev->dma_params;
-
/* general line settings */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
return ret;
}
+static int davinci_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+ return 0;
+}
+
static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+ .startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger,
@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = {
.probe = davinci_i2s_probe,
.remove = davinci_i2s_remove,
.driver = {
- .name = "davinci-i2s",
+ .name = "davinci-mcbsp",
.owner = THIS_MODULE,
},
};
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 86918ee1241..fb55d2c5d70 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
int word_length;
u8 fifo_level;
- cpu_dai->capture_dma_data = dev->dma_params;
- cpu_dai->playback_dma_data = dev->dma_params;
-
davinci_hw_common_param(dev, substream->stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = dev->txnumevt;
@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
return ret;
}
+static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+ return 0;
+}
+
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+ .startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt,
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 009b6521a1b..6c6666a1f94 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = {
static struct snd_soc_dai_link sffsdr_dai = {
.name = "PCM3008", /* Codec name */
.stream_name = "PCM3008 HiFi",
- .cpu_dai_name = "davinci-asp.0",
+ .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "pcm3008-hifi",
.codec_name = "pcm3008-codec",
.platform_name = "davinci-pcm-audio",
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index ea232f6a2c2..9d2afccc3a2 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
&davinci_vcif_dev->dma_params[substream->stream];
u32 w;
- dai->capture_dma_data = davinci_vcif_dev->dma_params;
- dai->playback_dma_data = davinci_vcif_dev->dma_params;
-
/* Restart the codec before setup */
davinci_vcif_stop(substream);
davinci_vcif_start(substream);
@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
return ret;
}
+static int davinci_vcif_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+ return 0;
+}
+
#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
+ .startup = davinci_vcif_startup,
.trigger = davinci_vcif_trigger,
.hw_params = davinci_vcif_hw_params,
};
@@ -240,7 +247,10 @@ fail:
static int davinci_vcif_remove(struct platform_device *pdev)
{
+ struct davinci_vcif_dev *davinci_vcif_dev = dev_get_drvdata(&pdev->dev);
+
snd_soc_unregister_dai(&pdev->dev);
+ kfree(davinci_vcif_dev);
return 0;
}
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c
index 4b0d1991372..286817946c5 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/ep93xx/simone.c
@@ -54,24 +54,26 @@ static int __init simone_init(void)
ret = platform_device_add(simone_snd_ac97_device);
if (ret)
- goto fail;
+ goto fail1;
simone_snd_device = platform_device_alloc("soc-audio", -1);
if (!simone_snd_device) {
ret = -ENOMEM;
- goto fail;
+ goto fail2;
}
platform_set_drvdata(simone_snd_device, &snd_soc_simone);
ret = platform_device_add(simone_snd_device);
- if (ret) {
- platform_device_put(simone_snd_device);
- goto fail;
- }
+ if (ret)
+ goto fail3;
- return ret;
+ return 0;
-fail:
+fail3:
+ platform_device_put(simone_snd_device);
+fail2:
+ platform_device_del(simone_snd_ac97_device);
+fail1:
platform_device_put(simone_snd_ac97_device);
return ret;
}
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
index 53251e6b5bd..108b5d8bd0e 100644
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ b/sound/soc/fsl/efika-audio-fabric.c
@@ -76,6 +76,7 @@ static __init int efika_fabric_init(void)
rc = platform_device_add(pdev);
if (rc) {
pr_err("efika_fabric_init: platform_device_add() failed\n");
+ platform_device_put(pdev);
return -ENODEV;
}
return 0;
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index dce6b551cd7..f92dca07cd3 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/slab.h>
-#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <sound/soc.h>
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 74ffed41340..9018fa5bf0d 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op,
rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
if (rc != 0) {
pr_err("Failed to register DAI\n");
- return 0;
+ return rc;
}
psc_dma = dev_get_drvdata(&op->dev);
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 0d7dcf1e486..7d7847a1e66 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -498,6 +498,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "platform device add failed\n");
goto error;
}
+ dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 63b9eaa1ebc..026b756961e 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -498,6 +498,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "platform device add failed\n");
goto error;
}
+ dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 25f27ec1dd6..ba4d85e317e 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -76,6 +76,7 @@ static __init int pcm030_fabric_init(void)
rc = platform_device_add(pdev);
if (rc) {
pr_err("pcm030_fabric_init: platform_device_add() failed\n");
+ platform_device_put(pdev);
return -ENODEV;
}
return 0;
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index b59675257ce..dd4fffdbd17 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
static struct snd_soc_dai_link eukrea_tlv320_dai = {
.name = "tlv320aic23",
.stream_name = "TLV320AIC23",
- .codec_dai = "tlv320aic23-hifi",
+ .codec_dai_name = "tlv320aic23-hifi",
.platform_name = "imx-pcm-audio.0",
.codec_name = "tlv320aic23-codec.0-001a",
- .cpu_dai = "imx-ssi.0",
+ .cpu_dai_name = "imx-ssi.0",
.ops = &eukrea_tlv320_snd_ops,
};
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index fd493ee1428..671ef8dd524 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/dmaengine.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -27,165 +28,146 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <mach/dma-mx1-mx2.h>
+#include <mach/dma.h>
#include "imx-ssi.h"
struct imx_pcm_runtime_data {
- int sg_count;
- struct scatterlist *sg_list;
- int period;
+ int period_bytes;
int periods;
- unsigned long dma_addr;
int dma;
- struct snd_pcm_substream *substream;
unsigned long offset;
unsigned long size;
- unsigned long period_cnt;
void *buf;
int period_time;
+ struct dma_async_tx_descriptor *desc;
+ struct dma_chan *dma_chan;
+ struct imx_dma_data dma_data;
};
-/* Called by the DMA framework when a period has elapsed */
-static void imx_ssi_dma_progression(int channel, void *data,
- struct scatterlist *sg)
+static void audio_dma_irq(void *data)
{
- struct snd_pcm_substream *substream = data;
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- if (!sg)
- return;
-
- runtime = iprtd->substream->runtime;
+ iprtd->offset += iprtd->period_bytes;
+ iprtd->offset %= iprtd->period_bytes * iprtd->periods;
- iprtd->offset = sg->dma_address - runtime->dma_addr;
-
- snd_pcm_period_elapsed(iprtd->substream);
+ snd_pcm_period_elapsed(substream);
}
-static void imx_ssi_dma_callback(int channel, void *data)
+static bool filter(struct dma_chan *chan, void *param)
{
- pr_err("%s shouldn't be called\n", __func__);
-}
+ struct imx_pcm_runtime_data *iprtd = param;
-static void snd_imx_dma_err_callback(int channel, void *data, int err)
-{
- struct snd_pcm_substream *substream = data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params =
- snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- int ret;
+ if (!imx_dma_is_general_purpose(chan))
+ return false;
- pr_err("DMA timeout on channel %d -%s%s%s%s\n",
- channel,
- err & IMX_DMA_ERR_BURST ? " burst" : "",
- err & IMX_DMA_ERR_REQUEST ? " request" : "",
- err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
- err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
+ chan->private = &iprtd->dma_data;
- imx_dma_disable(iprtd->dma);
- ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
- IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- DMA_MODE_WRITE : DMA_MODE_READ);
- if (!ret)
- imx_dma_enable(iprtd->dma);
+ return true;
}
-static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
+static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+ struct dma_slave_config slave_config;
+ dma_cap_mask_t mask;
+ enum dma_slave_buswidth buswidth;
int ret;
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
- if (iprtd->dma < 0) {
- pr_err("Failed to claim the audio DMA\n");
- return -ENODEV;
- }
+ iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI;
+ iprtd->dma_data.priority = DMA_PRIO_HIGH;
+ iprtd->dma_data.dma_request = dma_params->dma;
- ret = imx_dma_setup_handlers(iprtd->dma,
- imx_ssi_dma_callback,
- snd_imx_dma_err_callback, substream);
- if (ret)
- goto out;
+ /* Try to grab a DMA channel */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
+ if (!iprtd->dma_chan)
+ return -EINVAL;
- ret = imx_dma_setup_progression_handler(iprtd->dma,
- imx_ssi_dma_progression);
- if (ret) {
- pr_err("Failed to setup the DMA handler\n");
- goto out;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ return 0;
}
- ret = imx_dma_config_channel(iprtd->dma,
- IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
- IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
- dma_params->dma, 1);
- if (ret < 0) {
- pr_err("Cannot configure DMA channel: %d\n", ret);
- goto out;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ slave_config.direction = DMA_TO_DEVICE;
+ slave_config.dst_addr = dma_params->dma_addr;
+ slave_config.dst_addr_width = buswidth;
+ slave_config.dst_maxburst = dma_params->burstsize;
+ } else {
+ slave_config.direction = DMA_FROM_DEVICE;
+ slave_config.src_addr = dma_params->dma_addr;
+ slave_config.src_addr_width = buswidth;
+ slave_config.src_maxburst = dma_params->burstsize;
}
- imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
+ ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
+ if (ret)
+ return ret;
return 0;
-out:
- imx_dma_free(iprtd->dma);
- return ret;
}
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- int i;
unsigned long dma_addr;
+ struct dma_chan *chan;
+ struct imx_pcm_dma_params *dma_params;
+ int ret;
- imx_ssi_dma_alloc(substream);
+ dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ ret = imx_ssi_dma_alloc(substream, params);
+ if (ret)
+ return ret;
+ chan = iprtd->dma_chan;
iprtd->size = params_buffer_bytes(params);
iprtd->periods = params_periods(params);
- iprtd->period = params_period_bytes(params);
+ iprtd->period_bytes = params_period_bytes(params);
iprtd->offset = 0;
iprtd->period_time = HZ / (params_rate(params) /
params_period_size(params));
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- if (iprtd->sg_count != iprtd->periods) {
- kfree(iprtd->sg_list);
-
- iprtd->sg_list = kcalloc(iprtd->periods + 1,
- sizeof(struct scatterlist), GFP_KERNEL);
- if (!iprtd->sg_list)
- return -ENOMEM;
- iprtd->sg_count = iprtd->periods + 1;
- }
-
- sg_init_table(iprtd->sg_list, iprtd->sg_count);
dma_addr = runtime->dma_addr;
- for (i = 0; i < iprtd->periods; i++) {
- iprtd->sg_list[i].page_link = 0;
- iprtd->sg_list[i].offset = 0;
- iprtd->sg_list[i].dma_address = dma_addr;
- iprtd->sg_list[i].length = iprtd->period;
- dma_addr += iprtd->period;
+ iprtd->buf = (unsigned int *)substream->dma_buffer.area;
+
+ iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
+ iprtd->period_bytes * iprtd->periods,
+ iprtd->period_bytes,
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ if (!iprtd->desc) {
+ dev_err(&chan->dev->device, "cannot prepare slave dma\n");
+ return -EINVAL;
}
- /* close the loop */
- iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
- iprtd->sg_list[iprtd->sg_count - 1].length = 0;
- iprtd->sg_list[iprtd->sg_count - 1].page_link =
- ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
+ iprtd->desc->callback = audio_dma_irq;
+ iprtd->desc->callback_param = substream;
+
return 0;
}
@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- if (iprtd->dma >= 0) {
- imx_dma_free(iprtd->dma);
- iprtd->dma = -EINVAL;
+ if (iprtd->dma_chan) {
+ dma_release_channel(iprtd->dma_chan);
+ iprtd->dma_chan = NULL;
}
- kfree(iprtd->sg_list);
- iprtd->sg_list = NULL;
-
return 0;
}
static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- int err;
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- iprtd->substream = substream;
- iprtd->buf = (unsigned int *)substream->dma_buffer.area;
- iprtd->period_cnt = 0;
-
- pr_debug("%s: buf: %p period: %d periods: %d\n",
- __func__, iprtd->buf, iprtd->period, iprtd->periods);
-
- err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
- IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- DMA_MODE_WRITE : DMA_MODE_READ);
- if (err)
- return err;
-
return 0;
}
@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- imx_dma_enable(iprtd->dma);
+ dmaengine_submit(iprtd->desc);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- imx_dma_disable(iprtd->dma);
+ dmaengine_terminate_all(iprtd->dma_chan);
break;
default:
@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+ pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
+ bytes_to_frames(substream->runtime, iprtd->offset));
+
return bytes_to_frames(substream->runtime, iprtd->offset);
}
@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
.channels_max = 2,
.buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
.period_bytes_min = 128,
- .period_bytes_max = 16 * 1024,
+ .period_bytes_max = 65535, /* Limited by SDMA engine */
.periods_min = 2,
.periods_max = 255,
.fifo_size = 0,
@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
}
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+
+ return 0;
+}
+
+static int snd_imx_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+ kfree(iprtd);
+
return 0;
}
static struct snd_pcm_ops imx_pcm_ops = {
.open = snd_imx_open,
+ .close = snd_imx_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_imx_pcm_hw_params,
.hw_free = snd_imx_pcm_hw_free,
@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = {
.name = "imx-pcm-audio",
.owner = THIS_MODULE,
},
-
.probe = imx_soc_platform_probe,
.remove = __devexit_p(imx_soc_platform_remove),
};
@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void)
platform_driver_unregister(&imx_pcm_driver);
}
module_exit(snd_imx_pcm_exit);
-
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index d4bd345b0a8..390b6ffc265 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm)
}
EXPORT_SYMBOL_GPL(imx_pcm_free);
+static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
+{
+ struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
+ uint32_t val;
+
+ snd_soc_dai_set_drvdata(dai, ssi);
+
+ val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
+ SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
+ writel(val, ssi->base + SSI_SFCSR);
+
+ return 0;
+}
+
static struct snd_soc_dai_driver imx_ssi_dai = {
+ .probe = imx_ssi_dai_probe,
.playback = {
.channels_min = 2,
.channels_max = 2,
@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = {
.ops = &imx_ssi_pcm_dai_ops,
};
-static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
-{
- struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
- uint32_t val;
-
- snd_soc_dai_set_drvdata(dai, ssi);
-
- val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
- SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
- writel(val, ssi->base + SSI_SFCSR);
-
- return 0;
-}
-
static struct snd_soc_dai_driver imx_ac97_dai = {
.probe = imx_ssi_dai_probe,
.ac97_control = 1,
@@ -677,9 +678,25 @@ static int imx_ssi_probe(struct platform_device *pdev)
goto failed_register;
}
- ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
- if (!ssi->soc_platform_pdev)
+ ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
+ if (!ssi->soc_platform_pdev_fiq) {
+ ret = -ENOMEM;
+ goto failed_pdev_fiq_alloc;
+ }
+
+ platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
+ ret = platform_device_add(ssi->soc_platform_pdev_fiq);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform device\n");
+ goto failed_pdev_fiq_add;
+ }
+
+ ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
+ if (!ssi->soc_platform_pdev) {
+ ret = -ENOMEM;
goto failed_pdev_alloc;
+ }
+
platform_set_drvdata(ssi->soc_platform_pdev, ssi);
ret = platform_device_add(ssi->soc_platform_pdev);
if (ret) {
@@ -692,6 +709,10 @@ static int imx_ssi_probe(struct platform_device *pdev)
failed_pdev_add:
platform_device_put(ssi->soc_platform_pdev);
failed_pdev_alloc:
+ platform_device_del(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_add:
+ platform_device_put(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_alloc:
snd_soc_unregister_dai(&pdev->dev);
failed_register:
failed_ac97:
@@ -712,8 +733,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct imx_ssi *ssi = platform_get_drvdata(pdev);
- platform_device_del(ssi->soc_platform_pdev);
- platform_device_put(ssi->soc_platform_pdev);
+ platform_device_unregister(ssi->soc_platform_pdev);
+ platform_device_unregister(ssi->soc_platform_pdev_fiq);
snd_soc_unregister_dai(&pdev->dev);
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 53b780d9b2b..a4406a13489 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -185,6 +185,9 @@
#define DRV_NAME "imx-ssi"
+#include <linux/dmaengine.h>
+#include <mach/dma.h>
+
struct imx_pcm_dma_params {
int dma;
unsigned long dma_addr;
@@ -212,6 +215,7 @@ struct imx_ssi {
int enabled;
struct platform_device *soc_platform_pdev;
+ struct platform_device *soc_platform_pdev_fiq;
};
struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 6a65dd70551..9eabc28667e 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -20,9 +20,6 @@
#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
-#include "../codecs/wm9712.h"
-#include "imx-ssi.h"
-
static struct snd_soc_card imx_phycore;
static struct snd_soc_ops imx_phycore_hifi_ops = {
@@ -41,11 +38,12 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
};
static struct snd_soc_card imx_phycore = {
- .name = "PhyCORE-audio",
+ .name = "PhyCORE-ac97-audio",
.dai_link = imx_phycore_dai_ac97,
.num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
};
+static struct platform_device *imx_phycore_snd_ac97_device;
static struct platform_device *imx_phycore_snd_device;
static int __init imx_phycore_init(void)
@@ -56,29 +54,42 @@ static int __init imx_phycore_init(void)
/* return happy. We might run on a totally different machine */
return 0;
- imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
- if (!imx_phycore_snd_device)
+ imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
+ if (!imx_phycore_snd_ac97_device)
return -ENOMEM;
- platform_set_drvdata(imx_phycore_snd_device, &imx_phycore);
- ret = platform_device_add(imx_phycore_snd_device);
+ platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
+ ret = platform_device_add(imx_phycore_snd_ac97_device);
+ if (ret)
+ goto fail1;
imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
- if (!imx_phycore_snd_device)
- return -ENOMEM;
+ if (!imx_phycore_snd_device) {
+ ret = -ENOMEM;
+ goto fail2;
+ }
ret = platform_device_add(imx_phycore_snd_device);
if (ret) {
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- platform_device_put(imx_phycore_snd_device);
+ goto fail3;
}
+ return 0;
+
+fail3:
+ platform_device_put(imx_phycore_snd_device);
+fail2:
+ platform_device_del(imx_phycore_snd_ac97_device);
+fail1:
+ platform_device_put(imx_phycore_snd_ac97_device);
return ret;
}
static void __exit imx_phycore_exit(void)
{
platform_device_unregister(imx_phycore_snd_device);
+ platform_device_unregister(imx_phycore_snd_ac97_device);
}
late_initcall(imx_phycore_init);
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index 293dc748797..dac6732da96 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -49,7 +49,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
mutex_lock(&ac97_mutex);
val = nuc900_checkready();
- if (!!val) {
+ if (val) {
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
goto out;
}
@@ -102,7 +102,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
mutex_lock(&ac97_mutex);
tmp = nuc900_checkready();
- if (!!tmp)
+ if (tmp)
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
/* clear the R_WB bit and write register index */
@@ -149,7 +149,7 @@ static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
udelay(100);
val = nuc900_checkready();
- if (!!val)
+ if (val)
dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
mutex_unlock(&ac97_mutex);
@@ -263,8 +263,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
return ret;
}
-static int nuc900_ac97_probe(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int nuc900_ac97_probe(struct snd_soc_dai *dai)
{
struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
unsigned long val;
@@ -284,12 +283,12 @@ static int nuc900_ac97_probe(struct platform_device *pdev,
return 0;
}
-static void nuc900_ac97_remove(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int nuc900_ac97_remove(struct snd_soc_dai *dai)
{
struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
clk_disable(nuc900_audio->clk);
+ return 0;
}
static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
@@ -313,7 +312,7 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = {
.channels_max = 2,
},
.ops = &nuc900_ac97_dai_ops,
-}
+};
static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
{
@@ -384,7 +383,6 @@ out0:
static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
{
-
snd_soc_unregister_dai(&pdev->dev);
clk_put(nuc900_ac97_data->clk);
@@ -392,6 +390,7 @@ static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
release_mem_region(nuc900_ac97_data->res->start,
resource_size(nuc900_ac97_data->res));
+ kfree(nuc900_ac97_data);
nuc900_ac97_data = NULL;
return 0;
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
index aeed8ead2b2..59f7e8ed1a6 100644
--- a/sound/soc/nuc900/nuc900-audio.h
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -110,4 +110,6 @@ struct nuc900_audio {
};
+extern struct nuc900_audio *nuc900_ac97_data;
+
#endif /*end _NUC900_AUDIO_H */
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index 195d1ac9477..8263f56dc66 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -50,12 +50,12 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&nuc900_audio->lock, flags);
-
ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
if (ret < 0)
return ret;
+ spin_lock_irqsave(&nuc900_audio->lock, flags);
+
nuc900_audio->substream = substream;
nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
nuc900_audio->buffersize[substream->stream] =
@@ -169,6 +169,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct nuc900_audio *nuc900_audio = runtime->private_data;
unsigned long flags, val;
+ int ret = 0;
spin_lock_irqsave(&nuc900_audio->lock, flags);
@@ -197,10 +198,10 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
spin_unlock_irqrestore(&nuc900_audio->lock, flags);
- return 0;
+ return ret;
}
static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -332,7 +333,7 @@ static struct snd_soc_platform_driver nuc900_soc_platform = {
.ops = &nuc900_dma_ops,
.pcm_new = nuc900_dma_new,
.pcm_free = nuc900_dma_free_dma_buffers,
-}
+};
static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
{
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index d542ea2ff6b..a088db6d509 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -12,8 +12,8 @@ config SND_OMAP_SOC_MCPDM
config SND_OMAP_SOC_N810
tristate "SoC Audio support for Nokia N810"
depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
+ depends on OMAP_MUX
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.
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index d211c9fa5a9..7e84f24b9a8 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
case OMAP_MCBSP_CLKR_SRC_CLKR:
+ if (cpu_class_is_omap1())
+ break;
omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
break;
case OMAP_MCBSP_CLKR_SRC_CLKX:
+ if (cpu_class_is_omap1())
+ break;
omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
break;
case OMAP_MCBSP_FSR_SRC_FSR:
+ if (cpu_class_is_omap1())
+ break;
omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
break;
case OMAP_MCBSP_FSR_SRC_FSX:
+ if (cpu_class_is_omap1())
+ break;
omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
break;
default:
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index dbd9d96b5f9..4ee33ce2cb9 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -306,6 +306,7 @@ static int __init omap3pandora_soc_init(void)
pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
dev_name(&omap3pandora_snd_device->dev),
PTR_ERR(omap3pandora_dac_reg));
+ ret = PTR_ERR(omap3pandora_dac_reg);
goto fail3;
}
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index f0e66255642..65ae00e976e 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -177,7 +177,8 @@ static int __init osk_soc_init(void)
tlv320aic23_mclk = clk_get(dev, "mclk");
if (IS_ERR(tlv320aic23_mclk)) {
printk(KERN_ERR "Could not get mclk clock\n");
- return -ENODEV;
+ err = PTR_ERR(tlv320aic23_mclk);
+ goto err2;
}
/*
@@ -188,7 +189,7 @@ static int __init osk_soc_init(void)
if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
err = -ECANCELED;
- goto err1;
+ goto err3;
}
}
@@ -196,9 +197,12 @@ static int __init osk_soc_init(void)
(uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
return 0;
-err1:
+
+err3:
clk_put(tlv320aic23_mclk);
+err2:
platform_device_del(osk_snd_device);
+err1:
platform_device_put(osk_snd_device);
return err;
@@ -207,6 +211,7 @@ err1:
static void __exit osk_soc_exit(void)
{
+ clk_put(tlv320aic23_mclk);
platform_device_unregister(osk_snd_device);
}
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 37f191bbfdd..580f4857130 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
config SND_PXA2XX_SOC
tristate "SoC Audio for the Intel PXA2xx chip"
depends on ARCH_PXA
+ select SND_ARM
select SND_PXA2XX_LIB
help
Say Y or M if you want to add support for codecs attached to
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 97e9423615c..f451acd4935 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ mutex_lock(&codec->mutex);
+
/* check the jack status at stream startup */
corgi_ext_control(codec);
+
+ mutex_unlock(&codec->mutex);
+
return 0;
}
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index b8207ced407..5ef0526924b 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ mutex_lock(&codec->mutex);
+
/* check the jack status at stream startup */
magician_ext_control(codec);
+ mutex_unlock(&codec->mutex);
+
return 0;
}
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index af84ee9c5e1..84edd0385a2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ mutex_lock(&codec->mutex);
+
/* check the jack status at stream startup */
poodle_ext_control(codec);
+
+ mutex_unlock(&codec->mutex);
+
return 0;
}
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index f470f360f4d..0b30d7de24e 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ mutex_lock(&codec->mutex);
+
/* check the jack status at stream startup */
spitz_ext_control(codec);
+
+ mutex_unlock(&codec->mutex);
+
return 0;
}
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 73d0edd8ded..7b983f93545 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ mutex_lock(&codec->mutex);
+
/* check the jack status at stream startup */
tosa_ext_control(codec);
+
+ mutex_unlock(&codec->mutex);
+
return 0;
}
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 8a6b53ccd20..d85bf8a0abb 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC
tristate "SoC Audio for the Samsung S3CXXXX chips"
depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
select S3C64XX_DMA if ARCH_S3C64XX
+ select S3C2410_DMA if ARCH_S3C2410
help
Say Y or M if you want to add support for codecs attached to
the S3C24XX AC97 or I2S interfaces. You will also need to
diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c
index ffd5cf2fb0a..468cc11fdf4 100644
--- a/sound/soc/s3c24xx/rx1950_uda1380.c
+++ b/sound/soc/s3c24xx/rx1950_uda1380.c
@@ -50,7 +50,6 @@ static unsigned int rates[] = {
16000,
44100,
48000,
- 88200,
};
static struct snd_pcm_hw_constraint_list hw_rates = {
@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
};
static struct platform_device *s3c24xx_snd_device;
-static struct clk *xtal;
static int rx1950_startup(struct snd_pcm_substream *substream)
{
@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
case 44100:
case 88200:
clk_source = S3C24XX_CLKSRC_MPLL;
- fs_mode = S3C2410_IISMOD_256FS;
- div = clk_get_rate(xtal) / (256 * rate);
- if (clk_get_rate(xtal) % (256 * rate) > (128 * rate))
- div++;
+ fs_mode = S3C2410_IISMOD_384FS;
+ div = 1;
break;
default:
printk(KERN_ERR "%s: rate %d is not supported\n",
@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
/* set MCLK division for sample rate */
ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
- S3C2410_IISMOD_384FS);
+ fs_mode);
if (ret < 0)
return ret;
@@ -295,17 +291,8 @@ static int __init rx1950_init(void)
goto err_plat_add;
}
- xtal = clk_get(&s3c24xx_snd_device->dev, "xtal");
-
- if (IS_ERR(xtal)) {
- ret = PTR_ERR(xtal);
- platform_device_unregister(s3c24xx_snd_device);
- goto err_clk;
- }
-
return 0;
-err_clk:
err_plat_add:
err_plat_alloc:
err_gpio_conf:
@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void)
platform_device_unregister(s3c24xx_snd_device);
snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
hp_jack_gpios);
- clk_put(xtal);
gpio_free(S3C2410_GPA(1));
}
diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/s3c24xx/smdk_spdif.c
index f31d22ad7c8..c8bd90488a8 100644
--- a/sound/soc/s3c24xx/smdk_spdif.c
+++ b/sound/soc/s3c24xx/smdk_spdif.c
@@ -38,7 +38,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
}
mout_epll = clk_get(NULL, "mout_epll");
- if (IS_ERR(fout_epll)) {
+ if (IS_ERR(mout_epll)) {
printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
__func__);
ret = -EINVAL;
@@ -54,7 +54,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
}
sclk_spdif = clk_get(NULL, "sclk_spdif");
- if (IS_ERR(fout_epll)) {
+ if (IS_ERR(sclk_spdif)) {
printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n",
__func__);
ret = -EINVAL;
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 8778faa174a..3052f64b240 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -434,7 +434,7 @@ static struct snd_soc_dai_driver s6000_i2s_dai = {
.rate_max = 1562500,
},
.ops = &s6000_i2s_dai_ops,
-}
+};
static int __devinit s6000_i2s_probe(struct platform_device *pdev)
{
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 271fd222bf1..ab3ccaec72d 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -473,7 +473,7 @@ static int s6000_pcm_new(struct snd_card *card,
}
res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
- s6000_soc_platform.name, pcm);
+ "s6000-audio", pcm);
if (res) {
printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
return res;
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 96c05e13753..c1244c5bc73 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -167,7 +167,7 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_sync(codec);
- snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+ snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
return 0;
}
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 507e709f280..4c2404b1b86 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -132,6 +132,8 @@ struct fsi_priv {
struct fsi_stream playback;
struct fsi_stream capture;
+ long rate;
+
u32 mst_ctrl;
};
@@ -854,10 +856,17 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
int is_play = fsi_is_play(substream);
+ struct fsi_master *master = fsi_get_master(fsi);
+ int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
fsi_irq_disable(fsi, is_play);
fsi_clk_ctrl(fsi, 0);
+ set_rate = master->info->set_rate;
+ if (set_rate && fsi->rate)
+ set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
+ fsi->rate = 0;
+
pm_runtime_put_sync(dai->dev);
}
@@ -891,20 +900,20 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
struct fsi_master *master = fsi_get_master(fsi);
- int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
+ int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
int fsi_ver = master->core->ver;
- int is_play = fsi_is_play(substream);
+ long rate = params_rate(params);
int ret;
- /* if slave mode, set_rate is not needed */
- if (!fsi_is_master_mode(fsi, is_play))
+ set_rate = master->info->set_rate;
+ if (!set_rate)
return 0;
- /* it is error if no set_rate */
- if (!set_rate)
- return -EIO;
+ ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
+ if (ret < 0) /* error */
+ return ret;
- ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
+ fsi->rate = rate;
if (ret > 0) {
u32 data = 0;
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 40bbdf1591d..05192d97b37 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -387,7 +387,7 @@ static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
{
- snd_soc_unregister_dai(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
+ snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
return 0;
}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 614a8b30d87..85b7d548f16 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
#ifdef CONFIG_SND_SOC_AC97_BUS
/* register any AC97 codecs */
for (i = 0; i < card->num_rtd; i++) {
- ret = soc_register_ac97_dai_link(&card->rtd[i]);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
- goto probe_dai_err;
- }
+ ret = soc_register_ac97_dai_link(&card->rtd[i]);
+ if (ret < 0) {
+ printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+ while (--i >= 0)
+ soc_unregister_ac97_dai_link(&card->rtd[i]);
+ goto probe_dai_err;
}
+ }
#endif
card->instantiated = 1;
@@ -3043,8 +3045,10 @@ int snd_soc_register_dais(struct device *dev,
for (i = 0; i < count; i++) {
dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
- if (dai == NULL)
- return -ENOMEM;
+ if (dai == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
/* create DAI component name */
dai->name = fmt_multiple_name(dev, &dai_drv[i]);
@@ -3070,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev,
pr_debug("Registered DAI '%s'\n", dai->name);
}
+ mutex_lock(&client_mutex);
snd_soc_instantiate_cards();
+ mutex_unlock(&client_mutex);
return 0;
err:
@@ -3263,9 +3269,6 @@ int snd_soc_register_codec(struct device *dev,
return 0;
error:
- for (i--; i >= 0; i--)
- snd_soc_unregister_dai(dev);
-
if (codec->reg_cache)
kfree(codec->reg_cache);
kfree(codec->name);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7d85c6496af..c721502833b 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
struct snd_soc_dapm_widget *b,
int sort[])
{
- if (a->codec != b->codec)
- return (unsigned long)a - (unsigned long)b;
if (sort[a->id] != sort[b->id])
return sort[a->id] - sort[b->id];
if (a->reg != b->reg)
return a->reg - b->reg;
+ if (a->codec != b->codec)
+ return (unsigned long)a->codec - (unsigned long)b->codec;
return 0;
}
@@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
case SND_SOC_DAPM_STREAM_RESUME:
sys_power = 1;
break;
+ case SND_SOC_DAPM_STREAM_STOP:
+ sys_power = !!codec->active;
+ break;
case SND_SOC_DAPM_STREAM_SUSPEND:
sys_power = 0;
break;