aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-15 02:37:22 -0400
committerTakashi Iwai <tiwai@suse.de>2012-03-15 02:37:22 -0400
commit828006de1bddf83b6ecf03ec459c15f7c7c22db7 (patch)
tree73a224bf0371b41c9777c2bad8169ed50bcca879 /sound
parentd0f47ff17f29740eabbd64e11705b7332241714c (diff)
parent5ec65ee589fdaca7298b6303fd74ad6c121a8f38 (diff)
Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into topic/asoc
Linus decided to go for another week so here's a few more updates - a mixed bag here, a few minor diagnostic tweaks, some driver enhancements and the dmaengine conversion for ep93xx drivers which was tested a while ago and just waiting for a signoff.
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/da7210.c146
-rw-r--r--sound/soc/codecs/wm8994.c69
-rw-r--r--sound/soc/codecs/wm8996.c34
-rw-r--r--sound/soc/ep93xx/Kconfig1
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c148
-rw-r--r--sound/soc/fsl/fsl_ssi.c6
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c32
-rw-r--r--sound/soc/imx/imx-audmux.c8
-rw-r--r--sound/soc/imx/mx27vis-aic32x4.c41
-rw-r--r--sound/soc/pxa/pxa-ssp.c3
-rw-r--r--sound/soc/soc-core.c12
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/soc/soc-dmaengine-pcm.c1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c1
15 files changed, 223 insertions, 283 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index ab38e93c3543..7843711729bc 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/regmap.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
626 627
627/* Codec private data */ 628/* Codec private data */
628struct da7210_priv { 629struct da7210_priv {
629 enum snd_soc_control_type control_type; 630 struct regmap *regmap;
630}; 631};
631 632
632/* 633static struct reg_default da7210_reg_defaults[] = {
633 * Register cache 634 { 0x01, 0x11 },
634 */ 635 { 0x03, 0x00 },
635static const u8 da7210_reg[] = { 636 { 0x04, 0x00 },
636 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */ 637 { 0x05, 0x00 },
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */ 638 { 0x06, 0x00 },
638 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */ 639 { 0x07, 0x00 },
639 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */ 640 { 0x08, 0x00 },
640 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */ 641 { 0x09, 0x00 },
641 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */ 642 { 0x0a, 0x00 },
642 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */ 643 { 0x0b, 0x00 },
643 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */ 644 { 0x0c, 0x00 },
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */ 645 { 0x0d, 0x00 },
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */ 646 { 0x0e, 0x00 },
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */ 647 { 0x0f, 0x08 },
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */ 648 { 0x10, 0x00 },
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */ 649 { 0x11, 0x00 },
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */ 650 { 0x12, 0x00 },
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */ 651 { 0x13, 0x00 },
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */ 652 { 0x14, 0x08 },
652 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */ 653 { 0x15, 0x10 },
653 0x00, /* R88 */ 654 { 0x16, 0x10 },
655 { 0x17, 0x54 },
656 { 0x18, 0x40 },
657 { 0x19, 0x00 },
658 { 0x1a, 0x00 },
659 { 0x1b, 0x00 },
660 { 0x1c, 0x00 },
661 { 0x1d, 0x00 },
662 { 0x1e, 0x00 },
663 { 0x1f, 0x00 },
664 { 0x20, 0x00 },
665 { 0x21, 0x00 },
666 { 0x22, 0x00 },
667 { 0x23, 0x02 },
668 { 0x24, 0x00 },
669 { 0x25, 0x76 },
670 { 0x26, 0x00 },
671 { 0x27, 0x00 },
672 { 0x28, 0x04 },
673 { 0x29, 0x00 },
674 { 0x2a, 0x00 },
675 { 0x2b, 0x30 },
676 { 0x2c, 0x2A },
677 { 0x83, 0x00 },
678 { 0x84, 0x00 },
679 { 0x85, 0x00 },
680 { 0x86, 0x00 },
681 { 0x87, 0x00 },
682 { 0x88, 0x00 },
654}; 683};
655 684
656static int da7210_volatile_register(struct snd_soc_codec *codec, 685static bool da7210_readable_register(struct device *dev, unsigned int reg)
686{
687 switch (reg) {
688 case DA7210_A_HID_UNLOCK:
689 case DA7210_A_TEST_UNLOCK:
690 case DA7210_A_PLL1:
691 case DA7210_A_CP_MODE:
692 return false;
693 default:
694 return true;
695 }
696}
697
698static bool da7210_volatile_register(struct device *dev,
657 unsigned int reg) 699 unsigned int reg)
658{ 700{
659 switch (reg) { 701 switch (reg) {
660 case DA7210_STATUS: 702 case DA7210_STATUS:
661 return 1; 703 return true;
662 default: 704 default:
663 return 0; 705 return false;
664 } 706 }
665} 707}
666 708
@@ -866,7 +908,8 @@ static int da7210_probe(struct snd_soc_codec *codec)
866 908
867 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 909 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
868 910
869 ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); 911 codec->control_data = da7210->regmap;
912 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
870 if (ret < 0) { 913 if (ret < 0) {
871 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 914 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
872 return ret; 915 return ret;
@@ -983,12 +1026,14 @@ static int da7210_probe(struct snd_soc_codec *codec)
983 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); 1026 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
984 1027
985 /* As suggested by Dialog */ 1028 /* As suggested by Dialog */
986 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ 1029 /* unlock */
987 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); 1030 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
988 snd_soc_write(codec, DA7210_A_PLL1, 0x01); 1031 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
989 snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); 1032 regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
990 snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ 1033 regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
991 snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); 1034 /* re-lock */
1035 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
1036 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
992 1037
993 /* Activate all enabled subsystem */ 1038 /* Activate all enabled subsystem */
994 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 1039 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
@@ -1000,10 +1045,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
1000 1045
1001static struct snd_soc_codec_driver soc_codec_dev_da7210 = { 1046static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1002 .probe = da7210_probe, 1047 .probe = da7210_probe,
1003 .reg_cache_size = ARRAY_SIZE(da7210_reg),
1004 .reg_word_size = sizeof(u8),
1005 .reg_cache_default = da7210_reg,
1006 .volatile_register = da7210_volatile_register,
1007 1048
1008 .controls = da7210_snd_controls, 1049 .controls = da7210_snd_controls,
1009 .num_controls = ARRAY_SIZE(da7210_snd_controls), 1050 .num_controls = ARRAY_SIZE(da7210_snd_controls),
@@ -1014,6 +1055,17 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1014 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), 1055 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
1015}; 1056};
1016 1057
1058static struct regmap_config da7210_regmap = {
1059 .reg_bits = 8,
1060 .val_bits = 8,
1061
1062 .reg_defaults = da7210_reg_defaults,
1063 .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
1064 .volatile_reg = da7210_volatile_register,
1065 .readable_reg = da7210_readable_register,
1066 .cache_type = REGCACHE_RBTREE,
1067};
1068
1017#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1018static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 1070static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1019 const struct i2c_device_id *id) 1071 const struct i2c_device_id *id)
@@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1027 return -ENOMEM; 1079 return -ENOMEM;
1028 1080
1029 i2c_set_clientdata(i2c, da7210); 1081 i2c_set_clientdata(i2c, da7210);
1030 da7210->control_type = SND_SOC_I2C; 1082
1083 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap);
1084 if (IS_ERR(da7210->regmap)) {
1085 ret = PTR_ERR(da7210->regmap);
1086 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1087 return ret;
1088 }
1031 1089
1032 ret = snd_soc_register_codec(&i2c->dev, 1090 ret = snd_soc_register_codec(&i2c->dev,
1033 &soc_codec_dev_da7210, &da7210_dai, 1); 1091 &soc_codec_dev_da7210, &da7210_dai, 1);
1092 if (ret < 0) {
1093 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1094 goto err_regmap;
1095 }
1096 return ret;
1097
1098err_regmap:
1099 regmap_exit(da7210->regmap);
1100
1034 return ret; 1101 return ret;
1035} 1102}
1036 1103
1037static int __devexit da7210_i2c_remove(struct i2c_client *client) 1104static int __devexit da7210_i2c_remove(struct i2c_client *client)
1038{ 1105{
1106 struct da7210_priv *da7210 = i2c_get_clientdata(client);
1107
1039 snd_soc_unregister_codec(&client->dev); 1108 snd_soc_unregister_codec(&client->dev);
1109 regmap_exit(da7210->regmap);
1040 return 0; 1110 return 0;
1041} 1111}
1042 1112
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index bc12d097ef0d..15fcb1bb7148 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3166,9 +3166,16 @@ static void wm8958_default_micdet(u16 status, void *data)
3166 3166
3167 /* If we have jackdet that will detect removal */ 3167 /* If we have jackdet that will detect removal */
3168 if (wm8994->jackdet) { 3168 if (wm8994->jackdet) {
3169 mutex_lock(&wm8994->accdet_lock);
3170
3169 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3171 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3170 WM8958_MICD_ENA, 0); 3172 WM8958_MICD_ENA, 0);
3171 3173
3174 wm1811_jackdet_set_mode(codec,
3175 WM1811_JACKDET_MODE_JACK);
3176
3177 mutex_unlock(&wm8994->accdet_lock);
3178
3172 if (wm8994->pdata->jd_ext_cap) { 3179 if (wm8994->pdata->jd_ext_cap) {
3173 mutex_lock(&codec->mutex); 3180 mutex_lock(&codec->mutex);
3174 snd_soc_dapm_disable_pin(&codec->dapm, 3181 snd_soc_dapm_disable_pin(&codec->dapm,
@@ -3176,9 +3183,6 @@ static void wm8958_default_micdet(u16 status, void *data)
3176 snd_soc_dapm_sync(&codec->dapm); 3183 snd_soc_dapm_sync(&codec->dapm);
3177 mutex_unlock(&codec->mutex); 3184 mutex_unlock(&codec->mutex);
3178 } 3185 }
3179
3180 wm1811_jackdet_set_mode(codec,
3181 WM1811_JACKDET_MODE_JACK);
3182 } 3186 }
3183 } 3187 }
3184 3188
@@ -3213,6 +3217,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3213 struct wm8994_priv *wm8994 = data; 3217 struct wm8994_priv *wm8994 = data;
3214 struct snd_soc_codec *codec = wm8994->codec; 3218 struct snd_soc_codec *codec = wm8994->codec;
3215 int reg; 3219 int reg;
3220 bool present;
3216 3221
3217 mutex_lock(&wm8994->accdet_lock); 3222 mutex_lock(&wm8994->accdet_lock);
3218 3223
@@ -3225,11 +3230,10 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3225 3230
3226 dev_dbg(codec->dev, "JACKDET %x\n", reg); 3231 dev_dbg(codec->dev, "JACKDET %x\n", reg);
3227 3232
3228 if (reg & WM1811_JACKDET_LVL) { 3233 present = reg & WM1811_JACKDET_LVL;
3229 dev_dbg(codec->dev, "Jack detected\n");
3230 3234
3231 snd_soc_jack_report(wm8994->micdet[0].jack, 3235 if (present) {
3232 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); 3236 dev_dbg(codec->dev, "Jack detected\n");
3233 3237
3234 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3238 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3235 WM8958_MICB2_DISCH, 0); 3239 WM8958_MICB2_DISCH, 0);
@@ -3247,32 +3251,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3247 3251
3248 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3252 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3249 WM8958_MICD_ENA, WM8958_MICD_ENA); 3253 WM8958_MICD_ENA, WM8958_MICD_ENA);
3250
3251 /* If required for an external cap force MICBIAS on */
3252 if (wm8994->pdata->jd_ext_cap) {
3253 mutex_lock(&codec->mutex);
3254 snd_soc_dapm_force_enable_pin(&codec->dapm,
3255 "MICBIAS2");
3256 snd_soc_dapm_sync(&codec->dapm);
3257 mutex_unlock(&codec->mutex);
3258 }
3259 } else { 3254 } else {
3260 dev_dbg(codec->dev, "Jack not detected\n"); 3255 dev_dbg(codec->dev, "Jack not detected\n");
3261 3256
3262 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3257 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3263 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); 3258 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
3264 3259
3265 if (wm8994->pdata->jd_ext_cap) {
3266 mutex_lock(&codec->mutex);
3267 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3268 snd_soc_dapm_sync(&codec->dapm);
3269 mutex_unlock(&codec->mutex);
3270 }
3271
3272 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3273 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3274 wm8994->btn_mask);
3275
3276 /* Enable debounce while removed */ 3260 /* Enable debounce while removed */
3277 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, 3261 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3278 WM1811_JACKDET_DB, WM1811_JACKDET_DB); 3262 WM1811_JACKDET_DB, WM1811_JACKDET_DB);
@@ -3286,6 +3270,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3286 3270
3287 mutex_unlock(&wm8994->accdet_lock); 3271 mutex_unlock(&wm8994->accdet_lock);
3288 3272
3273 /* If required for an external cap force MICBIAS on */
3274 if (wm8994->pdata->jd_ext_cap) {
3275 mutex_lock(&codec->mutex);
3276
3277 if (present)
3278 snd_soc_dapm_force_enable_pin(&codec->dapm,
3279 "MICBIAS2");
3280 else
3281 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3282
3283 snd_soc_dapm_sync(&codec->dapm);
3284 mutex_unlock(&codec->mutex);
3285 }
3286
3287 if (present)
3288 snd_soc_jack_report(wm8994->micdet[0].jack,
3289 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
3290 else
3291 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3292 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3293 wm8994->btn_mask);
3294
3289 return IRQ_HANDLED; 3295 return IRQ_HANDLED;
3290} 3296}
3291 3297
@@ -3389,17 +3395,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3389 struct snd_soc_codec *codec = wm8994->codec; 3395 struct snd_soc_codec *codec = wm8994->codec;
3390 int reg, count; 3396 int reg, count;
3391 3397
3392 mutex_lock(&wm8994->accdet_lock);
3393
3394 /* 3398 /*
3395 * Jack detection may have detected a removal simulataneously 3399 * Jack detection may have detected a removal simulataneously
3396 * with an update of the MICDET status; if so it will have 3400 * with an update of the MICDET status; if so it will have
3397 * stopped detection and we can ignore this interrupt. 3401 * stopped detection and we can ignore this interrupt.
3398 */ 3402 */
3399 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { 3403 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
3400 mutex_unlock(&wm8994->accdet_lock);
3401 return IRQ_HANDLED; 3404 return IRQ_HANDLED;
3402 }
3403 3405
3404 /* We may occasionally read a detection without an impedence 3406 /* We may occasionally read a detection without an impedence
3405 * range being provided - if that happens loop again. 3407 * range being provided - if that happens loop again.
@@ -3408,7 +3410,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3408 do { 3410 do {
3409 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); 3411 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
3410 if (reg < 0) { 3412 if (reg < 0) {
3411 mutex_unlock(&wm8994->accdet_lock);
3412 dev_err(codec->dev, 3413 dev_err(codec->dev,
3413 "Failed to read mic detect status: %d\n", 3414 "Failed to read mic detect status: %d\n",
3414 reg); 3415 reg);
@@ -3439,8 +3440,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3439 dev_warn(codec->dev, "Accessory detection with no callback\n"); 3440 dev_warn(codec->dev, "Accessory detection with no callback\n");
3440 3441
3441out: 3442out:
3442 mutex_unlock(&wm8994->accdet_lock);
3443
3444 return IRQ_HANDLED; 3443 return IRQ_HANDLED;
3445} 3444}
3446 3445
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 9376b19941b6..40a124c9f15d 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -118,7 +118,6 @@ WM8996_REGULATOR_EVENT(1)
118WM8996_REGULATOR_EVENT(2) 118WM8996_REGULATOR_EVENT(2)
119 119
120static struct reg_default wm8996_reg[] = { 120static struct reg_default wm8996_reg[] = {
121 { WM8996_SOFTWARE_RESET, 0x8996 },
122 { WM8996_POWER_MANAGEMENT_1, 0x0 }, 121 { WM8996_POWER_MANAGEMENT_1, 0x0 },
123 { WM8996_POWER_MANAGEMENT_2, 0x0 }, 122 { WM8996_POWER_MANAGEMENT_2, 0x0 },
124 { WM8996_POWER_MANAGEMENT_3, 0x0 }, 123 { WM8996_POWER_MANAGEMENT_3, 0x0 },
@@ -153,7 +152,6 @@ static struct reg_default wm8996_reg[] = {
153 { WM8996_CHARGE_PUMP_1, 0x1f25 }, 152 { WM8996_CHARGE_PUMP_1, 0x1f25 },
154 { WM8996_CHARGE_PUMP_2, 0xab19 }, 153 { WM8996_CHARGE_PUMP_2, 0xab19 },
155 { WM8996_DC_SERVO_1, 0x0 }, 154 { WM8996_DC_SERVO_1, 0x0 },
156 { WM8996_DC_SERVO_2, 0x0 },
157 { WM8996_DC_SERVO_3, 0x0 }, 155 { WM8996_DC_SERVO_3, 0x0 },
158 { WM8996_DC_SERVO_5, 0x2a2a }, 156 { WM8996_DC_SERVO_5, 0x2a2a },
159 { WM8996_DC_SERVO_6, 0x0 }, 157 { WM8996_DC_SERVO_6, 0x0 },
@@ -892,8 +890,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
892 val = 0; 890 val = 0;
893 mask = 0; 891 mask = 0;
894 if (wm8996->hpout_pending & HPOUT1L) { 892 if (wm8996->hpout_pending & HPOUT1L) {
895 val |= WM8996_HPOUT1L_RMV_SHORT; 893 val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
896 mask |= WM8996_HPOUT1L_RMV_SHORT; 894 mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
897 } else { 895 } else {
898 mask |= WM8996_HPOUT1L_RMV_SHORT | 896 mask |= WM8996_HPOUT1L_RMV_SHORT |
899 WM8996_HPOUT1L_OUTP | 897 WM8996_HPOUT1L_OUTP |
@@ -901,8 +899,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
901 } 899 }
902 900
903 if (wm8996->hpout_pending & HPOUT1R) { 901 if (wm8996->hpout_pending & HPOUT1R) {
904 val |= WM8996_HPOUT1R_RMV_SHORT; 902 val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
905 mask |= WM8996_HPOUT1R_RMV_SHORT; 903 mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
906 } else { 904 } else {
907 mask |= WM8996_HPOUT1R_RMV_SHORT | 905 mask |= WM8996_HPOUT1R_RMV_SHORT |
908 WM8996_HPOUT1R_OUTP | 906 WM8996_HPOUT1R_OUTP |
@@ -914,8 +912,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
914 val = 0; 912 val = 0;
915 mask = 0; 913 mask = 0;
916 if (wm8996->hpout_pending & HPOUT2L) { 914 if (wm8996->hpout_pending & HPOUT2L) {
917 val |= WM8996_HPOUT2L_RMV_SHORT; 915 val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
918 mask |= WM8996_HPOUT2L_RMV_SHORT; 916 mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
919 } else { 917 } else {
920 mask |= WM8996_HPOUT2L_RMV_SHORT | 918 mask |= WM8996_HPOUT2L_RMV_SHORT |
921 WM8996_HPOUT2L_OUTP | 919 WM8996_HPOUT2L_OUTP |
@@ -923,8 +921,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
923 } 921 }
924 922
925 if (wm8996->hpout_pending & HPOUT2R) { 923 if (wm8996->hpout_pending & HPOUT2R) {
926 val |= WM8996_HPOUT2R_RMV_SHORT; 924 val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
927 mask |= WM8996_HPOUT2R_RMV_SHORT; 925 mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
928 } else { 926 } else {
929 mask |= WM8996_HPOUT2R_RMV_SHORT | 927 mask |= WM8996_HPOUT2R_RMV_SHORT |
930 WM8996_HPOUT2R_OUTP | 928 WM8996_HPOUT2R_OUTP |
@@ -1216,7 +1214,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1216SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), 1214SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0),
1217SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, 1215SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start,
1218 SND_SOC_DAPM_POST_PMU), 1216 SND_SOC_DAPM_POST_PMU),
1219SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0),
1220SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, 1217SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1221 rmv_short_event, 1218 rmv_short_event,
1222 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1219 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1225,7 +1222,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1225SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), 1222SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0),
1226SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, 1223SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start,
1227 SND_SOC_DAPM_POST_PMU), 1224 SND_SOC_DAPM_POST_PMU),
1228SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0),
1229SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, 1225SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1230 rmv_short_event, 1226 rmv_short_event,
1231 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1227 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1234,7 +1230,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1234SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), 1230SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0),
1235SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, 1231SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start,
1236 SND_SOC_DAPM_POST_PMU), 1232 SND_SOC_DAPM_POST_PMU),
1237SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0),
1238SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, 1233SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1239 rmv_short_event, 1234 rmv_short_event,
1240 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1235 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1243,7 +1238,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1243SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), 1238SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0),
1244SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, 1239SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start,
1245 SND_SOC_DAPM_POST_PMU), 1240 SND_SOC_DAPM_POST_PMU),
1246SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0),
1247SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, 1241SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1248 rmv_short_event, 1242 rmv_short_event,
1249 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 1243 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1436,32 +1430,28 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1436 { "HPOUT2L PGA", NULL, "DAC2L" }, 1430 { "HPOUT2L PGA", NULL, "DAC2L" },
1437 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1431 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1438 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1432 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1439 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, 1433 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" },
1440 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1441 1434
1442 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1435 { "HPOUT2R PGA", NULL, "Charge Pump" },
1443 { "HPOUT2R PGA", NULL, "Bandgap" }, 1436 { "HPOUT2R PGA", NULL, "Bandgap" },
1444 { "HPOUT2R PGA", NULL, "DAC2R" }, 1437 { "HPOUT2R PGA", NULL, "DAC2R" },
1445 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1438 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1446 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1439 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1447 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, 1440 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" },
1448 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1449 1441
1450 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1442 { "HPOUT1L PGA", NULL, "Charge Pump" },
1451 { "HPOUT1L PGA", NULL, "Bandgap" }, 1443 { "HPOUT1L PGA", NULL, "Bandgap" },
1452 { "HPOUT1L PGA", NULL, "DAC1L" }, 1444 { "HPOUT1L PGA", NULL, "DAC1L" },
1453 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1445 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1454 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1446 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1455 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, 1447 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" },
1456 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1457 1448
1458 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1449 { "HPOUT1R PGA", NULL, "Charge Pump" },
1459 { "HPOUT1R PGA", NULL, "Bandgap" }, 1450 { "HPOUT1R PGA", NULL, "Bandgap" },
1460 { "HPOUT1R PGA", NULL, "DAC1R" }, 1451 { "HPOUT1R PGA", NULL, "DAC1R" },
1461 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1452 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1462 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1453 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1463 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, 1454 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" },
1464 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1465 1455
1466 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, 1456 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1467 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, 1457 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
index 91a28de94109..88143db7e753 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/ep93xx/Kconfig
@@ -1,6 +1,7 @@
1config SND_EP93XX_SOC 1config SND_EP93XX_SOC
2 tristate "SoC Audio support for the Cirrus Logic EP93xx series" 2 tristate "SoC Audio support for the Cirrus Logic EP93xx series"
3 depends on ARCH_EP93XX && SND_SOC 3 depends on ARCH_EP93XX && SND_SOC
4 select SND_SOC_DMAENGINE_PCM
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the EP93xx I2S or AC97 interfaces. 7 the EP93xx I2S or AC97 interfaces.
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 32adca38b48b..162dbb74f4cc 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -23,6 +23,7 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h>
26 27
27#include <mach/dma.h> 28#include <mach/dma.h>
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -52,26 +53,6 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
52 .fifo_size = 32, 53 .fifo_size = 32,
53}; 54};
54 55
55struct ep93xx_runtime_data
56{
57 int pointer_bytes;
58 int periods;
59 int period_bytes;
60 struct dma_chan *dma_chan;
61 struct ep93xx_dma_data dma_data;
62};
63
64static void ep93xx_pcm_dma_callback(void *data)
65{
66 struct snd_pcm_substream *substream = data;
67 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
68
69 rtd->pointer_bytes += rtd->period_bytes;
70 rtd->pointer_bytes %= rtd->period_bytes * rtd->periods;
71
72 snd_pcm_period_elapsed(substream);
73}
74
75static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) 56static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
76{ 57{
77 struct ep93xx_dma_data *data = filter_param; 58 struct ep93xx_dma_data *data = filter_param;
@@ -86,98 +67,48 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
86 67
87static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 68static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
88{ 69{
89 struct snd_soc_pcm_runtime *soc_rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai; 71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 struct ep93xx_pcm_dma_params *dma_params; 72 struct ep93xx_pcm_dma_params *dma_params;
92 struct ep93xx_runtime_data *rtd; 73 struct ep93xx_dma_data *dma_data;
93 dma_cap_mask_t mask;
94 int ret; 74 int ret;
95 75
96 ret = snd_pcm_hw_constraint_integer(substream->runtime,
97 SNDRV_PCM_HW_PARAM_PERIODS);
98 if (ret < 0)
99 return ret;
100
101 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); 76 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
102 77
103 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); 78 dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL);
104 if (!rtd) 79 if (!dma_data)
105 return -ENOMEM; 80 return -ENOMEM;
106 81
107 dma_cap_zero(mask);
108 dma_cap_set(DMA_SLAVE, mask);
109 dma_cap_set(DMA_CYCLIC, mask);
110
111 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); 82 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
112 rtd->dma_data.port = dma_params->dma_port; 83 dma_data->port = dma_params->dma_port;
113 rtd->dma_data.name = dma_params->name; 84 dma_data->name = dma_params->name;
114 85 dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 rtd->dma_data.direction = DMA_MEM_TO_DEV;
117 else
118 rtd->dma_data.direction = DMA_DEV_TO_MEM;
119
120 rtd->dma_chan = dma_request_channel(mask, ep93xx_pcm_dma_filter,
121 &rtd->dma_data);
122 if (!rtd->dma_chan) {
123 kfree(rtd);
124 return -EINVAL;
125 }
126
127 substream->runtime->private_data = rtd;
128 return 0;
129}
130 86
131static int ep93xx_pcm_close(struct snd_pcm_substream *substream) 87 ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
132{ 88 if (ret) {
133 struct ep93xx_runtime_data *rtd = substream->runtime->private_data; 89 kfree(dma_data);
90 return ret;
91 }
134 92
135 dma_release_channel(rtd->dma_chan); 93 snd_dmaengine_pcm_set_data(substream, dma_data);
136 kfree(rtd);
137 return 0;
138}
139 94
140static int ep93xx_pcm_dma_submit(struct snd_pcm_substream *substream)
141{
142 struct snd_pcm_runtime *runtime = substream->runtime;
143 struct ep93xx_runtime_data *rtd = runtime->private_data;
144 struct dma_chan *chan = rtd->dma_chan;
145 struct dma_device *dma_dev = chan->device;
146 struct dma_async_tx_descriptor *desc;
147
148 rtd->pointer_bytes = 0;
149 desc = dma_dev->device_prep_dma_cyclic(chan, runtime->dma_addr,
150 rtd->period_bytes * rtd->periods,
151 rtd->period_bytes,
152 rtd->dma_data.direction);
153 if (!desc)
154 return -EINVAL;
155
156 desc->callback = ep93xx_pcm_dma_callback;
157 desc->callback_param = substream;
158
159 dmaengine_submit(desc);
160 return 0; 95 return 0;
161} 96}
162 97
163static void ep93xx_pcm_dma_flush(struct snd_pcm_substream *substream) 98static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
164{ 99{
165 struct snd_pcm_runtime *runtime = substream->runtime; 100 struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
166 struct ep93xx_runtime_data *rtd = runtime->private_data;
167 101
168 dmaengine_terminate_all(rtd->dma_chan); 102 snd_dmaengine_pcm_close(substream);
103 kfree(dma_data);
104 return 0;
169} 105}
170 106
171static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, 107static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
172 struct snd_pcm_hw_params *params) 108 struct snd_pcm_hw_params *params)
173{ 109{
174 struct snd_pcm_runtime *runtime = substream->runtime;
175 struct ep93xx_runtime_data *rtd = runtime->private_data;
176
177 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 110 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
178 111
179 rtd->periods = params_periods(params);
180 rtd->period_bytes = params_period_bytes(params);
181 return 0; 112 return 0;
182} 113}
183 114
@@ -187,41 +118,6 @@ static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
187 return 0; 118 return 0;
188} 119}
189 120
190static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
191{
192 int ret;
193
194 ret = 0;
195 switch (cmd) {
196 case SNDRV_PCM_TRIGGER_START:
197 case SNDRV_PCM_TRIGGER_RESUME:
198 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
199 ret = ep93xx_pcm_dma_submit(substream);
200 break;
201
202 case SNDRV_PCM_TRIGGER_STOP:
203 case SNDRV_PCM_TRIGGER_SUSPEND:
204 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
205 ep93xx_pcm_dma_flush(substream);
206 break;
207
208 default:
209 ret = -EINVAL;
210 break;
211 }
212
213 return ret;
214}
215
216static snd_pcm_uframes_t ep93xx_pcm_pointer(struct snd_pcm_substream *substream)
217{
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
220
221 /* FIXME: implement this with sub-period granularity */
222 return bytes_to_frames(runtime, rtd->pointer_bytes);
223}
224
225static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, 121static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
226 struct vm_area_struct *vma) 122 struct vm_area_struct *vma)
227{ 123{
@@ -239,8 +135,8 @@ static struct snd_pcm_ops ep93xx_pcm_ops = {
239 .ioctl = snd_pcm_lib_ioctl, 135 .ioctl = snd_pcm_lib_ioctl,
240 .hw_params = ep93xx_pcm_hw_params, 136 .hw_params = ep93xx_pcm_hw_params,
241 .hw_free = ep93xx_pcm_hw_free, 137 .hw_free = ep93xx_pcm_hw_free,
242 .trigger = ep93xx_pcm_trigger, 138 .trigger = snd_dmaengine_pcm_trigger,
243 .pointer = ep93xx_pcm_pointer, 139 .pointer = snd_dmaengine_pcm_pointer,
244 .mmap = ep93xx_pcm_mmap, 140 .mmap = ep93xx_pcm_mmap,
245}; 141};
246 142
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 3e066966d878..2eb407fa3b48 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -716,12 +716,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
716 } 716 }
717 717
718 /* Trigger the machine driver's probe function. The platform driver 718 /* Trigger the machine driver's probe function. The platform driver
719 * name of the machine driver is taken from the /model property of the 719 * name of the machine driver is taken from /compatible property of the
720 * device tree. We also pass the address of the CPU DAI driver 720 * device tree. We also pass the address of the CPU DAI driver
721 * structure. 721 * structure.
722 */ 722 */
723 sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); 723 sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
724 /* Sometimes the model name has a "fsl," prefix, so we strip that. */ 724 /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
725 p = strrchr(sprop, ','); 725 p = strrchr(sprop, ',');
726 if (p) 726 if (p)
727 sprop = p + 1; 727 sprop = p + 1;
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index fcf9302f59b4..afbabf427f27 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -546,7 +546,7 @@ static struct platform_driver mpc8610_hpcd_driver = {
546 .probe = mpc8610_hpcd_probe, 546 .probe = mpc8610_hpcd_probe,
547 .remove = __devexit_p(mpc8610_hpcd_remove), 547 .remove = __devexit_p(mpc8610_hpcd_remove),
548 .driver = { 548 .driver = {
549 /* The name must match the 'model' property in the device tree, 549 /* The name must match 'compatible' property in the device tree,
550 * in lowercase letters. 550 * in lowercase letters.
551 */ 551 */
552 .name = "snd-soc-mpc8610hpcd", 552 .name = "snd-soc-mpc8610hpcd",
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index d32ec4646d25..b88987083475 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -543,6 +543,11 @@ static struct platform_driver p1022_ds_driver = {
543 .probe = p1022_ds_probe, 543 .probe = p1022_ds_probe,
544 .remove = __devexit_p(p1022_ds_remove), 544 .remove = __devexit_p(p1022_ds_remove),
545 .driver = { 545 .driver = {
546 /*
547 * The name must match 'compatible' property in the device tree,
548 * in lowercase letters.
549 */
550 .name = "snd-soc-p1022ds",
546 .owner = THIS_MODULE, 551 .owner = THIS_MODULE,
547 }, 552 },
548}; 553};
@@ -556,33 +561,6 @@ static int __init p1022_ds_init(void)
556{ 561{
557 struct device_node *guts_np; 562 struct device_node *guts_np;
558 struct resource res; 563 struct resource res;
559 const char *sprop;
560
561 /*
562 * Check if we're actually running on a P1022DS. Older device trees
563 * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we
564 * need to support both. The SSI driver uses that property to link to
565 * the machine driver, so have to match it.
566 */
567 sprop = of_get_property(of_find_node_by_path("/"), "model", NULL);
568 if (!sprop) {
569 pr_err("snd-soc-p1022ds: missing /model node");
570 return -ENODEV;
571 }
572
573 pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop);
574
575 /*
576 * The name of this board, taken from the device tree. Normally, this is a*
577 * fixed string, but some P1022DS device trees have a /model property of
578 * "fsl,P1022", and others have "fsl,P1022DS".
579 */
580 if (strcasecmp(sprop, "fsl,p1022ds") == 0)
581 p1022_ds_driver.driver.name = "snd-soc-p1022ds";
582 else if (strcasecmp(sprop, "fsl,p1022") == 0)
583 p1022_ds_driver.driver.name = "snd-soc-p1022";
584 else
585 return -ENODEV;
586 564
587 /* Get the physical address of the global utilities registers */ 565 /* Get the physical address of the global utilities registers */
588 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); 566 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c
index b83699d905bb..a839494c5ea8 100644
--- a/sound/soc/imx/imx-audmux.c
+++ b/sound/soc/imx/imx-audmux.c
@@ -167,7 +167,7 @@ static void __init audmux_debugfs_init(void)
167 } 167 }
168} 168}
169 169
170static void __exit audmux_debugfs_remove(void) 170static void __devexit audmux_debugfs_remove(void)
171{ 171{
172 debugfs_remove_recursive(audmux_debugfs_root); 172 debugfs_remove_recursive(audmux_debugfs_root);
173} 173}
@@ -249,7 +249,7 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
249} 249}
250EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); 250EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
251 251
252static int __init imx_audmux_probe(struct platform_device *pdev) 252static int __devinit imx_audmux_probe(struct platform_device *pdev)
253{ 253{
254 struct resource *res; 254 struct resource *res;
255 const struct of_device_id *of_id = 255 const struct of_device_id *of_id =
@@ -276,7 +276,7 @@ static int __init imx_audmux_probe(struct platform_device *pdev)
276 return 0; 276 return 0;
277} 277}
278 278
279static int __exit imx_audmux_remove(struct platform_device *pdev) 279static int __devexit imx_audmux_remove(struct platform_device *pdev)
280{ 280{
281 if (audmux_type == IMX31_AUDMUX) 281 if (audmux_type == IMX31_AUDMUX)
282 audmux_debugfs_remove(); 282 audmux_debugfs_remove();
@@ -287,7 +287,7 @@ static int __exit imx_audmux_remove(struct platform_device *pdev)
287 287
288static struct platform_driver imx_audmux_driver = { 288static struct platform_driver imx_audmux_driver = {
289 .probe = imx_audmux_probe, 289 .probe = imx_audmux_probe,
290 .remove = __exit_p(imx_audmux_remove), 290 .remove = __devexit_p(imx_audmux_remove),
291 .id_table = imx_audmux_ids, 291 .id_table = imx_audmux_ids,
292 .driver = { 292 .driver = {
293 .name = DRIVER_NAME, 293 .name = DRIVER_NAME,
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
index 976f857151f0..f6d04ad4bb39 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -188,22 +188,16 @@ static struct snd_soc_card mx27vis_aic32x4 = {
188 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), 188 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
189}; 189};
190 190
191static struct platform_device *mx27vis_aic32x4_snd_device; 191static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
192
193static int __init mx27vis_aic32x4_init(void)
194{ 192{
195 int ret; 193 int ret;
196 194
197 mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1); 195 mx27vis_aic32x4.dev = &pdev->dev;
198 if (!mx27vis_aic32x4_snd_device) 196 ret = snd_soc_register_card(&mx27vis_aic32x4);
199 return -ENOMEM;
200
201 platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
202 ret = platform_device_add(mx27vis_aic32x4_snd_device);
203
204 if (ret) { 197 if (ret) {
205 printk(KERN_ERR "ASoC: Platform device allocation failed\n"); 198 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
206 platform_device_put(mx27vis_aic32x4_snd_device); 199 ret);
200 return ret;
207 } 201 }
208 202
209 /* Connect SSI0 as clock slave to SSI1 external pins */ 203 /* Connect SSI0 as clock slave to SSI1 external pins */
@@ -221,22 +215,31 @@ static int __init mx27vis_aic32x4_init(void)
221 215
222 ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, 216 ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
223 ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP"); 217 ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
224 if (ret) { 218 if (ret)
225 printk(KERN_ERR "ASoC: unable to setup gpios\n"); 219 printk(KERN_ERR "ASoC: unable to setup gpios\n");
226 platform_device_put(mx27vis_aic32x4_snd_device);
227 }
228 220
229 return ret; 221 return ret;
230} 222}
231 223
232static void __exit mx27vis_aic32x4_exit(void) 224static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
233{ 225{
234 platform_device_unregister(mx27vis_aic32x4_snd_device); 226 snd_soc_unregister_card(&mx27vis_aic32x4);
227
228 return 0;
235} 229}
236 230
237module_init(mx27vis_aic32x4_init); 231static struct platform_driver mx27vis_aic32x4_audio_driver = {
238module_exit(mx27vis_aic32x4_exit); 232 .driver = {
233 .name = "mx27vis",
234 .owner = THIS_MODULE,
235 },
236 .probe = mx27vis_aic32x4_probe,
237 .remove = __devexit_p(mx27vis_aic32x4_remove),
238};
239
240module_platform_driver(mx27vis_aic32x4_audio_driver);
239 241
240MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); 242MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
241MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim"); 243MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
242MODULE_LICENSE("GPL"); 244MODULE_LICENSE("GPL");
245MODULE_ALIAS("platform:mx27vis");
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a57cfbc038e3..a16df0fa6eff 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -764,7 +764,8 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai)
764 764
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
766 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 766 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
767 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 767 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
768 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
768 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 769 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
769 770
770#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 771#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7978f6c01ef7..93a0daac5088 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1531,14 +1531,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1531 if (dai_link->dai_fmt) { 1531 if (dai_link->dai_fmt) {
1532 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, 1532 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
1533 dai_link->dai_fmt); 1533 dai_link->dai_fmt);
1534 if (ret != 0) 1534 if (ret != 0 && ret != -ENOTSUPP)
1535 dev_warn(card->rtd[i].codec_dai->dev, 1535 dev_warn(card->rtd[i].codec_dai->dev,
1536 "Failed to set DAI format: %d\n", 1536 "Failed to set DAI format: %d\n",
1537 ret); 1537 ret);
1538 1538
1539 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, 1539 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1540 dai_link->dai_fmt); 1540 dai_link->dai_fmt);
1541 if (ret != 0) 1541 if (ret != 0 && ret != -ENOTSUPP)
1542 dev_warn(card->rtd[i].cpu_dai->dev, 1542 dev_warn(card->rtd[i].cpu_dai->dev,
1543 "Failed to set DAI format: %d\n", 1543 "Failed to set DAI format: %d\n",
1544 ret); 1544 ret);
@@ -2971,10 +2971,11 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
2971 */ 2971 */
2972int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2972int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2973{ 2973{
2974 if (dai->driver && dai->driver->ops->set_fmt) 2974 if (dai->driver == NULL)
2975 return dai->driver->ops->set_fmt(dai, fmt);
2976 else
2977 return -EINVAL; 2975 return -EINVAL;
2976 if (dai->driver->ops->set_fmt == NULL)
2977 return -ENOTSUPP;
2978 return dai->driver->ops->set_fmt(dai, fmt);
2978} 2979}
2979EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); 2980EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2980 2981
@@ -3382,6 +3383,7 @@ int snd_soc_register_platform(struct device *dev,
3382 platform->dapm.dev = dev; 3383 platform->dapm.dev = dev;
3383 platform->dapm.platform = platform; 3384 platform->dapm.platform = platform;
3384 platform->dapm.stream_event = platform_drv->stream_event; 3385 platform->dapm.stream_event = platform_drv->stream_event;
3386 mutex_init(&platform->mutex);
3385 3387
3386 mutex_lock(&client_mutex); 3388 mutex_lock(&client_mutex);
3387 list_add(&platform->list, &platform_list); 3389 list_add(&platform->list, &platform_list);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a4d4aa1e6c49..dcd11609f930 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1667,7 +1667,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1667 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 1667 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1668 1668
1669 if (!dapm->debugfs_dapm) { 1669 if (!dapm->debugfs_dapm) {
1670 printk(KERN_WARNING 1670 dev_warn(dapm->dev,
1671 "Failed to create DAPM debugfs directory\n"); 1671 "Failed to create DAPM debugfs directory\n");
1672 return; 1672 return;
1673 } 1673 }
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 0526cf82b54f..4420b7030c83 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -142,6 +142,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
142 142
143 direction = snd_pcm_substream_to_dma_direction(substream); 143 direction = snd_pcm_substream_to_dma_direction(substream);
144 144
145 prtd->pos = 0;
145 desc = chan->device->device_prep_dma_cyclic(chan, 146 desc = chan->device->device_prep_dma_cyclic(chan,
146 substream->runtime->dma_addr, 147 substream->runtime->dma_addr,
147 snd_pcm_lib_buffer_bytes(substream), 148 snd_pcm_lib_buffer_bytes(substream),
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 2a27725cc9b1..e45ccd851f6a 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -115,7 +115,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
115 struct snd_soc_dapm_context *dapm = &codec->dapm; 115 struct snd_soc_dapm_context *dapm = &codec->dapm;
116 struct device_node *np = codec->card->dev->of_node; 116 struct device_node *np = codec->card->dev->of_node;
117 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); 117 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
118 int ret;
119 118
120 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 119 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
121 &tegra_alc5632_hs_jack); 120 &tegra_alc5632_hs_jack);