aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-09-22 03:56:12 -0400
committerTakashi Iwai <tiwai@suse.de>2011-09-22 03:56:12 -0400
commitaf1910a817c5ad52c32dddacc1744cfa1b35889e (patch)
tree2d6504a2ac5971bb84e0172bbdd309b781048849 /sound/soc
parent5495ffbd7b56d8bffebc5e30f03ea374590f1bb4 (diff)
parentf648de832dbf6d1947ce5a7c0ed24a3a71d8545b (diff)
Merge branch 'topic/asoc' into topic/remove-irqf_disable
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c5
-rw-r--r--sound/soc/au1x/Kconfig28
-rw-r--r--sound/soc/au1x/Makefile10
-rw-r--r--sound/soc/au1x/ac97c.c363
-rw-r--r--sound/soc/au1x/db1000.c75
-rw-r--r--sound/soc/au1x/db1200.c64
-rw-r--r--sound/soc/au1x/dbdma2.c91
-rw-r--r--sound/soc/au1x/dma.c377
-rw-r--r--sound/soc/au1x/i2sc.c346
-rw-r--r--sound/soc/au1x/psc-ac97.c48
-rw-r--r--sound/soc/au1x/psc-i2s.c42
-rw-r--r--sound/soc/au1x/psc.h16
-rw-r--r--sound/soc/blackfin/Kconfig13
-rw-r--r--sound/soc/blackfin/Makefile2
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c2
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c202
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ad193x.c65
-rw-r--r--sound/soc/codecs/ad193x.h34
-rw-r--r--sound/soc/codecs/ad1980.c10
-rw-r--r--sound/soc/codecs/adau1373.c1414
-rw-r--r--sound/soc/codecs/adau1373.h29
-rw-r--r--sound/soc/codecs/adav80x.c3
-rw-r--r--sound/soc/codecs/alc5623.c2
-rw-r--r--sound/soc/codecs/sgtl5000.c8
-rw-r--r--sound/soc/codecs/sn95031.c10
-rw-r--r--sound/soc/codecs/ssm2602.c3
-rw-r--r--sound/soc/codecs/sta32x.c21
-rw-r--r--sound/soc/codecs/tpa6130a2.c1
-rw-r--r--sound/soc/codecs/twl6040.c114
-rw-r--r--sound/soc/codecs/wm1250-ev1.c20
-rw-r--r--sound/soc/codecs/wm8510.c8
-rw-r--r--sound/soc/codecs/wm8523.c35
-rw-r--r--sound/soc/codecs/wm8580.c9
-rw-r--r--sound/soc/codecs/wm8711.c13
-rw-r--r--sound/soc/codecs/wm8728.c13
-rw-r--r--sound/soc/codecs/wm8731.c10
-rw-r--r--sound/soc/codecs/wm8737.c10
-rw-r--r--sound/soc/codecs/wm8741.c135
-rw-r--r--sound/soc/codecs/wm8750.c14
-rw-r--r--sound/soc/codecs/wm8753.c13
-rw-r--r--sound/soc/codecs/wm8770.c8
-rw-r--r--sound/soc/codecs/wm8776.c51
-rw-r--r--sound/soc/codecs/wm8804.c9
-rw-r--r--sound/soc/codecs/wm8962.c213
-rw-r--r--sound/soc/codecs/wm8993.c7
-rw-r--r--sound/soc/codecs/wm8994-tables.c16
-rw-r--r--sound/soc/codecs/wm8994.c270
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm8995.c3
-rw-r--r--sound/soc/codecs/wm8996.c310
-rw-r--r--sound/soc/codecs/wm9081.c4
-rw-r--r--sound/soc/codecs/wm9090.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c48
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-mcasp.c20
-rw-r--r--sound/soc/davinci/davinci-pcm.c123
-rw-r--r--sound/soc/ep93xx/edb93xx.c60
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c1
-rw-r--r--sound/soc/ep93xx/simone.c64
-rw-r--r--sound/soc/ep93xx/snappercl15.c53
-rw-r--r--sound/soc/fsl/fsl_dma.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c206
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c4
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c11
-rw-r--r--sound/soc/imx/imx-ssi.c8
-rw-r--r--sound/soc/mid-x86/sst_platform.c17
-rw-r--r--sound/soc/mxs/Kconfig20
-rw-r--r--sound/soc/mxs/Makefile10
-rw-r--r--sound/soc/mxs/mxs-pcm.c359
-rw-r--r--sound/soc/mxs/mxs-pcm.h43
-rw-r--r--sound/soc/mxs/mxs-saif.c797
-rw-r--r--sound/soc/mxs/mxs-saif.h134
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c173
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c1
-rw-r--r--sound/soc/pxa/raumfeld.c4
-rw-r--r--sound/soc/pxa/spitz.c2
-rw-r--r--sound/soc/pxa/z2.c2
-rw-r--r--sound/soc/s6000/s6000-pcm.c1
-rw-r--r--sound/soc/samsung/Kconfig6
-rw-r--r--sound/soc/samsung/jive_wm8750.c2
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c4
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c4
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c8
-rw-r--r--sound/soc/samsung/smartq_wm8987.c2
-rw-r--r--sound/soc/samsung/smdk_wm8580.c6
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c4
-rw-r--r--sound/soc/samsung/speyside.c10
-rw-r--r--sound/soc/samsung/speyside_wm8962.c4
-rw-r--r--sound/soc/soc-cache.c7
-rw-r--r--sound/soc/soc-core.c20
-rw-r--r--sound/soc/soc-dapm.c16
-rw-r--r--sound/soc/soc-io.c357
-rw-r--r--sound/soc/soc-pcm.c2
98 files changed, 6028 insertions, 1174 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 8224db5f043..1381db853ef 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -7,6 +7,8 @@ menuconfig SND_SOC
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS 8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER
10 ---help--- 12 ---help---
11 13
12 If you want ASoC support, you should say Y here and also to the 14 If you want ASoC support, you should say Y here and also to the
@@ -51,6 +53,7 @@ source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 53source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 54source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/mid-x86/Kconfig" 55source "sound/soc/mid-x86/Kconfig"
56source "sound/soc/mxs/Kconfig"
54source "sound/soc/pxa/Kconfig" 57source "sound/soc/pxa/Kconfig"
55source "sound/soc/samsung/Kconfig" 58source "sound/soc/samsung/Kconfig"
56source "sound/soc/s6000/Kconfig" 59source "sound/soc/s6000/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 4f913876f33..9ea8ac827ad 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC) += fsl/
12obj-$(CONFIG_SND_SOC) += imx/ 12obj-$(CONFIG_SND_SOC) += imx/
13obj-$(CONFIG_SND_SOC) += jz4740/ 13obj-$(CONFIG_SND_SOC) += jz4740/
14obj-$(CONFIG_SND_SOC) += mid-x86/ 14obj-$(CONFIG_SND_SOC) += mid-x86/
15obj-$(CONFIG_SND_SOC) += mxs/
15obj-$(CONFIG_SND_SOC) += nuc900/ 16obj-$(CONFIG_SND_SOC) += nuc900/
16obj-$(CONFIG_SND_SOC) += omap/ 17obj-$(CONFIG_SND_SOC) += omap/
17obj-$(CONFIG_SND_SOC) += kirkwood/ 18obj-$(CONFIG_SND_SOC) += kirkwood/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 1aac2f4dbcf..2909bfaed26 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -383,14 +383,17 @@ static int __init playpaq_asoc_init(void)
383 _gclk0 = clk_get(NULL, "gclk0"); 383 _gclk0 = clk_get(NULL, "gclk0");
384 if (IS_ERR(_gclk0)) { 384 if (IS_ERR(_gclk0)) {
385 _gclk0 = NULL; 385 _gclk0 = NULL;
386 ret = PTR_ERR(_gclk0);
386 goto err_gclk0; 387 goto err_gclk0;
387 } 388 }
388 _pll0 = clk_get(NULL, "pll0"); 389 _pll0 = clk_get(NULL, "pll0");
389 if (IS_ERR(_pll0)) { 390 if (IS_ERR(_pll0)) {
390 _pll0 = NULL; 391 _pll0 = NULL;
392 ret = PTR_ERR(_pll0);
391 goto err_pll0; 393 goto err_pll0;
392 } 394 }
393 if (clk_set_parent(_gclk0, _pll0)) { 395 ret = clk_set_parent(_gclk0, _pll0);
396 if (ret) {
394 pr_warning("snd-soc-playpaq: " 397 pr_warning("snd-soc-playpaq: "
395 "Failed to set PLL0 as parent for DAC clock\n"); 398 "Failed to set PLL0 as parent for DAC clock\n");
396 goto err_set_clk; 399 goto err_set_clk;
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index 4b67140fdec..6d592546e8f 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -18,10 +18,38 @@ config SND_SOC_AU1XPSC_AC97
18 select SND_AC97_CODEC 18 select SND_AC97_CODEC
19 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
20 20
21##
22## Au1000/1500/1100 DMA + AC97C/I2SC
23##
24config SND_SOC_AU1XAUDIO
25 tristate "SoC Audio for Au1000/Au1500/Au1100"
26 depends on MIPS_ALCHEMY
27 help
28 This is a driver set for the AC97 unit and the
29 old DMA controller as found on the Au1000/Au1500/Au1100 chips.
30
31config SND_SOC_AU1XAC97C
32 tristate
33 select AC97_BUS
34 select SND_AC97_CODEC
35 select SND_SOC_AC97_BUS
36
37config SND_SOC_AU1XI2SC
38 tristate
39
21 40
22## 41##
23## Boards 42## Boards
24## 43##
44config SND_SOC_DB1000
45 tristate "DB1000 Audio support"
46 depends on SND_SOC_AU1XAUDIO
47 select SND_SOC_AU1XAC97C
48 select SND_SOC_AC97_CODEC
49 help
50 Select this option to enable AC97 audio on the early DB1x00 series
51 of boards (DB1000/DB1500/DB1100).
52
25config SND_SOC_DB1200 53config SND_SOC_DB1200
26 tristate "DB1200 AC97+I2S audio support" 54 tristate "DB1200 AC97+I2S audio support"
27 depends on SND_SOC_AU1XPSC 55 depends on SND_SOC_AU1XPSC
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 16873076e8c..920710514ea 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -3,11 +3,21 @@ snd-soc-au1xpsc-dbdma-objs := dbdma2.o
3snd-soc-au1xpsc-i2s-objs := psc-i2s.o 3snd-soc-au1xpsc-i2s-objs := psc-i2s.o
4snd-soc-au1xpsc-ac97-objs := psc-ac97.o 4snd-soc-au1xpsc-ac97-objs := psc-ac97.o
5 5
6# Au1000/1500/1100 Audio units
7snd-soc-au1x-dma-objs := dma.o
8snd-soc-au1x-ac97c-objs := ac97c.o
9snd-soc-au1x-i2sc-objs := i2sc.o
10
6obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o 11obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
7obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o 12obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o 13obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
14obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o
15obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o
16obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o
9 17
10# Boards 18# Boards
19snd-soc-db1000-objs := db1000.o
11snd-soc-db1200-objs := db1200.o 20snd-soc-db1200-objs := db1200.o
12 21
22obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o
13obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o 23obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
new file mode 100644
index 00000000000..13802ff7cf0
--- /dev/null
+++ b/sound/soc/au1x/ac97c.c
@@ -0,0 +1,363 @@
1/*
2 * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * based on the old ALSA driver originally written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/device.h>
14#include <linux/delay.h>
15#include <linux/mutex.h>
16#include <linux/platform_device.h>
17#include <linux/suspend.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22#include <asm/mach-au1x00/au1000.h>
23
24#include "psc.h"
25
26/* register offsets and bits */
27#define AC97_CONFIG 0x00
28#define AC97_STATUS 0x04
29#define AC97_DATA 0x08
30#define AC97_CMDRESP 0x0c
31#define AC97_ENABLE 0x10
32
33#define CFG_RC(x) (((x) & 0x3ff) << 13) /* valid rx slots mask */
34#define CFG_XS(x) (((x) & 0x3ff) << 3) /* valid tx slots mask */
35#define CFG_SG (1 << 2) /* sync gate */
36#define CFG_SN (1 << 1) /* sync control */
37#define CFG_RS (1 << 0) /* acrst# control */
38#define STAT_XU (1 << 11) /* tx underflow */
39#define STAT_XO (1 << 10) /* tx overflow */
40#define STAT_RU (1 << 9) /* rx underflow */
41#define STAT_RO (1 << 8) /* rx overflow */
42#define STAT_RD (1 << 7) /* codec ready */
43#define STAT_CP (1 << 6) /* command pending */
44#define STAT_TE (1 << 4) /* tx fifo empty */
45#define STAT_TF (1 << 3) /* tx fifo full */
46#define STAT_RE (1 << 1) /* rx fifo empty */
47#define STAT_RF (1 << 0) /* rx fifo full */
48#define CMD_SET_DATA(x) (((x) & 0xffff) << 16)
49#define CMD_GET_DATA(x) ((x) & 0xffff)
50#define CMD_READ (1 << 7)
51#define CMD_WRITE (0 << 7)
52#define CMD_IDX(x) ((x) & 0x7f)
53#define EN_D (1 << 1) /* DISable bit */
54#define EN_CE (1 << 0) /* clock enable bit */
55
56/* how often to retry failed codec register reads/writes */
57#define AC97_RW_RETRIES 5
58
59#define AC97_RATES \
60 SNDRV_PCM_RATE_CONTINUOUS
61
62#define AC97_FMTS \
63 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
64
65/* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
66 * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
67 */
68static struct au1xpsc_audio_data *ac97c_workdata;
69#define ac97_to_ctx(x) ac97c_workdata
70
71static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
72{
73 return __raw_readl(ctx->mmio + reg);
74}
75
76static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
77{
78 __raw_writel(v, ctx->mmio + reg);
79 wmb();
80}
81
82static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
83 unsigned short r)
84{
85 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
86 unsigned int tmo, retry;
87 unsigned long data;
88
89 data = ~0;
90 retry = AC97_RW_RETRIES;
91 do {
92 mutex_lock(&ctx->lock);
93
94 tmo = 5;
95 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
96 udelay(21); /* wait an ac97 frame time */
97 if (!tmo) {
98 pr_debug("ac97rd timeout #1\n");
99 goto next;
100 }
101
102 WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
103
104 /* stupid errata: data is only valid for 21us, so
105 * poll, Forrest, poll...
106 */
107 tmo = 0x10000;
108 while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
109 asm volatile ("nop");
110 data = RD(ctx, AC97_CMDRESP);
111
112 if (!tmo)
113 pr_debug("ac97rd timeout #2\n");
114
115next:
116 mutex_unlock(&ctx->lock);
117 } while (--retry && !tmo);
118
119 pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
120
121 return retry ? data & 0xffff : 0xffff;
122}
123
124static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
125 unsigned short v)
126{
127 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
128 unsigned int tmo, retry;
129
130 retry = AC97_RW_RETRIES;
131 do {
132 mutex_lock(&ctx->lock);
133
134 for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
135 udelay(21);
136 if (!tmo) {
137 pr_debug("ac97wr timeout #1\n");
138 goto next;
139 }
140
141 WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
142
143 for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
144 udelay(21);
145 if (!tmo)
146 pr_debug("ac97wr timeout #2\n");
147next:
148 mutex_unlock(&ctx->lock);
149 } while (--retry && !tmo);
150
151 pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
152}
153
154static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
155{
156 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
157
158 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
159 msleep(20);
160 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
161 WR(ctx, AC97_CONFIG, ctx->cfg);
162}
163
164static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
167 int i;
168
169 WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
170 msleep(500);
171 WR(ctx, AC97_CONFIG, ctx->cfg);
172
173 /* wait for codec ready */
174 i = 50;
175 while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
176 msleep(20);
177 if (!i)
178 printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
179}
180
181/* AC97 controller operations */
182struct snd_ac97_bus_ops soc_ac97_ops = {
183 .read = au1xac97c_ac97_read,
184 .write = au1xac97c_ac97_write,
185 .reset = au1xac97c_ac97_cold_reset,
186 .warm_reset = au1xac97c_ac97_warm_reset,
187};
188EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189
190static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
194 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
195 return 0;
196}
197
198static struct snd_soc_dai_ops alchemy_ac97c_ops = {
199 .startup = alchemy_ac97c_startup,
200};
201
202static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
203{
204 return ac97c_workdata ? 0 : -ENODEV;
205}
206
207static struct snd_soc_dai_driver au1xac97c_dai_driver = {
208 .name = "alchemy-ac97c",
209 .ac97_control = 1,
210 .probe = au1xac97c_dai_probe,
211 .playback = {
212 .rates = AC97_RATES,
213 .formats = AC97_FMTS,
214 .channels_min = 2,
215 .channels_max = 2,
216 },
217 .capture = {
218 .rates = AC97_RATES,
219 .formats = AC97_FMTS,
220 .channels_min = 2,
221 .channels_max = 2,
222 },
223 .ops = &alchemy_ac97c_ops,
224};
225
226static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
227{
228 int ret;
229 struct resource *r;
230 struct au1xpsc_audio_data *ctx;
231
232 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
233 if (!ctx)
234 return -ENOMEM;
235
236 mutex_init(&ctx->lock);
237
238 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!r) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(r->start, resource_size(r), pdev->name))
246 goto out0;
247
248 ctx->mmio = ioremap_nocache(r->start, resource_size(r));
249 if (!ctx->mmio)
250 goto out1;
251
252 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
253 if (!r)
254 goto out1;
255 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
256
257 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
258 if (!r)
259 goto out1;
260 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
261
262 /* switch it on */
263 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
264 WR(ctx, AC97_ENABLE, EN_CE);
265
266 ctx->cfg = CFG_RC(3) | CFG_XS(3);
267 WR(ctx, AC97_CONFIG, ctx->cfg);
268
269 platform_set_drvdata(pdev, ctx);
270
271 ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
272 if (ret)
273 goto out1;
274
275 ac97c_workdata = ctx;
276 return 0;
277
278out1:
279 release_mem_region(r->start, resource_size(r));
280out0:
281 kfree(ctx);
282 return ret;
283}
284
285static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
286{
287 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
288 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
289
290 snd_soc_unregister_dai(&pdev->dev);
291
292 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
293
294 iounmap(ctx->mmio);
295 release_mem_region(r->start, resource_size(r));
296 kfree(ctx);
297
298 ac97c_workdata = NULL; /* MDEV */
299
300 return 0;
301}
302
303#ifdef CONFIG_PM
304static int au1xac97c_drvsuspend(struct device *dev)
305{
306 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
307
308 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
309
310 return 0;
311}
312
313static int au1xac97c_drvresume(struct device *dev)
314{
315 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
316
317 WR(ctx, AC97_ENABLE, EN_D | EN_CE);
318 WR(ctx, AC97_ENABLE, EN_CE);
319 WR(ctx, AC97_CONFIG, ctx->cfg);
320
321 return 0;
322}
323
324static const struct dev_pm_ops au1xpscac97_pmops = {
325 .suspend = au1xac97c_drvsuspend,
326 .resume = au1xac97c_drvresume,
327};
328
329#define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
330
331#else
332
333#define AU1XPSCAC97_PMOPS NULL
334
335#endif
336
337static struct platform_driver au1xac97c_driver = {
338 .driver = {
339 .name = "alchemy-ac97c",
340 .owner = THIS_MODULE,
341 .pm = AU1XPSCAC97_PMOPS,
342 },
343 .probe = au1xac97c_drvprobe,
344 .remove = __devexit_p(au1xac97c_drvremove),
345};
346
347static int __init au1xac97c_load(void)
348{
349 ac97c_workdata = NULL;
350 return platform_driver_register(&au1xac97c_driver);
351}
352
353static void __exit au1xac97c_unload(void)
354{
355 platform_driver_unregister(&au1xac97c_driver);
356}
357
358module_init(au1xac97c_load);
359module_exit(au1xac97c_unload);
360
361MODULE_LICENSE("GPL");
362MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
363MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
new file mode 100644
index 00000000000..127477a5e0c
--- /dev/null
+++ b/sound/soc/au1x/db1000.c
@@ -0,0 +1,75 @@
1/*
2 * DB1000/DB1500/DB1100 ASoC audio fabric support code.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <asm/mach-au1x00/au1000.h>
17#include <asm/mach-db1x00/bcsr.h>
18
19#include "psc.h"
20
21static struct snd_soc_dai_link db1000_ac97_dai = {
22 .name = "AC97",
23 .stream_name = "AC97 HiFi",
24 .codec_dai_name = "ac97-hifi",
25 .cpu_dai_name = "alchemy-ac97c",
26 .platform_name = "alchemy-pcm-dma.0",
27 .codec_name = "ac97-codec",
28};
29
30static struct snd_soc_card db1000_ac97 = {
31 .name = "DB1000_AC97",
32 .dai_link = &db1000_ac97_dai,
33 .num_links = 1,
34};
35
36static int __devinit db1000_audio_probe(struct platform_device *pdev)
37{
38 struct snd_soc_card *card = &db1000_ac97;
39 card->dev = &pdev->dev;
40 return snd_soc_register_card(card);
41}
42
43static int __devexit db1000_audio_remove(struct platform_device *pdev)
44{
45 struct snd_soc_card *card = platform_get_drvdata(pdev);
46 snd_soc_unregister_card(card);
47 return 0;
48}
49
50static struct platform_driver db1000_audio_driver = {
51 .driver = {
52 .name = "db1000-audio",
53 .owner = THIS_MODULE,
54 .pm = &snd_soc_pm_ops,
55 },
56 .probe = db1000_audio_probe,
57 .remove = __devexit_p(db1000_audio_remove),
58};
59
60static int __init db1000_audio_load(void)
61{
62 return platform_driver_register(&db1000_audio_driver);
63}
64
65static void __exit db1000_audio_unload(void)
66{
67 platform_driver_unregister(&db1000_audio_driver);
68}
69
70module_init(db1000_audio_load);
71module_exit(db1000_audio_unload);
72
73MODULE_LICENSE("GPL");
74MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
75MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 1d3e258c9ea..289312c14b9 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * DB1200 ASoC audio fabric support code. 2 * DB1200 ASoC audio fabric support code.
3 * 3 *
4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> 4 * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 * 5 *
6 */ 6 */
7 7
@@ -21,6 +21,17 @@
21#include "../codecs/wm8731.h" 21#include "../codecs/wm8731.h"
22#include "psc.h" 22#include "psc.h"
23 23
24static struct platform_device_id db1200_pids[] = {
25 {
26 .name = "db1200-ac97",
27 .driver_data = 0,
28 }, {
29 .name = "db1200-i2s",
30 .driver_data = 1,
31 },
32 {},
33};
34
24/*------------------------- AC97 PART ---------------------------*/ 35/*------------------------- AC97 PART ---------------------------*/
25 36
26static struct snd_soc_dai_link db1200_ac97_dai = { 37static struct snd_soc_dai_link db1200_ac97_dai = {
@@ -89,36 +100,47 @@ static struct snd_soc_card db1200_i2s_machine = {
89 100
90/*------------------------- COMMON PART ---------------------------*/ 101/*------------------------- COMMON PART ---------------------------*/
91 102
92static struct platform_device *db1200_asoc_dev; 103static struct snd_soc_card *db1200_cards[] __devinitdata = {
104 &db1200_ac97_machine,
105 &db1200_i2s_machine,
106};
93 107
94static int __init db1200_audio_load(void) 108static int __devinit db1200_audio_probe(struct platform_device *pdev)
95{ 109{
96 int ret; 110 const struct platform_device_id *pid = platform_get_device_id(pdev);
111 struct snd_soc_card *card;
97 112
98 ret = -ENOMEM; 113 card = db1200_cards[pid->driver_data];
99 db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */ 114 card->dev = &pdev->dev;
100 if (!db1200_asoc_dev) 115 return snd_soc_register_card(card);
101 goto out; 116}
102 117
103 /* DB1200 board setup set PSC1MUX to preferred audio device */ 118static int __devexit db1200_audio_remove(struct platform_device *pdev)
104 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) 119{
105 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine); 120 struct snd_soc_card *card = platform_get_drvdata(pdev);
106 else 121 snd_soc_unregister_card(card);
107 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine); 122 return 0;
123}
108 124
109 ret = platform_device_add(db1200_asoc_dev); 125static struct platform_driver db1200_audio_driver = {
126 .driver = {
127 .name = "db1200-ac97",
128 .owner = THIS_MODULE,
129 .pm = &snd_soc_pm_ops,
130 },
131 .id_table = db1200_pids,
132 .probe = db1200_audio_probe,
133 .remove = __devexit_p(db1200_audio_remove),
134};
110 135
111 if (ret) { 136static int __init db1200_audio_load(void)
112 platform_device_put(db1200_asoc_dev); 137{
113 db1200_asoc_dev = NULL; 138 return platform_driver_register(&db1200_audio_driver);
114 }
115out:
116 return ret;
117} 139}
118 140
119static void __exit db1200_audio_unload(void) 141static void __exit db1200_audio_unload(void)
120{ 142{
121 platform_device_unregister(db1200_asoc_dev); 143 platform_driver_unregister(&db1200_audio_driver);
122} 144}
123 145
124module_init(db1200_audio_load); 146module_init(db1200_audio_load);
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 20bb53a837b..d7d04e26eee 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -169,7 +169,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
169 169
170 au1x_pcm_dbdma_free(pcd); 170 au1x_pcm_dbdma_free(pcd);
171 171
172 if (stype == PCM_RX) 172 if (stype == SNDRV_PCM_STREAM_CAPTURE)
173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, 173 pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
174 DSCR_CMD0_ALWAYS, 174 DSCR_CMD0_ALWAYS,
175 au1x_pcm_dmarx_cb, (void *)pcd); 175 au1x_pcm_dmarx_cb, (void *)pcd);
@@ -198,7 +198,7 @@ static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream
198 struct snd_soc_pcm_runtime *rtd = ss->private_data; 198 struct snd_soc_pcm_runtime *rtd = ss->private_data;
199 struct au1xpsc_audio_dmadata *pcd = 199 struct au1xpsc_audio_dmadata *pcd =
200 snd_soc_platform_get_drvdata(rtd->platform); 200 snd_soc_platform_get_drvdata(rtd->platform);
201 return &pcd[SUBSTREAM_TYPE(ss)]; 201 return &pcd[ss->stream];
202} 202}
203 203
204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, 204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -212,7 +212,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
212 if (ret < 0) 212 if (ret < 0)
213 goto out; 213 goto out;
214 214
215 stype = SUBSTREAM_TYPE(substream); 215 stype = substream->stream;
216 pcd = to_dmadata(substream); 216 pcd = to_dmadata(substream);
217 217
218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " 218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
@@ -255,7 +255,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
255 255
256 au1xxx_dbdma_reset(pcd->ddma_chan); 256 au1xxx_dbdma_reset(pcd->ddma_chan);
257 257
258 if (SUBSTREAM_TYPE(substream) == PCM_RX) { 258 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
259 au1x_pcm_queue_rx(pcd); 259 au1x_pcm_queue_rx(pcd);
260 au1x_pcm_queue_rx(pcd); 260 au1x_pcm_queue_rx(pcd);
261 } else { 261 } else {
@@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
293 293
294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) 294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
295{ 295{
296 struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
297 struct snd_soc_pcm_runtime *rtd = substream->private_data;
298 int stype = substream->stream, *dmaids;
299
300 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
301 if (!dmaids)
302 return -ENODEV; /* whoa, has ordering changed? */
303
304 pcd->ddma_id = dmaids[stype];
305
296 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); 306 snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
297 return 0; 307 return 0;
298} 308}
@@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = {
340static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) 350static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
341{ 351{
342 struct au1xpsc_audio_dmadata *dmadata; 352 struct au1xpsc_audio_dmadata *dmadata;
343 struct resource *r;
344 int ret; 353 int ret;
345 354
346 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); 355 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
347 if (!dmadata) 356 if (!dmadata)
348 return -ENOMEM; 357 return -ENOMEM;
349 358
350 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
351 if (!r) {
352 ret = -ENODEV;
353 goto out1;
354 }
355 dmadata[PCM_TX].ddma_id = r->start;
356
357 /* RX DMA */
358 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
359 if (!r) {
360 ret = -ENODEV;
361 goto out1;
362 }
363 dmadata[PCM_RX].ddma_id = r->start;
364
365 platform_set_drvdata(pdev, dmadata); 359 platform_set_drvdata(pdev, dmadata);
366 360
367 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); 361 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
368 if (!ret) 362 if (ret)
369 return ret; 363 kfree(dmadata);
370 364
371out1:
372 kfree(dmadata);
373 return ret; 365 return ret;
374} 366}
375 367
@@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void)
405module_init(au1xpsc_audio_dbdma_load); 397module_init(au1xpsc_audio_dbdma_load);
406module_exit(au1xpsc_audio_dbdma_unload); 398module_exit(au1xpsc_audio_dbdma_unload);
407 399
408
409struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
410{
411 struct resource *res, *r;
412 struct platform_device *pd;
413 int id[2];
414 int ret;
415
416 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
417 if (!r)
418 return NULL;
419 id[0] = r->start;
420
421 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
422 if (!r)
423 return NULL;
424 id[1] = r->start;
425
426 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
427 if (!res)
428 return NULL;
429
430 res[0].start = res[0].end = id[0];
431 res[1].start = res[1].end = id[1];
432 res[0].flags = res[1].flags = IORESOURCE_DMA;
433
434 pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
435 if (!pd)
436 goto out;
437
438 pd->resource = res;
439 pd->num_resources = 2;
440
441 ret = platform_device_add(pd);
442 if (!ret)
443 return pd;
444
445 platform_device_put(pd);
446out:
447 kfree(res);
448 return NULL;
449}
450EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
451
452void au1xpsc_pcm_destroy(struct platform_device *dmapd)
453{
454 if (dmapd)
455 platform_device_unregister(dmapd);
456}
457EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
458
459MODULE_LICENSE("GPL"); 400MODULE_LICENSE("GPL");
460MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 401MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
461MODULE_AUTHOR("Manuel Lauss"); 402MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
new file mode 100644
index 00000000000..7aa5b760677
--- /dev/null
+++ b/sound/soc/au1x/dma.c
@@ -0,0 +1,377 @@
1/*
2 * Au1000/Au1500/Au1100 Audio DMA support.
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * copied almost verbatim from the old ALSA driver, written by
7 * Charles Eidsness <charles@cooper-street.com>
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/dma-mapping.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <asm/mach-au1x00/au1000.h>
20#include <asm/mach-au1x00/au1000_dma.h>
21
22#include "psc.h"
23
24#define ALCHEMY_PCM_FMTS \
25 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
26 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
27 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
28 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
29 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
30 0)
31
32struct pcm_period {
33 u32 start;
34 u32 relative_end; /* relative to start of buffer */
35 struct pcm_period *next;
36};
37
38struct audio_stream {
39 struct snd_pcm_substream *substream;
40 int dma;
41 struct pcm_period *buffer;
42 unsigned int period_size;
43 unsigned int periods;
44};
45
46struct alchemy_pcm_ctx {
47 struct audio_stream stream[2]; /* playback & capture */
48};
49
50static void au1000_release_dma_link(struct audio_stream *stream)
51{
52 struct pcm_period *pointer;
53 struct pcm_period *pointer_next;
54
55 stream->period_size = 0;
56 stream->periods = 0;
57 pointer = stream->buffer;
58 if (!pointer)
59 return;
60 do {
61 pointer_next = pointer->next;
62 kfree(pointer);
63 pointer = pointer_next;
64 } while (pointer != stream->buffer);
65 stream->buffer = NULL;
66}
67
68static int au1000_setup_dma_link(struct audio_stream *stream,
69 unsigned int period_bytes,
70 unsigned int periods)
71{
72 struct snd_pcm_substream *substream = stream->substream;
73 struct snd_pcm_runtime *runtime = substream->runtime;
74 struct pcm_period *pointer;
75 unsigned long dma_start;
76 int i;
77
78 dma_start = virt_to_phys(runtime->dma_area);
79
80 if (stream->period_size == period_bytes &&
81 stream->periods == periods)
82 return 0; /* not changed */
83
84 au1000_release_dma_link(stream);
85
86 stream->period_size = period_bytes;
87 stream->periods = periods;
88
89 stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL);
90 if (!stream->buffer)
91 return -ENOMEM;
92 pointer = stream->buffer;
93 for (i = 0; i < periods; i++) {
94 pointer->start = (u32)(dma_start + (i * period_bytes));
95 pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
96 if (i < periods - 1) {
97 pointer->next = kmalloc(sizeof(struct pcm_period),
98 GFP_KERNEL);
99 if (!pointer->next) {
100 au1000_release_dma_link(stream);
101 return -ENOMEM;
102 }
103 pointer = pointer->next;
104 }
105 }
106 pointer->next = stream->buffer;
107 return 0;
108}
109
110static void au1000_dma_stop(struct audio_stream *stream)
111{
112 if (stream->buffer)
113 disable_dma(stream->dma);
114}
115
116static void au1000_dma_start(struct audio_stream *stream)
117{
118 if (!stream->buffer)
119 return;
120
121 init_dma(stream->dma);
122 if (get_dma_active_buffer(stream->dma) == 0) {
123 clear_dma_done0(stream->dma);
124 set_dma_addr0(stream->dma, stream->buffer->start);
125 set_dma_count0(stream->dma, stream->period_size >> 1);
126 set_dma_addr1(stream->dma, stream->buffer->next->start);
127 set_dma_count1(stream->dma, stream->period_size >> 1);
128 } else {
129 clear_dma_done1(stream->dma);
130 set_dma_addr1(stream->dma, stream->buffer->start);
131 set_dma_count1(stream->dma, stream->period_size >> 1);
132 set_dma_addr0(stream->dma, stream->buffer->next->start);
133 set_dma_count0(stream->dma, stream->period_size >> 1);
134 }
135 enable_dma_buffers(stream->dma);
136 start_dma(stream->dma);
137}
138
139static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
140{
141 struct audio_stream *stream = (struct audio_stream *)ptr;
142 struct snd_pcm_substream *substream = stream->substream;
143
144 switch (get_dma_buffer_done(stream->dma)) {
145 case DMA_D0:
146 stream->buffer = stream->buffer->next;
147 clear_dma_done0(stream->dma);
148 set_dma_addr0(stream->dma, stream->buffer->next->start);
149 set_dma_count0(stream->dma, stream->period_size >> 1);
150 enable_dma_buffer0(stream->dma);
151 break;
152 case DMA_D1:
153 stream->buffer = stream->buffer->next;
154 clear_dma_done1(stream->dma);
155 set_dma_addr1(stream->dma, stream->buffer->next->start);
156 set_dma_count1(stream->dma, stream->period_size >> 1);
157 enable_dma_buffer1(stream->dma);
158 break;
159 case (DMA_D0 | DMA_D1):
160 pr_debug("DMA %d missed interrupt.\n", stream->dma);
161 au1000_dma_stop(stream);
162 au1000_dma_start(stream);
163 break;
164 case (~DMA_D0 & ~DMA_D1):
165 pr_debug("DMA %d empty irq.\n", stream->dma);
166 }
167 snd_pcm_period_elapsed(substream);
168 return IRQ_HANDLED;
169}
170
171static const struct snd_pcm_hardware alchemy_pcm_hardware = {
172 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
173 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
174 .formats = ALCHEMY_PCM_FMTS,
175 .rates = SNDRV_PCM_RATE_8000_192000,
176 .rate_min = SNDRV_PCM_RATE_8000,
177 .rate_max = SNDRV_PCM_RATE_192000,
178 .channels_min = 2,
179 .channels_max = 2,
180 .period_bytes_min = 1024,
181 .period_bytes_max = 16 * 1024 - 1,
182 .periods_min = 4,
183 .periods_max = 255,
184 .buffer_bytes_max = 128 * 1024,
185 .fifo_size = 16,
186};
187
188static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
189{
190 struct snd_soc_pcm_runtime *rtd = ss->private_data;
191 return snd_soc_platform_get_drvdata(rtd->platform);
192}
193
194static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
195{
196 struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss);
197 return &(ctx->stream[ss->stream]);
198}
199
200static int alchemy_pcm_open(struct snd_pcm_substream *substream)
201{
202 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
203 struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 int *dmaids, s = substream->stream;
205 char *name;
206
207 dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
208 if (!dmaids)
209 return -ENODEV; /* whoa, has ordering changed? */
210
211 /* DMA setup */
212 name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx";
213 ctx->stream[s].dma = request_au1000_dma(dmaids[s], name,
214 au1000_dma_interrupt, IRQF_DISABLED,
215 &ctx->stream[s]);
216 set_dma_mode(ctx->stream[s].dma,
217 get_dma_mode(ctx->stream[s].dma) & ~DMA_NC);
218
219 ctx->stream[s].substream = substream;
220 ctx->stream[s].buffer = NULL;
221 snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware);
222
223 return 0;
224}
225
226static int alchemy_pcm_close(struct snd_pcm_substream *substream)
227{
228 struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
229 int stype = substream->stream;
230
231 ctx->stream[stype].substream = NULL;
232 free_au1000_dma(ctx->stream[stype].dma);
233
234 return 0;
235}
236
237static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream,
238 struct snd_pcm_hw_params *hw_params)
239{
240 struct audio_stream *stream = ss_to_as(substream);
241 int err;
242
243 err = snd_pcm_lib_malloc_pages(substream,
244 params_buffer_bytes(hw_params));
245 if (err < 0)
246 return err;
247 err = au1000_setup_dma_link(stream,
248 params_period_bytes(hw_params),
249 params_periods(hw_params));
250 if (err)
251 snd_pcm_lib_free_pages(substream);
252
253 return err;
254}
255
256static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream)
257{
258 struct audio_stream *stream = ss_to_as(substream);
259 au1000_release_dma_link(stream);
260 return snd_pcm_lib_free_pages(substream);
261}
262
263static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
264{
265 struct audio_stream *stream = ss_to_as(substream);
266 int err = 0;
267
268 switch (cmd) {
269 case SNDRV_PCM_TRIGGER_START:
270 au1000_dma_start(stream);
271 break;
272 case SNDRV_PCM_TRIGGER_STOP:
273 au1000_dma_stop(stream);
274 break;
275 default:
276 err = -EINVAL;
277 break;
278 }
279 return err;
280}
281
282static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
283{
284 struct audio_stream *stream = ss_to_as(ss);
285 long location;
286
287 location = get_dma_residue(stream->dma);
288 location = stream->buffer->relative_end - location;
289 if (location == -1)
290 location = 0;
291 return bytes_to_frames(ss->runtime, location);
292}
293
294static struct snd_pcm_ops alchemy_pcm_ops = {
295 .open = alchemy_pcm_open,
296 .close = alchemy_pcm_close,
297 .ioctl = snd_pcm_lib_ioctl,
298 .hw_params = alchemy_pcm_hw_params,
299 .hw_free = alchemy_pcm_hw_free,
300 .trigger = alchemy_pcm_trigger,
301 .pointer = alchemy_pcm_pointer,
302};
303
304static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
305{
306 snd_pcm_lib_preallocate_free_for_all(pcm);
307}
308
309static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
310{
311 struct snd_pcm *pcm = rtd->pcm;
312
313 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
314 snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1);
315
316 return 0;
317}
318
319struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
320 .ops = &alchemy_pcm_ops,
321 .pcm_new = alchemy_pcm_new,
322 .pcm_free = alchemy_pcm_free_dma_buffers,
323};
324
325static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
326{
327 struct alchemy_pcm_ctx *ctx;
328 int ret;
329
330 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
331 if (!ctx)
332 return -ENOMEM;
333
334 platform_set_drvdata(pdev, ctx);
335
336 ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
337 if (ret)
338 kfree(ctx);
339
340 return ret;
341}
342
343static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
344{
345 struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev);
346
347 snd_soc_unregister_platform(&pdev->dev);
348 kfree(ctx);
349
350 return 0;
351}
352
353static struct platform_driver alchemy_pcmdma_driver = {
354 .driver = {
355 .name = "alchemy-pcm-dma",
356 .owner = THIS_MODULE,
357 },
358 .probe = alchemy_pcm_drvprobe,
359 .remove = __devexit_p(alchemy_pcm_drvremove),
360};
361
362static int __init alchemy_pcmdma_load(void)
363{
364 return platform_driver_register(&alchemy_pcmdma_driver);
365}
366
367static void __exit alchemy_pcmdma_unload(void)
368{
369 platform_driver_unregister(&alchemy_pcmdma_driver);
370}
371
372module_init(alchemy_pcmdma_load);
373module_exit(alchemy_pcmdma_unload);
374
375MODULE_LICENSE("GPL");
376MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
377MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
new file mode 100644
index 00000000000..19e0d2a9c82
--- /dev/null
+++ b/sound/soc/au1x/i2sc.c
@@ -0,0 +1,346 @@
1/*
2 * Au1000/Au1500/Au1100 I2S controller driver for ASoC
3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 *
6 * Note: clock supplied to the I2S controller must be 256x samplerate.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/suspend.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/initval.h>
16#include <sound/soc.h>
17#include <asm/mach-au1x00/au1000.h>
18
19#include "psc.h"
20
21#define I2S_RXTX 0x00
22#define I2S_CFG 0x04
23#define I2S_ENABLE 0x08
24
25#define CFG_XU (1 << 25) /* tx underflow */
26#define CFG_XO (1 << 24)
27#define CFG_RU (1 << 23)
28#define CFG_RO (1 << 22)
29#define CFG_TR (1 << 21)
30#define CFG_TE (1 << 20)
31#define CFG_TF (1 << 19)
32#define CFG_RR (1 << 18)
33#define CFG_RF (1 << 17)
34#define CFG_ICK (1 << 12) /* clock invert */
35#define CFG_PD (1 << 11) /* set to make I2SDIO INPUT */
36#define CFG_LB (1 << 10) /* loopback */
37#define CFG_IC (1 << 9) /* word select invert */
38#define CFG_FM_I2S (0 << 7) /* I2S format */
39#define CFG_FM_LJ (1 << 7) /* left-justified */
40#define CFG_FM_RJ (2 << 7) /* right-justified */
41#define CFG_FM_MASK (3 << 7)
42#define CFG_TN (1 << 6) /* tx fifo en */
43#define CFG_RN (1 << 5) /* rx fifo en */
44#define CFG_SZ_8 (0x08)
45#define CFG_SZ_16 (0x10)
46#define CFG_SZ_18 (0x12)
47#define CFG_SZ_20 (0x14)
48#define CFG_SZ_24 (0x18)
49#define CFG_SZ_MASK (0x1f)
50#define EN_D (1 << 1) /* DISable */
51#define EN_CE (1 << 0) /* clock enable */
52
53/* only limited by clock generator and board design */
54#define AU1XI2SC_RATES \
55 SNDRV_PCM_RATE_CONTINUOUS
56
57#define AU1XI2SC_FMTS \
58 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
59 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
60 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
61 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
62 SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE | \
63 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
64 SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE | \
65 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
66 SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE | \
67 0)
68
69static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
70{
71 return __raw_readl(ctx->mmio + reg);
72}
73
74static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
75{
76 __raw_writel(v, ctx->mmio + reg);
77 wmb();
78}
79
80static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
81{
82 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
83 unsigned long c;
84 int ret;
85
86 ret = -EINVAL;
87 c = ctx->cfg;
88
89 c &= ~CFG_FM_MASK;
90 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
91 case SND_SOC_DAIFMT_I2S:
92 c |= CFG_FM_I2S;
93 break;
94 case SND_SOC_DAIFMT_MSB:
95 c |= CFG_FM_RJ;
96 break;
97 case SND_SOC_DAIFMT_LSB:
98 c |= CFG_FM_LJ;
99 break;
100 default:
101 goto out;
102 }
103
104 c &= ~(CFG_IC | CFG_ICK); /* IB-IF */
105 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
106 case SND_SOC_DAIFMT_NB_NF:
107 c |= CFG_IC | CFG_ICK;
108 break;
109 case SND_SOC_DAIFMT_NB_IF:
110 c |= CFG_IC;
111 break;
112 case SND_SOC_DAIFMT_IB_NF:
113 c |= CFG_ICK;
114 break;
115 case SND_SOC_DAIFMT_IB_IF:
116 break;
117 default:
118 goto out;
119 }
120
121 /* I2S controller only supports master */
122 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
123 case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
124 break;
125 default:
126 goto out;
127 }
128
129 ret = 0;
130 ctx->cfg = c;
131out:
132 return ret;
133}
134
135static int au1xi2s_trigger(struct snd_pcm_substream *substream,
136 int cmd, struct snd_soc_dai *dai)
137{
138 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
139 int stype = SUBSTREAM_TYPE(substream);
140
141 switch (cmd) {
142 case SNDRV_PCM_TRIGGER_START:
143 case SNDRV_PCM_TRIGGER_RESUME:
144 /* power up */
145 WR(ctx, I2S_ENABLE, EN_D | EN_CE);
146 WR(ctx, I2S_ENABLE, EN_CE);
147 ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
148 WR(ctx, I2S_CFG, ctx->cfg);
149 break;
150 case SNDRV_PCM_TRIGGER_STOP:
151 case SNDRV_PCM_TRIGGER_SUSPEND:
152 ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
153 WR(ctx, I2S_CFG, ctx->cfg);
154 WR(ctx, I2S_ENABLE, EN_D); /* power off */
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 return 0;
161}
162
163static unsigned long msbits_to_reg(int msbits)
164{
165 switch (msbits) {
166 case 8:
167 return CFG_SZ_8;
168 case 16:
169 return CFG_SZ_16;
170 case 18:
171 return CFG_SZ_18;
172 case 20:
173 return CFG_SZ_20;
174 case 24:
175 return CFG_SZ_24;
176 }
177 return 0;
178}
179
180static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai)
183{
184 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
185 unsigned long v;
186
187 v = msbits_to_reg(params->msbits);
188 if (!v)
189 return -EINVAL;
190
191 ctx->cfg &= ~CFG_SZ_MASK;
192 ctx->cfg |= v;
193 return 0;
194}
195
196static int au1xi2s_startup(struct snd_pcm_substream *substream,
197 struct snd_soc_dai *dai)
198{
199 struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
200 snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
201 return 0;
202}
203
204static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
205 .startup = au1xi2s_startup,
206 .trigger = au1xi2s_trigger,
207 .hw_params = au1xi2s_hw_params,
208 .set_fmt = au1xi2s_set_fmt,
209};
210
211static struct snd_soc_dai_driver au1xi2s_dai_driver = {
212 .symmetric_rates = 1,
213 .playback = {
214 .rates = AU1XI2SC_RATES,
215 .formats = AU1XI2SC_FMTS,
216 .channels_min = 2,
217 .channels_max = 2,
218 },
219 .capture = {
220 .rates = AU1XI2SC_RATES,
221 .formats = AU1XI2SC_FMTS,
222 .channels_min = 2,
223 .channels_max = 2,
224 },
225 .ops = &au1xi2s_dai_ops,
226};
227
228static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
229{
230 int ret;
231 struct resource *r;
232 struct au1xpsc_audio_data *ctx;
233
234 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
235 if (!ctx)
236 return -ENOMEM;
237
238 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!r) {
240 ret = -ENODEV;
241 goto out0;
242 }
243
244 ret = -EBUSY;
245 if (!request_mem_region(r->start, resource_size(r), pdev->name))
246 goto out0;
247
248 ctx->mmio = ioremap_nocache(r->start, resource_size(r));
249 if (!ctx->mmio)
250 goto out1;
251
252 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
253 if (!r)
254 goto out1;
255 ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
256
257 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
258 if (!r)
259 goto out1;
260 ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
261
262 platform_set_drvdata(pdev, ctx);
263
264 ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
265 if (ret)
266 goto out1;
267
268 return 0;
269
270out1:
271 release_mem_region(r->start, resource_size(r));
272out0:
273 kfree(ctx);
274 return ret;
275}
276
277static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
278{
279 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
280 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281
282 snd_soc_unregister_dai(&pdev->dev);
283
284 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
285
286 iounmap(ctx->mmio);
287 release_mem_region(r->start, resource_size(r));
288 kfree(ctx);
289
290 return 0;
291}
292
293#ifdef CONFIG_PM
294static int au1xi2s_drvsuspend(struct device *dev)
295{
296 struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
297
298 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
299
300 return 0;
301}
302
303static int au1xi2s_drvresume(struct device *dev)
304{
305 return 0;
306}
307
308static const struct dev_pm_ops au1xi2sc_pmops = {
309 .suspend = au1xi2s_drvsuspend,
310 .resume = au1xi2s_drvresume,
311};
312
313#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)
314
315#else
316
317#define AU1XI2SC_PMOPS NULL
318
319#endif
320
321static struct platform_driver au1xi2s_driver = {
322 .driver = {
323 .name = "alchemy-i2sc",
324 .owner = THIS_MODULE,
325 .pm = AU1XI2SC_PMOPS,
326 },
327 .probe = au1xi2s_drvprobe,
328 .remove = __devexit_p(au1xi2s_drvremove),
329};
330
331static int __init au1xi2s_load(void)
332{
333 return platform_driver_register(&au1xi2s_driver);
334}
335
336static void __exit au1xi2s_unload(void)
337{
338 platform_driver_unregister(&au1xi2s_driver);
339}
340
341module_init(au1xi2s_load);
342module_exit(au1xi2s_unload);
343
344MODULE_LICENSE("GPL");
345MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
346MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index d0db66f24a0..172eefd38b2 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -41,14 +41,14 @@
41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) 41 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
42 42
43#define AC97PCR_START(stype) \ 43#define AC97PCR_START(stype) \
44 ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) 44 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
45#define AC97PCR_STOP(stype) \ 45#define AC97PCR_STOP(stype) \
46 ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) 46 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
47#define AC97PCR_CLRFIFO(stype) \ 47#define AC97PCR_CLRFIFO(stype) \
48 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) 48 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
49 49
50#define AC97STAT_BUSY(stype) \ 50#define AC97STAT_BUSY(stype) \
51 ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
52 52
53/* instance data. There can be only one, MacLeod!!!! */ 53/* instance data. There can be only one, MacLeod!!!! */
54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; 54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
@@ -215,7 +215,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
215{ 215{
216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
217 unsigned long r, ro, stat; 217 unsigned long r, ro, stat;
218 int chans, t, stype = SUBSTREAM_TYPE(substream); 218 int chans, t, stype = substream->stream;
219 219
220 chans = params_channels(params); 220 chans = params_channels(params);
221 221
@@ -235,7 +235,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
235 r |= PSC_AC97CFG_SET_LEN(params->msbits); 235 r |= PSC_AC97CFG_SET_LEN(params->msbits);
236 236
237 /* channels: enable slots for front L/R channel */ 237 /* channels: enable slots for front L/R channel */
238 if (stype == PCM_TX) { 238 if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
239 r &= ~PSC_AC97CFG_TXSLOT_MASK; 239 r &= ~PSC_AC97CFG_TXSLOT_MASK;
240 r |= PSC_AC97CFG_TXSLOT_ENA(3); 240 r |= PSC_AC97CFG_TXSLOT_ENA(3);
241 r |= PSC_AC97CFG_TXSLOT_ENA(4); 241 r |= PSC_AC97CFG_TXSLOT_ENA(4);
@@ -294,7 +294,7 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
294 int cmd, struct snd_soc_dai *dai) 294 int cmd, struct snd_soc_dai *dai)
295{ 295{
296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
297 int ret, stype = SUBSTREAM_TYPE(substream); 297 int ret, stype = substream->stream;
298 298
299 ret = 0; 299 ret = 0;
300 300
@@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
324 return ret; 324 return ret;
325} 325}
326 326
327static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
328 struct snd_soc_dai *dai)
329{
330 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
331 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
332 return 0;
333}
334
327static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) 335static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
328{ 336{
329 return au1xpsc_ac97_workdata ? 0 : -ENODEV; 337 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
330} 338}
331 339
332static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 340static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
341 .startup = au1xpsc_ac97_startup,
333 .trigger = au1xpsc_ac97_trigger, 342 .trigger = au1xpsc_ac97_trigger,
334 .hw_params = au1xpsc_ac97_hw_params, 343 .hw_params = au1xpsc_ac97_hw_params,
335}; 344};
@@ -379,6 +388,16 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
379 if (!wd->mmio) 388 if (!wd->mmio)
380 goto out1; 389 goto out1;
381 390
391 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
392 if (!r)
393 goto out2;
394 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
395
396 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
397 if (!r)
398 goto out2;
399 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
400
382 /* configuration: max dma trigger threshold, enable ac97 */ 401 /* configuration: max dma trigger threshold, enable ac97 */
383 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | 402 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
384 PSC_AC97CFG_DE_ENABLE; 403 PSC_AC97CFG_DE_ENABLE;
@@ -401,15 +420,13 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
401 420
402 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 421 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
403 if (ret) 422 if (ret)
404 goto out1; 423 goto out2;
405 424
406 wd->dmapd = au1xpsc_pcm_add(pdev); 425 au1xpsc_ac97_workdata = wd;
407 if (wd->dmapd) { 426 return 0;
408 au1xpsc_ac97_workdata = wd;
409 return 0;
410 }
411 427
412 snd_soc_unregister_dai(&pdev->dev); 428out2:
429 iounmap(wd->mmio);
413out1: 430out1:
414 release_mem_region(r->start, resource_size(r)); 431 release_mem_region(r->start, resource_size(r));
415out0: 432out0:
@@ -422,9 +439,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
422 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 439 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
423 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 440 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
424 441
425 if (wd->dmapd)
426 au1xpsc_pcm_destroy(wd->dmapd);
427
428 snd_soc_unregister_dai(&pdev->dev); 442 snd_soc_unregister_dai(&pdev->dev);
429 443
430 /* disable PSC completely */ 444 /* disable PSC completely */
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index fca09127632..7c5ae920544 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -42,13 +42,13 @@
42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 42 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
43 43
44#define I2SSTAT_BUSY(stype) \ 44#define I2SSTAT_BUSY(stype) \
45 ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) 45 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
46#define I2SPCR_START(stype) \ 46#define I2SPCR_START(stype) \
47 ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) 47 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
48#define I2SPCR_STOP(stype) \ 48#define I2SPCR_STOP(stype) \
49 ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) 49 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
50#define I2SPCR_CLRFIFO(stype) \ 50#define I2SPCR_CLRFIFO(stype) \
51 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) 51 ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
52 52
53 53
54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -240,7 +240,7 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
240 struct snd_soc_dai *dai) 240 struct snd_soc_dai *dai)
241{ 241{
242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); 242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
243 int ret, stype = SUBSTREAM_TYPE(substream); 243 int ret, stype = substream->stream;
244 244
245 switch (cmd) { 245 switch (cmd) {
246 case SNDRV_PCM_TRIGGER_START: 246 case SNDRV_PCM_TRIGGER_START:
@@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
257 return ret; 257 return ret;
258} 258}
259 259
260static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
261 struct snd_soc_dai *dai)
262{
263 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
264 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
265 return 0;
266}
267
260static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 268static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
269 .startup = au1xpsc_i2s_startup,
261 .trigger = au1xpsc_i2s_trigger, 270 .trigger = au1xpsc_i2s_trigger,
262 .hw_params = au1xpsc_i2s_hw_params, 271 .hw_params = au1xpsc_i2s_hw_params,
263 .set_fmt = au1xpsc_i2s_set_fmt, 272 .set_fmt = au1xpsc_i2s_set_fmt,
@@ -304,6 +313,16 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
304 if (!wd->mmio) 313 if (!wd->mmio)
305 goto out1; 314 goto out1;
306 315
316 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
317 if (!r)
318 goto out2;
319 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
320
321 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
322 if (!r)
323 goto out2;
324 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
325
307 /* preserve PSC clock source set up by platform (dev.platform_data 326 /* preserve PSC clock source set up by platform (dev.platform_data
308 * is already occupied by soc layer) 327 * is already occupied by soc layer)
309 */ 328 */
@@ -330,15 +349,11 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
330 platform_set_drvdata(pdev, wd); 349 platform_set_drvdata(pdev, wd);
331 350
332 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); 351 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
333 if (ret) 352 if (!ret)
334 goto out1;
335
336 /* finally add the DMA device for this PSC */
337 wd->dmapd = au1xpsc_pcm_add(pdev);
338 if (wd->dmapd)
339 return 0; 353 return 0;
340 354
341 snd_soc_unregister_dai(&pdev->dev); 355out2:
356 iounmap(wd->mmio);
342out1: 357out1:
343 release_mem_region(r->start, resource_size(r)); 358 release_mem_region(r->start, resource_size(r));
344out0: 359out0:
@@ -351,9 +366,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
351 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 366 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
352 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 367 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 368
354 if (wd->dmapd)
355 au1xpsc_pcm_destroy(wd->dmapd);
356
357 snd_soc_unregister_dai(&pdev->dev); 369 snd_soc_unregister_dai(&pdev->dev);
358 370
359 au_writel(0, I2S_CFG(wd)); 371 au_writel(0, I2S_CFG(wd));
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index b30eadd422a..b16b2e02e0c 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Alchemy ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2011 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <manuel.lauss@gmail.com> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -13,10 +13,6 @@
13#ifndef _AU1X_PCM_H 13#ifndef _AU1X_PCM_H
14#define _AU1X_PCM_H 14#define _AU1X_PCM_H
15 15
16/* DBDMA helpers */
17extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
18extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
19
20struct au1xpsc_audio_data { 16struct au1xpsc_audio_data {
21 void __iomem *mmio; 17 void __iomem *mmio;
22 18
@@ -27,15 +23,9 @@ struct au1xpsc_audio_data {
27 23
28 unsigned long pm[2]; 24 unsigned long pm[2];
29 struct mutex lock; 25 struct mutex lock;
30 struct platform_device *dmapd; 26 int dmaids[2];
31}; 27};
32 28
33#define PCM_TX 0
34#define PCM_RX 1
35
36#define SUBSTREAM_TYPE(substream) \
37 ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX)
38
39/* easy access macros */ 29/* easy access macros */
40#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) 30#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
41#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) 31#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index fe9d548a683..9f6bc55fc39 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701
27 board connected to one of the Blackfin evaluation boards like the 27 board connected to one of the Blackfin evaluation boards like the
28 BF5XX-STAMP or BF5XX-EZKIT. 28 BF5XX-STAMP or BF5XX-EZKIT.
29 29
30config SND_SOC_BFIN_EVAL_ADAU1373
31 tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && I2C
33 select SND_BF5XX_SOC_I2S
34 select SND_SOC_ADAU1373
35 help
36 Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
37 board connected to one of the Blackfin evaluation boards like the
38 BF5XX-STAMP or BF5XX-EZKIT.
39
40 Note: This driver assumes that first ADAU1373 DAI is connected to the
41 first SPORT port on the BF5XX board.
42
30config SND_SOC_BFIN_EVAL_ADAV80X 43config SND_SOC_BFIN_EVAL_ADAV80X
31 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" 44 tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
32 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 45 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 6018bf52a23..1bf86ccaa8d 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -21,6 +21,7 @@ snd-ad1980-objs := bf5xx-ad1980.o
21snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
22snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad193x-objs := bf5xx-ad193x.o 23snd-ad193x-objs := bf5xx-ad193x.o
24snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
24snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o 25snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
25snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o 26snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
26 27
@@ -29,5 +30,6 @@ obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
29obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 30obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
30obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 31obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
31obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o 32obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
32obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o 34obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
33obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o 35obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 732a247f252..b94eb7ef7d1 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -128,7 +128,7 @@ static int snd_ad73311_configure(void)
128 return 0; 128 return 0;
129} 129}
130 130
131static int bf5xx_probe(struct platform_device *pdev) 131static int bf5xx_probe(struct snd_soc_card *card)
132{ 132{
133 int err; 133 int err;
134 if (gpio_request(GPIO_SE, "AD73311_SE")) { 134 if (gpio_request(GPIO_SE, "AD73311_SE")) {
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
new file mode 100644
index 00000000000..8df2a3b0cb3
--- /dev/null
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -0,0 +1,202 @@
1/*
2 * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
3 * evaluation boards.
4 *
5 * Copyright 2011 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/pcm_params.h>
17
18#include "../codecs/adau1373.h"
19
20static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
21 SND_SOC_DAPM_LINE("Line In1", NULL),
22 SND_SOC_DAPM_LINE("Line In2", NULL),
23 SND_SOC_DAPM_LINE("Line In3", NULL),
24 SND_SOC_DAPM_LINE("Line In4", NULL),
25
26 SND_SOC_DAPM_LINE("Line Out1", NULL),
27 SND_SOC_DAPM_LINE("Line Out2", NULL),
28 SND_SOC_DAPM_LINE("Stereo Out", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_HP("Earpiece", NULL),
31 SND_SOC_DAPM_SPK("Speaker", NULL),
32};
33
34static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
35 { "AIN1L", NULL, "Line In1" },
36 { "AIN1R", NULL, "Line In1" },
37 { "AIN2L", NULL, "Line In2" },
38 { "AIN2R", NULL, "Line In2" },
39 { "AIN3L", NULL, "Line In3" },
40 { "AIN3R", NULL, "Line In3" },
41 { "AIN4L", NULL, "Line In4" },
42 { "AIN4R", NULL, "Line In4" },
43
44 /* MICBIAS can be connected via a jumper to the line-in jack, since w
45 don't know which one is going to be used, just power both. */
46 { "Line In1", NULL, "MICBIAS1" },
47 { "Line In2", NULL, "MICBIAS1" },
48 { "Line In3", NULL, "MICBIAS1" },
49 { "Line In4", NULL, "MICBIAS1" },
50 { "Line In1", NULL, "MICBIAS2" },
51 { "Line In2", NULL, "MICBIAS2" },
52 { "Line In3", NULL, "MICBIAS2" },
53 { "Line In4", NULL, "MICBIAS2" },
54
55 { "Line Out1", NULL, "LOUT1L" },
56 { "Line Out1", NULL, "LOUT1R" },
57 { "Line Out2", NULL, "LOUT2L" },
58 { "Line Out2", NULL, "LOUT2R" },
59 { "Headphone", NULL, "HPL" },
60 { "Headphone", NULL, "HPR" },
61 { "Earpiece", NULL, "EP" },
62 { "Speaker", NULL, "SPKL" },
63 { "Stereo Out", NULL, "SPKR" },
64};
65
66static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_dai *codec_dai = rtd->codec_dai;
72 int ret;
73 int pll_rate;
74
75 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
76 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
77 if (ret)
78 return ret;
79
80 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
81 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
82 if (ret)
83 return ret;
84
85 switch (params_rate(params)) {
86 case 48000:
87 case 8000:
88 case 12000:
89 case 16000:
90 case 24000:
91 case 32000:
92 pll_rate = 48000 * 1024;
93 break;
94 case 44100:
95 case 7350:
96 case 11025:
97 case 14700:
98 case 22050:
99 case 29400:
100 pll_rate = 44100 * 1024;
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
107 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
108 if (ret)
109 return ret;
110
111 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
112 SND_SOC_CLOCK_IN);
113
114 return ret;
115}
116
117static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
118{
119 struct snd_soc_dai *codec_dai = rtd->codec_dai;
120 unsigned int pll_rate = 48000 * 1024;
121 int ret;
122
123 ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
124 ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
125 if (ret)
126 return ret;
127
128 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
129 SND_SOC_CLOCK_IN);
130
131 return ret;
132}
133static struct snd_soc_ops bfin_eval_adau1373_ops = {
134 .hw_params = bfin_eval_adau1373_hw_params,
135};
136
137static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
138 .name = "adau1373",
139 .stream_name = "adau1373",
140 .cpu_dai_name = "bfin-i2s.0",
141 .codec_dai_name = "adau1373-aif1",
142 .platform_name = "bfin-i2s-pcm-audio",
143 .codec_name = "adau1373.0-001a",
144 .ops = &bfin_eval_adau1373_ops,
145 .init = bfin_eval_adau1373_codec_init,
146};
147
148static struct snd_soc_card bfin_eval_adau1373 = {
149 .name = "bfin-eval-adau1373",
150 .dai_link = &bfin_eval_adau1373_dai,
151 .num_links = 1,
152
153 .dapm_widgets = bfin_eval_adau1373_dapm_widgets,
154 .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
155 .dapm_routes = bfin_eval_adau1373_dapm_routes,
156 .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
157};
158
159static int bfin_eval_adau1373_probe(struct platform_device *pdev)
160{
161 struct snd_soc_card *card = &bfin_eval_adau1373;
162
163 card->dev = &pdev->dev;
164
165 return snd_soc_register_card(&bfin_eval_adau1373);
166}
167
168static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
169{
170 struct snd_soc_card *card = platform_get_drvdata(pdev);
171
172 snd_soc_unregister_card(card);
173
174 return 0;
175}
176
177static struct platform_driver bfin_eval_adau1373_driver = {
178 .driver = {
179 .name = "bfin-eval-adau1373",
180 .owner = THIS_MODULE,
181 .pm = &snd_soc_pm_ops,
182 },
183 .probe = bfin_eval_adau1373_probe,
184 .remove = __devexit_p(bfin_eval_adau1373_remove),
185};
186
187static int __init bfin_eval_adau1373_init(void)
188{
189 return platform_driver_register(&bfin_eval_adau1373_driver);
190}
191module_init(bfin_eval_adau1373_init);
192
193static void __exit bfin_eval_adau1373_exit(void)
194{
195 platform_driver_unregister(&bfin_eval_adau1373_driver);
196}
197module_exit(bfin_eval_adau1373_exit);
198
199MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
200MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
201MODULE_LICENSE("GPL");
202MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 665d9240c4a..71b46c8f70d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311 19 select SND_SOC_AD73311
20 select SND_SOC_ADAU1373 if I2C
20 select SND_SOC_ADAV80X 21 select SND_SOC_ADAV80X
21 select SND_SOC_ADS117X 22 select SND_SOC_ADS117X
22 select SND_SOC_AK4104 if SPI_MASTER 23 select SND_SOC_AK4104 if SPI_MASTER
@@ -139,6 +140,9 @@ config SND_SOC_ADAU1701
139 select SIGMA 140 select SIGMA
140 tristate 141 tristate
141 142
143config SND_SOC_ADAU1373
144 tristate
145
142config SND_SOC_ADAV80X 146config SND_SOC_ADAV80X
143 tristate 147 tristate
144 148
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5119a7e2c1a..70c1769acd1 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -5,6 +5,7 @@ snd-soc-ad193x-objs := ad193x.o
5snd-soc-ad1980-objs := ad1980.o 5snd-soc-ad1980-objs := ad1980.o
6snd-soc-ad73311-objs := ad73311.o 6snd-soc-ad73311-objs := ad73311.o
7snd-soc-adau1701-objs := adau1701.o 7snd-soc-adau1701-objs := adau1701.o
8snd-soc-adau1373-objs := adau1373.o
8snd-soc-adav80x-objs := adav80x.o 9snd-soc-adav80x-objs := adav80x.o
9snd-soc-ads117x-objs := ads117x.o 10snd-soc-ads117x-objs := ads117x.o
10snd-soc-ak4104-objs := ak4104.o 11snd-soc-ak4104-objs := ak4104.o
@@ -100,6 +101,7 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
100obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 101obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
101obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 102obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
102obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 103obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
104obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
103obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 105obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
104obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 106obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
105obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 107obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index eedb6f5e582..f934670199a 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,7 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type control_type; 26 struct regmap *regmap;
27 int sysclk; 27 int sysclk;
28}; 28};
29 29
@@ -349,10 +349,8 @@ static int ad193x_probe(struct snd_soc_codec *codec)
349 struct snd_soc_dapm_context *dapm = &codec->dapm; 349 struct snd_soc_dapm_context *dapm = &codec->dapm;
350 int ret; 350 int ret;
351 351
352 if (ad193x->control_type == SND_SOC_I2C) 352 codec->control_data = ad193x->regmap;
353 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); 353 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
354 else
355 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
356 if (ret < 0) { 354 if (ret < 0) {
357 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 355 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
358 return ret; 356 return ret;
@@ -388,6 +386,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
388}; 386};
389 387
390#if defined(CONFIG_SPI_MASTER) 388#if defined(CONFIG_SPI_MASTER)
389
390static const struct regmap_config ad193x_spi_regmap_config = {
391 .val_bits = 8,
392 .reg_bits = 16,
393 .read_flag_mask = 0x09,
394 .write_flag_mask = 0x08,
395};
396
391static int __devinit ad193x_spi_probe(struct spi_device *spi) 397static int __devinit ad193x_spi_probe(struct spi_device *spi)
392{ 398{
393 struct ad193x_priv *ad193x; 399 struct ad193x_priv *ad193x;
@@ -397,20 +403,36 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
397 if (ad193x == NULL) 403 if (ad193x == NULL)
398 return -ENOMEM; 404 return -ENOMEM;
399 405
406 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
407 if (IS_ERR(ad193x->regmap)) {
408 ret = PTR_ERR(ad193x->regmap);
409 goto err_free;
410 }
411
400 spi_set_drvdata(spi, ad193x); 412 spi_set_drvdata(spi, ad193x);
401 ad193x->control_type = SND_SOC_SPI;
402 413
403 ret = snd_soc_register_codec(&spi->dev, 414 ret = snd_soc_register_codec(&spi->dev,
404 &soc_codec_dev_ad193x, &ad193x_dai, 1); 415 &soc_codec_dev_ad193x, &ad193x_dai, 1);
405 if (ret < 0) 416 if (ret < 0)
406 kfree(ad193x); 417 goto err_regmap_exit;
418
419 return 0;
420
421err_regmap_exit:
422 regmap_exit(ad193x->regmap);
423err_free:
424 kfree(ad193x);
425
407 return ret; 426 return ret;
408} 427}
409 428
410static int __devexit ad193x_spi_remove(struct spi_device *spi) 429static int __devexit ad193x_spi_remove(struct spi_device *spi)
411{ 430{
431 struct ad193x_priv *ad193x = spi_get_drvdata(spi);
432
412 snd_soc_unregister_codec(&spi->dev); 433 snd_soc_unregister_codec(&spi->dev);
413 kfree(spi_get_drvdata(spi)); 434 regmap_exit(ad193x->regmap);
435 kfree(ad193x);
414 return 0; 436 return 0;
415} 437}
416 438
@@ -425,6 +447,12 @@ static struct spi_driver ad193x_spi_driver = {
425#endif 447#endif
426 448
427#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 449#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
450
451static const struct regmap_config ad193x_i2c_regmap_config = {
452 .val_bits = 8,
453 .reg_bits = 8,
454};
455
428static const struct i2c_device_id ad193x_id[] = { 456static const struct i2c_device_id ad193x_id[] = {
429 { "ad1936", 0 }, 457 { "ad1936", 0 },
430 { "ad1937", 0 }, 458 { "ad1937", 0 },
@@ -442,20 +470,35 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
442 if (ad193x == NULL) 470 if (ad193x == NULL)
443 return -ENOMEM; 471 return -ENOMEM;
444 472
473 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
474 if (IS_ERR(ad193x->regmap)) {
475 ret = PTR_ERR(ad193x->regmap);
476 goto err_free;
477 }
478
445 i2c_set_clientdata(client, ad193x); 479 i2c_set_clientdata(client, ad193x);
446 ad193x->control_type = SND_SOC_I2C;
447 480
448 ret = snd_soc_register_codec(&client->dev, 481 ret = snd_soc_register_codec(&client->dev,
449 &soc_codec_dev_ad193x, &ad193x_dai, 1); 482 &soc_codec_dev_ad193x, &ad193x_dai, 1);
450 if (ret < 0) 483 if (ret < 0)
451 kfree(ad193x); 484 goto err_regmap_exit;
485
486 return 0;
487
488err_regmap_exit:
489 regmap_exit(ad193x->regmap);
490err_free:
491 kfree(ad193x);
452 return ret; 492 return ret;
453} 493}
454 494
455static int __devexit ad193x_i2c_remove(struct i2c_client *client) 495static int __devexit ad193x_i2c_remove(struct i2c_client *client)
456{ 496{
497 struct ad193x_priv *ad193x = i2c_get_clientdata(client);
498
457 snd_soc_unregister_codec(&client->dev); 499 snd_soc_unregister_codec(&client->dev);
458 kfree(i2c_get_clientdata(client)); 500 regmap_exit(ad193x->regmap);
501 kfree(ad193x);
459 return 0; 502 return 0;
460} 503}
461 504
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index cccc2e8e5fb..536e5f2b136 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -9,20 +9,20 @@
9#ifndef __AD193X_H__ 9#ifndef __AD193X_H__
10#define __AD193X_H__ 10#define __AD193X_H__
11 11
12#define AD193X_PLL_CLK_CTRL0 0x800 12#define AD193X_PLL_CLK_CTRL0 0x00
13#define AD193X_PLL_POWERDOWN 0x01 13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK (~0x6) 14#define AD193X_PLL_INPUT_MASK (~0x6)
15#define AD193X_PLL_INPUT_256 (0 << 1) 15#define AD193X_PLL_INPUT_256 (0 << 1)
16#define AD193X_PLL_INPUT_384 (1 << 1) 16#define AD193X_PLL_INPUT_384 (1 << 1)
17#define AD193X_PLL_INPUT_512 (2 << 1) 17#define AD193X_PLL_INPUT_512 (2 << 1)
18#define AD193X_PLL_INPUT_768 (3 << 1) 18#define AD193X_PLL_INPUT_768 (3 << 1)
19#define AD193X_PLL_CLK_CTRL1 0x801 19#define AD193X_PLL_CLK_CTRL1 0x01
20#define AD193X_DAC_CTRL0 0x802 20#define AD193X_DAC_CTRL0 0x02
21#define AD193X_DAC_POWERDOWN 0x01 21#define AD193X_DAC_POWERDOWN 0x01
22#define AD193X_DAC_SERFMT_MASK 0xC0 22#define AD193X_DAC_SERFMT_MASK 0xC0
23#define AD193X_DAC_SERFMT_STEREO (0 << 6) 23#define AD193X_DAC_SERFMT_STEREO (0 << 6)
24#define AD193X_DAC_SERFMT_TDM (1 << 6) 24#define AD193X_DAC_SERFMT_TDM (1 << 6)
25#define AD193X_DAC_CTRL1 0x803 25#define AD193X_DAC_CTRL1 0x03
26#define AD193X_DAC_2_CHANNELS 0 26#define AD193X_DAC_2_CHANNELS 0
27#define AD193X_DAC_4_CHANNELS 1 27#define AD193X_DAC_4_CHANNELS 1
28#define AD193X_DAC_8_CHANNELS 2 28#define AD193X_DAC_8_CHANNELS 2
@@ -33,11 +33,11 @@
33#define AD193X_DAC_BCLK_MASTER (1 << 5) 33#define AD193X_DAC_BCLK_MASTER (1 << 5)
34#define AD193X_DAC_LEFT_HIGH (1 << 3) 34#define AD193X_DAC_LEFT_HIGH (1 << 3)
35#define AD193X_DAC_BCLK_INV (1 << 7) 35#define AD193X_DAC_BCLK_INV (1 << 7)
36#define AD193X_DAC_CTRL2 0x804 36#define AD193X_DAC_CTRL2 0x04
37#define AD193X_DAC_WORD_LEN_SHFT 3 37#define AD193X_DAC_WORD_LEN_SHFT 3
38#define AD193X_DAC_WORD_LEN_MASK 0x18 38#define AD193X_DAC_WORD_LEN_MASK 0x18
39#define AD193X_DAC_MASTER_MUTE 1 39#define AD193X_DAC_MASTER_MUTE 1
40#define AD193X_DAC_CHNL_MUTE 0x805 40#define AD193X_DAC_CHNL_MUTE 0x05
41#define AD193X_DACL1_MUTE 0 41#define AD193X_DACL1_MUTE 0
42#define AD193X_DACR1_MUTE 1 42#define AD193X_DACR1_MUTE 1
43#define AD193X_DACL2_MUTE 2 43#define AD193X_DACL2_MUTE 2
@@ -46,28 +46,28 @@
46#define AD193X_DACR3_MUTE 5 46#define AD193X_DACR3_MUTE 5
47#define AD193X_DACL4_MUTE 6 47#define AD193X_DACL4_MUTE 6
48#define AD193X_DACR4_MUTE 7 48#define AD193X_DACR4_MUTE 7
49#define AD193X_DAC_L1_VOL 0x806 49#define AD193X_DAC_L1_VOL 0x06
50#define AD193X_DAC_R1_VOL 0x807 50#define AD193X_DAC_R1_VOL 0x07
51#define AD193X_DAC_L2_VOL 0x808 51#define AD193X_DAC_L2_VOL 0x08
52#define AD193X_DAC_R2_VOL 0x809 52#define AD193X_DAC_R2_VOL 0x09
53#define AD193X_DAC_L3_VOL 0x80a 53#define AD193X_DAC_L3_VOL 0x0a
54#define AD193X_DAC_R3_VOL 0x80b 54#define AD193X_DAC_R3_VOL 0x0b
55#define AD193X_DAC_L4_VOL 0x80c 55#define AD193X_DAC_L4_VOL 0x0c
56#define AD193X_DAC_R4_VOL 0x80d 56#define AD193X_DAC_R4_VOL 0x0d
57#define AD193X_ADC_CTRL0 0x80e 57#define AD193X_ADC_CTRL0 0x0e
58#define AD193X_ADC_POWERDOWN 0x01 58#define AD193X_ADC_POWERDOWN 0x01
59#define AD193X_ADC_HIGHPASS_FILTER 1 59#define AD193X_ADC_HIGHPASS_FILTER 1
60#define AD193X_ADCL1_MUTE 2 60#define AD193X_ADCL1_MUTE 2
61#define AD193X_ADCR1_MUTE 3 61#define AD193X_ADCR1_MUTE 3
62#define AD193X_ADCL2_MUTE 4 62#define AD193X_ADCL2_MUTE 4
63#define AD193X_ADCR2_MUTE 5 63#define AD193X_ADCR2_MUTE 5
64#define AD193X_ADC_CTRL1 0x80f 64#define AD193X_ADC_CTRL1 0x0f
65#define AD193X_ADC_SERFMT_MASK 0x60 65#define AD193X_ADC_SERFMT_MASK 0x60
66#define AD193X_ADC_SERFMT_STEREO (0 << 5) 66#define AD193X_ADC_SERFMT_STEREO (0 << 5)
67#define AD193X_ADC_SERFMT_TDM (1 << 5) 67#define AD193X_ADC_SERFMT_TDM (1 << 5)
68#define AD193X_ADC_SERFMT_AUX (2 << 5) 68#define AD193X_ADC_SERFMT_AUX (2 << 5)
69#define AD193X_ADC_WORD_LEN_MASK 0x3 69#define AD193X_ADC_WORD_LEN_MASK 0x3
70#define AD193X_ADC_CTRL2 0x810 70#define AD193X_ADC_CTRL2 0x10
71#define AD193X_ADC_2_CHANNELS 0 71#define AD193X_ADC_2_CHANNELS 0
72#define AD193X_ADC_4_CHANNELS 1 72#define AD193X_ADC_4_CHANNELS 1
73#define AD193X_ADC_8_CHANNELS 2 73#define AD193X_ADC_8_CHANNELS 2
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 923b364a3e4..4c0fc30a4cc 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -200,18 +200,22 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
200 } 200 }
201 201
202 /* Read out vendor ID to make sure it is ad1980 */ 202 /* Read out vendor ID to make sure it is ad1980 */
203 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) 203 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) {
204 ret = -ENODEV;
204 goto reset_err; 205 goto reset_err;
206 }
205 207
206 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); 208 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
207 209
208 if (vendor_id2 != 0x5370) { 210 if (vendor_id2 != 0x5370) {
209 if (vendor_id2 != 0x5374) 211 if (vendor_id2 != 0x5374) {
212 ret = -ENODEV;
210 goto reset_err; 213 goto reset_err;
211 else 214 } else {
212 printk(KERN_WARNING "ad1980: " 215 printk(KERN_WARNING "ad1980: "
213 "Found AD1981 - only 2/2 IN/OUT Channels " 216 "Found AD1981 - only 2/2 IN/OUT Channels "
214 "supported\n"); 217 "supported\n");
218 }
215 } 219 }
216 220
217 /* unmute captures and playbacks volume */ 221 /* unmute captures and playbacks volume */
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
new file mode 100644
index 00000000000..2aa40c3731d
--- /dev/null
+++ b/sound/soc/codecs/adau1373.c
@@ -0,0 +1,1414 @@
1/*
2 * Analog Devices ADAU1373 Audio Codec drive
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/delay.h>
13#include <linux/pm.h>
14#include <linux/i2c.h>
15#include <linux/slab.h>
16#include <linux/gcd.h>
17
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/tlv.h>
22#include <sound/soc.h>
23#include <sound/adau1373.h>
24
25#include "adau1373.h"
26
27struct adau1373_dai {
28 unsigned int clk_src;
29 unsigned int sysclk;
30 bool enable_src;
31 bool master;
32};
33
34struct adau1373 {
35 struct adau1373_dai dais[3];
36};
37
38#define ADAU1373_INPUT_MODE 0x00
39#define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2)
40#define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2)
41#define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2)
42#define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2)
43#define ADAU1373_LSPK_OUT 0x0d
44#define ADAU1373_RSPK_OUT 0x0e
45#define ADAU1373_LHP_OUT 0x0f
46#define ADAU1373_RHP_OUT 0x10
47#define ADAU1373_ADC_GAIN 0x11
48#define ADAU1373_LADC_MIXER 0x12
49#define ADAU1373_RADC_MIXER 0x13
50#define ADAU1373_LLINE1_MIX 0x14
51#define ADAU1373_RLINE1_MIX 0x15
52#define ADAU1373_LLINE2_MIX 0x16
53#define ADAU1373_RLINE2_MIX 0x17
54#define ADAU1373_LSPK_MIX 0x18
55#define ADAU1373_RSPK_MIX 0x19
56#define ADAU1373_LHP_MIX 0x1a
57#define ADAU1373_RHP_MIX 0x1b
58#define ADAU1373_EP_MIX 0x1c
59#define ADAU1373_HP_CTRL 0x1d
60#define ADAU1373_HP_CTRL2 0x1e
61#define ADAU1373_LS_CTRL 0x1f
62#define ADAU1373_EP_CTRL 0x21
63#define ADAU1373_MICBIAS_CTRL1 0x22
64#define ADAU1373_MICBIAS_CTRL2 0x23
65#define ADAU1373_OUTPUT_CTRL 0x24
66#define ADAU1373_PWDN_CTRL1 0x25
67#define ADAU1373_PWDN_CTRL2 0x26
68#define ADAU1373_PWDN_CTRL3 0x27
69#define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7)
70#define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7)
71#define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7)
72#define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7)
73#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7)
74#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7)
75#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7)
76#define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7)
77#define ADAU1373_HEADDECT 0x36
78#define ADAU1373_ADC_DAC_STATUS 0x37
79#define ADAU1373_ADC_CTRL 0x3c
80#define ADAU1373_DAI(x) (0x44 + (x))
81#define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2)
82#define ADAU1373_BCLKDIV(x) (0x47 + (x))
83#define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2)
84#define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2)
85#define ADAU1373_DEEMP_CTRL 0x50
86#define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x))
87#define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x))
88#define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x))
89#define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2)
90#define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2)
91#define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2)
92#define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2)
93#define ADAU1373_DAC1_PBL_VOL 0x6e
94#define ADAU1373_DAC1_PBR_VOL 0x6f
95#define ADAU1373_DAC2_PBL_VOL 0x70
96#define ADAU1373_DAC2_PBR_VOL 0x71
97#define ADAU1373_ADC_RECL_VOL 0x72
98#define ADAU1373_ADC_RECR_VOL 0x73
99#define ADAU1373_DMIC_RECL_VOL 0x74
100#define ADAU1373_DMIC_RECR_VOL 0x75
101#define ADAU1373_VOL_GAIN1 0x76
102#define ADAU1373_VOL_GAIN2 0x77
103#define ADAU1373_VOL_GAIN3 0x78
104#define ADAU1373_HPF_CTRL 0x7d
105#define ADAU1373_BASS1 0x7e
106#define ADAU1373_BASS2 0x7f
107#define ADAU1373_DRC(x) (0x80 + (x) * 0x10)
108#define ADAU1373_3D_CTRL1 0xc0
109#define ADAU1373_3D_CTRL2 0xc1
110#define ADAU1373_FDSP_SEL1 0xdc
111#define ADAU1373_FDSP_SEL2 0xdd
112#define ADAU1373_FDSP_SEL3 0xde
113#define ADAU1373_FDSP_SEL4 0xdf
114#define ADAU1373_DIGMICCTRL 0xe2
115#define ADAU1373_DIGEN 0xeb
116#define ADAU1373_SOFT_RESET 0xff
117
118
119#define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1)
120#define ADAU1373_PLL_CTRL6_PLL_EN BIT(0)
121
122#define ADAU1373_DAI_INVERT_BCLK BIT(7)
123#define ADAU1373_DAI_MASTER BIT(6)
124#define ADAU1373_DAI_INVERT_LRCLK BIT(4)
125#define ADAU1373_DAI_WLEN_16 0x0
126#define ADAU1373_DAI_WLEN_20 0x4
127#define ADAU1373_DAI_WLEN_24 0x8
128#define ADAU1373_DAI_WLEN_32 0xc
129#define ADAU1373_DAI_WLEN_MASK 0xc
130#define ADAU1373_DAI_FORMAT_RIGHT_J 0x0
131#define ADAU1373_DAI_FORMAT_LEFT_J 0x1
132#define ADAU1373_DAI_FORMAT_I2S 0x2
133#define ADAU1373_DAI_FORMAT_DSP 0x3
134
135#define ADAU1373_BCLKDIV_SOURCE BIT(5)
136#define ADAU1373_BCLKDIV_32 0x03
137#define ADAU1373_BCLKDIV_64 0x02
138#define ADAU1373_BCLKDIV_128 0x01
139#define ADAU1373_BCLKDIV_256 0x00
140
141#define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0)
142#define ADAU1373_ADC_CTRL_RESET BIT(1)
143#define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2)
144
145#define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3)
146#define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2)
147
148#define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0)
149
150#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
151#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
152
153static const uint8_t adau1373_default_regs[] = {
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */
161 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */
171 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
172 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */
173 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
174 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */
175 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
177 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */
183 0x00, 0x1f, 0x0f, 0x00, 0x00,
184};
185
186static const unsigned int adau1373_out_tlv[] = {
187 TLV_DB_RANGE_HEAD(4),
188 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
189 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
190 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
191 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
192};
193
194static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0);
195static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1);
196static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1);
197
198static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0);
199static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0);
200static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0);
201
202static const char *adau1373_fdsp_sel_text[] = {
203 "None",
204 "Channel 1",
205 "Channel 2",
206 "Channel 3",
207 "Channel 4",
208 "Channel 5",
209};
210
211static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
212 ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
213static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
214 ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
215static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
216 ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
217static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
218 ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
219static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
220 ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
221
222static const char *adau1373_hpf_cutoff_text[] = {
223 "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz",
224 "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz",
225 "800Hz",
226};
227
228static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
229 ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
230
231static const char *adau1373_bass_lpf_cutoff_text[] = {
232 "801Hz", "1001Hz",
233};
234
235static const char *adau1373_bass_clip_level_text[] = {
236 "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875",
237};
238
239static const unsigned int adau1373_bass_clip_level_values[] = {
240 1, 2, 3, 4, 5, 6, 7,
241};
242
243static const char *adau1373_bass_hpf_cutoff_text[] = {
244 "158Hz", "232Hz", "347Hz", "520Hz",
245};
246
247static const unsigned int adau1373_bass_tlv[] = {
248 TLV_DB_RANGE_HEAD(4),
249 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
250 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
251 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
252};
253
254static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
255 ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
256
257static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
258 ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
259 adau1373_bass_clip_level_values);
260
261static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
262 ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
263
264static const char *adau1373_3d_level_text[] = {
265 "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%",
266 "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%",
267 "80%", "86.67", "99.33%", "100%"
268};
269
270static const char *adau1373_3d_cutoff_text[] = {
271 "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs",
272 "0.16875 fs", "0.27083 fs"
273};
274
275static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
276 ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
277static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
278 ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
279
280static const unsigned int adau1373_3d_tlv[] = {
281 TLV_DB_RANGE_HEAD(2),
282 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
283 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120),
284};
285
286static const char *adau1373_lr_mux_text[] = {
287 "Mute",
288 "Right Channel (L+R)",
289 "Left Channel (L+R)",
290 "Stereo",
291};
292
293static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
294 ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
295static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
296 ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
297static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
298 ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
299
300static const struct snd_kcontrol_new adau1373_controls[] = {
301 SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0),
302 ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
303 SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1),
304 ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
305 SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2),
306 ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
307
308 SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL,
309 ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
310 SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL,
311 ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
312
313 SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0),
314 ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
315 SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1),
316 ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
317 SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2),
318 ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
319
320 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL,
321 ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
322 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL,
323 ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
324
325 SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0),
326 ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv),
327 SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT,
328 ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv),
329 SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT,
330 ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv),
331
332 SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0),
333 ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv),
334 SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1),
335 ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv),
336 SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2),
337 ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv),
338 SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3),
339 ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv),
340
341 SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0,
342 adau1373_ep_tlv),
343
344 SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5,
345 1, 0, adau1373_gain_boost_tlv),
346 SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3,
347 1, 0, adau1373_gain_boost_tlv),
348 SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1,
349 1, 0, adau1373_gain_boost_tlv),
350 SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5,
351 1, 0, adau1373_gain_boost_tlv),
352 SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3,
353 1, 0, adau1373_gain_boost_tlv),
354 SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1,
355 1, 0, adau1373_gain_boost_tlv),
356 SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7,
357 1, 0, adau1373_gain_boost_tlv),
358 SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5,
359 1, 0, adau1373_gain_boost_tlv),
360 SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3,
361 1, 0, adau1373_gain_boost_tlv),
362 SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1,
363 1, 0, adau1373_gain_boost_tlv),
364
365 SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4,
366 1, 0, adau1373_input_boost_tlv),
367 SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5,
368 1, 0, adau1373_input_boost_tlv),
369 SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6,
370 1, 0, adau1373_input_boost_tlv),
371 SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7,
372 1, 0, adau1373_input_boost_tlv),
373
374 SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3,
375 1, 0, adau1373_speaker_boost_tlv),
376
377 SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum),
378 SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum),
379
380 SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum),
381 SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0),
382 SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum),
383
384 SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum),
385 SOC_VALUE_ENUM("Bass Clip Level Threshold",
386 adau1373_bass_clip_level_enum),
387 SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum),
388 SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0),
389 SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0,
390 adau1373_bass_tlv),
391 SOC_ENUM("Bass Channel", adau1373_bass_channel_enum),
392
393 SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum),
394 SOC_ENUM("3D Level", adau1373_3d_level_enum),
395 SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0),
396 SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0,
397 adau1373_3d_tlv),
398 SOC_ENUM("3D Channel", adau1373_bass_channel_enum),
399
400 SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0),
401};
402
403static const struct snd_kcontrol_new adau1373_lineout2_controls[] = {
404 SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1),
405 ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv),
406 SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum),
407};
408
409static const struct snd_kcontrol_new adau1373_drc_controls[] = {
410 SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum),
411 SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum),
412 SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum),
413};
414
415static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 unsigned int pll_id = w->name[3] - '1';
420 unsigned int val;
421
422 if (SND_SOC_DAPM_EVENT_ON(event))
423 val = ADAU1373_PLL_CTRL6_PLL_EN;
424 else
425 val = 0;
426
427 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
428 ADAU1373_PLL_CTRL6_PLL_EN, val);
429
430 if (SND_SOC_DAPM_EVENT_ON(event))
431 mdelay(5);
432
433 return 0;
434}
435
436static const char *adau1373_decimator_text[] = {
437 "ADC",
438 "DMIC1",
439};
440
441static const struct soc_enum adau1373_decimator_enum =
442 SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text);
443
444static const struct snd_kcontrol_new adau1373_decimator_mux =
445 SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
446
447static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = {
448 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0),
449 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0),
450 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0),
451 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0),
452 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0),
453};
454
455static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = {
456 SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0),
457 SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0),
458 SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0),
459 SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0),
460 SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0),
461};
462
463#define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \
464const struct snd_kcontrol_new _name[] = { \
465 SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \
466 SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \
467 SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \
468 SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \
469 SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \
470 SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \
471 SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \
472 SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \
473}
474
475static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls,
476 ADAU1373_LLINE1_MIX);
477static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls,
478 ADAU1373_RLINE1_MIX);
479static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls,
480 ADAU1373_LLINE2_MIX);
481static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls,
482 ADAU1373_RLINE2_MIX);
483static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls,
484 ADAU1373_LSPK_MIX);
485static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls,
486 ADAU1373_RSPK_MIX);
487static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls,
488 ADAU1373_EP_MIX);
489
490static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = {
491 SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0),
492 SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0),
493 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0),
494 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0),
495 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0),
496 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0),
497};
498
499static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = {
500 SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0),
501 SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0),
502 SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0),
503 SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0),
504 SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0),
505 SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0),
506};
507
508#define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \
509const struct snd_kcontrol_new _name[] = { \
510 SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \
511 SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \
512 SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \
513 SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \
514 SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \
515 SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \
516 SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \
517}
518
519static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls,
520 ADAU1373_DIN_MIX_CTRL(0));
521static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls,
522 ADAU1373_DIN_MIX_CTRL(1));
523static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls,
524 ADAU1373_DIN_MIX_CTRL(2));
525static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls,
526 ADAU1373_DIN_MIX_CTRL(3));
527static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls,
528 ADAU1373_DIN_MIX_CTRL(4));
529
530#define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \
531const struct snd_kcontrol_new _name[] = { \
532 SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \
533 SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \
534 SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \
535 SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \
536 SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \
537}
538
539static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls,
540 ADAU1373_DOUT_MIX_CTRL(0));
541static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls,
542 ADAU1373_DOUT_MIX_CTRL(1));
543static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls,
544 ADAU1373_DOUT_MIX_CTRL(2));
545static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls,
546 ADAU1373_DOUT_MIX_CTRL(3));
547static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls,
548 ADAU1373_DOUT_MIX_CTRL(4));
549
550static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
551 /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that
552 * doesn't seem to be the case. */
553 SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0),
554 SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0),
555
556 SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0),
557 SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0),
558
559 SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0,
560 &adau1373_decimator_mux),
561
562 SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0),
563 SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0),
564
565 SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0),
566 SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0),
567 SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0),
568 SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0),
569
570 SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0),
571 SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0),
572 SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0),
573 SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0),
574
575 SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
576 adau1373_left_adc_mixer_controls),
577 SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
578 adau1373_right_adc_mixer_controls),
579
580 SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0,
581 adau1373_left_line2_mixer_controls),
582 SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0,
583 adau1373_right_line2_mixer_controls),
584 SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0,
585 adau1373_left_line1_mixer_controls),
586 SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0,
587 adau1373_right_line1_mixer_controls),
588
589 SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0,
590 adau1373_ep_mixer_controls),
591 SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0,
592 adau1373_left_spk_mixer_controls),
593 SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0,
594 adau1373_right_spk_mixer_controls),
595 SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
596 adau1373_left_hp_mixer_controls),
597 SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
598 adau1373_right_hp_mixer_controls),
599 SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0,
600 NULL, 0),
601
602 SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0,
603 NULL, 0),
604 SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0,
605 NULL, 0),
606 SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0,
607 NULL, 0),
608 SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0,
609 NULL, 0),
610 SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0,
611 NULL, 0),
612 SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0,
613 NULL, 0),
614 SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0,
615 NULL, 0),
616 SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0,
617 NULL, 0),
618 SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0,
619 NULL, 0),
620
621 SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
622 SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
623 SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
624 SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
625 SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
626 SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
627
628 SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0,
629 adau1373_dsp_channel1_mixer_controls),
630 SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0,
631 adau1373_dsp_channel2_mixer_controls),
632 SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0,
633 adau1373_dsp_channel3_mixer_controls),
634 SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0,
635 adau1373_dsp_channel4_mixer_controls),
636 SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0,
637 adau1373_dsp_channel5_mixer_controls),
638
639 SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0,
640 adau1373_aif1_mixer_controls),
641 SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0,
642 adau1373_aif2_mixer_controls),
643 SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0,
644 adau1373_aif3_mixer_controls),
645 SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
646 adau1373_dac1_mixer_controls),
647 SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
648 adau1373_dac2_mixer_controls),
649
650 SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0),
651 SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0),
652 SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0),
653 SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0),
654 SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0),
655
656 SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
657 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
658 SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
659 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
660 SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0),
661 SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0),
662
663 SND_SOC_DAPM_INPUT("AIN1L"),
664 SND_SOC_DAPM_INPUT("AIN1R"),
665 SND_SOC_DAPM_INPUT("AIN2L"),
666 SND_SOC_DAPM_INPUT("AIN2R"),
667 SND_SOC_DAPM_INPUT("AIN3L"),
668 SND_SOC_DAPM_INPUT("AIN3R"),
669 SND_SOC_DAPM_INPUT("AIN4L"),
670 SND_SOC_DAPM_INPUT("AIN4R"),
671
672 SND_SOC_DAPM_INPUT("DMIC1DAT"),
673 SND_SOC_DAPM_INPUT("DMIC2DAT"),
674
675 SND_SOC_DAPM_OUTPUT("LOUT1L"),
676 SND_SOC_DAPM_OUTPUT("LOUT1R"),
677 SND_SOC_DAPM_OUTPUT("LOUT2L"),
678 SND_SOC_DAPM_OUTPUT("LOUT2R"),
679 SND_SOC_DAPM_OUTPUT("HPL"),
680 SND_SOC_DAPM_OUTPUT("HPR"),
681 SND_SOC_DAPM_OUTPUT("SPKL"),
682 SND_SOC_DAPM_OUTPUT("SPKR"),
683 SND_SOC_DAPM_OUTPUT("EP"),
684};
685
686static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
687 struct snd_soc_dapm_widget *sink)
688{
689 struct snd_soc_codec *codec = source->codec;
690 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
691 unsigned int dai;
692 const char *clk;
693
694 dai = sink->name[3] - '1';
695
696 if (!adau1373->dais[dai].master)
697 return 0;
698
699 if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1)
700 clk = "SYSCLK1";
701 else
702 clk = "SYSCLK2";
703
704 return strcmp(source->name, clk) == 0;
705}
706
707static int adau1373_check_src(struct snd_soc_dapm_widget *source,
708 struct snd_soc_dapm_widget *sink)
709{
710 struct snd_soc_codec *codec = source->codec;
711 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
712 unsigned int dai;
713
714 dai = sink->name[3] - '1';
715
716 return adau1373->dais[dai].enable_src;
717}
718
719#define DSP_CHANNEL_MIXER_ROUTES(_sink) \
720 { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \
721 { _sink, "DMIC2 Switch", "DMIC2" }, \
722 { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \
723 { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \
724 { _sink, "AIF1 Switch", "AIF1 IN" }, \
725 { _sink, "AIF2 Switch", "AIF2 IN" }, \
726 { _sink, "AIF3 Switch", "AIF3 IN" }
727
728#define DSP_OUTPUT_MIXER_ROUTES(_sink) \
729 { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \
730 { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \
731 { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \
732 { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \
733 { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" }
734
735#define LEFT_OUTPUT_MIXER_ROUTES(_sink) \
736 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
737 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
738 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
739 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
740 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
741 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
742 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
743 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
744
745#define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \
746 { _sink, "Right DAC2 Switch", "Right DAC2" }, \
747 { _sink, "Left DAC2 Switch", "Left DAC2" }, \
748 { _sink, "Right DAC1 Switch", "Right DAC1" }, \
749 { _sink, "Left DAC1 Switch", "Left DAC1" }, \
750 { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
751 { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
752 { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
753 { _sink, "Input 4 Bypass Switch", "IN4PGA" }
754
755static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
756 { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" },
757 { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" },
758 { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" },
759 { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" },
760 { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" },
761
762 { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" },
763 { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" },
764 { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" },
765 { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" },
766 { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" },
767
768 { "Left ADC", NULL, "Left ADC Mixer" },
769 { "Right ADC", NULL, "Right ADC Mixer" },
770
771 { "Decimator Mux", "ADC", "Left ADC" },
772 { "Decimator Mux", "ADC", "Right ADC" },
773 { "Decimator Mux", "DMIC1", "DMIC1" },
774
775 DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"),
776 DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"),
777 DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"),
778 DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"),
779 DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"),
780
781 DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"),
782 DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"),
783 DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"),
784 DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"),
785 DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"),
786
787 { "AIF1 OUT", NULL, "AIF1 Mixer" },
788 { "AIF2 OUT", NULL, "AIF2 Mixer" },
789 { "AIF3 OUT", NULL, "AIF3 Mixer" },
790 { "Left DAC1", NULL, "DAC1 Mixer" },
791 { "Right DAC1", NULL, "DAC1 Mixer" },
792 { "Left DAC2", NULL, "DAC2 Mixer" },
793 { "Right DAC2", NULL, "DAC2 Mixer" },
794
795 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"),
796 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"),
797 LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"),
798 RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"),
799 LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"),
800 RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"),
801
802 { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" },
803 { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" },
804 { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
805 { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
806 { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
807 { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
808 { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" },
809 { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" },
810 { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
811 { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
812 { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
813 { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
814
815 { "Left Headphone Mixer", NULL, "Headphone Enable" },
816 { "Right Headphone Mixer", NULL, "Headphone Enable" },
817
818 { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" },
819 { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" },
820 { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" },
821 { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" },
822 { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" },
823 { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" },
824 { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" },
825 { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" },
826
827 { "LOUT1L", NULL, "Left Lineout1 Mixer" },
828 { "LOUT1R", NULL, "Right Lineout1 Mixer" },
829 { "LOUT2L", NULL, "Left Lineout2 Mixer" },
830 { "LOUT2R", NULL, "Right Lineout2 Mixer" },
831 { "SPKL", NULL, "Left Speaker Mixer" },
832 { "SPKR", NULL, "Right Speaker Mixer" },
833 { "HPL", NULL, "Left Headphone Mixer" },
834 { "HPR", NULL, "Right Headphone Mixer" },
835 { "EP", NULL, "Earpiece Mixer" },
836
837 { "IN1PGA", NULL, "AIN1L" },
838 { "IN2PGA", NULL, "AIN2L" },
839 { "IN3PGA", NULL, "AIN3L" },
840 { "IN4PGA", NULL, "AIN4L" },
841 { "IN1PGA", NULL, "AIN1R" },
842 { "IN2PGA", NULL, "AIN2R" },
843 { "IN3PGA", NULL, "AIN3R" },
844 { "IN4PGA", NULL, "AIN4R" },
845
846 { "SYSCLK1", NULL, "PLL1" },
847 { "SYSCLK2", NULL, "PLL2" },
848
849 { "Left DAC1", NULL, "SYSCLK1" },
850 { "Right DAC1", NULL, "SYSCLK1" },
851 { "Left DAC2", NULL, "SYSCLK1" },
852 { "Right DAC2", NULL, "SYSCLK1" },
853 { "Left ADC", NULL, "SYSCLK1" },
854 { "Right ADC", NULL, "SYSCLK1" },
855
856 { "DSP", NULL, "SYSCLK1" },
857
858 { "AIF1 Mixer", NULL, "DSP" },
859 { "AIF2 Mixer", NULL, "DSP" },
860 { "AIF3 Mixer", NULL, "DSP" },
861 { "DAC1 Mixer", NULL, "DSP" },
862 { "DAC2 Mixer", NULL, "DSP" },
863 { "DAC1 Mixer", NULL, "Playback Engine A" },
864 { "DAC2 Mixer", NULL, "Playback Engine B" },
865 { "Left ADC Mixer", NULL, "Recording Engine A" },
866 { "Right ADC Mixer", NULL, "Recording Engine A" },
867
868 { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
869 { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
870 { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
871 { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
872 { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
873 { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
874
875 { "AIF1 IN", NULL, "AIF1 CLK" },
876 { "AIF1 OUT", NULL, "AIF1 CLK" },
877 { "AIF2 IN", NULL, "AIF2 CLK" },
878 { "AIF2 OUT", NULL, "AIF2 CLK" },
879 { "AIF3 IN", NULL, "AIF3 CLK" },
880 { "AIF3 OUT", NULL, "AIF3 CLK" },
881 { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src },
882 { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src },
883 { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src },
884 { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src },
885 { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src },
886 { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src },
887
888 { "DMIC1", NULL, "DMIC1DAT" },
889 { "DMIC1", NULL, "SYSCLK1" },
890 { "DMIC1", NULL, "Recording Engine A" },
891 { "DMIC2", NULL, "DMIC2DAT" },
892 { "DMIC2", NULL, "SYSCLK1" },
893 { "DMIC2", NULL, "Recording Engine B" },
894};
895
896static int adau1373_hw_params(struct snd_pcm_substream *substream,
897 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
898{
899 struct snd_soc_codec *codec = dai->codec;
900 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
901 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
902 unsigned int div;
903 unsigned int freq;
904 unsigned int ctrl;
905
906 freq = adau1373_dai->sysclk;
907
908 if (freq % params_rate(params) != 0)
909 return -EINVAL;
910
911 switch (freq / params_rate(params)) {
912 case 1024: /* sysclk / 256 */
913 div = 0;
914 break;
915 case 1536: /* 2/3 sysclk / 256 */
916 div = 1;
917 break;
918 case 2048: /* 1/2 sysclk / 256 */
919 div = 2;
920 break;
921 case 3072: /* 1/3 sysclk / 256 */
922 div = 3;
923 break;
924 case 4096: /* 1/4 sysclk / 256 */
925 div = 4;
926 break;
927 case 6144: /* 1/6 sysclk / 256 */
928 div = 5;
929 break;
930 case 5632: /* 2/11 sysclk / 256 */
931 div = 6;
932 break;
933 default:
934 return -EINVAL;
935 }
936
937 adau1373_dai->enable_src = (div != 0);
938
939 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
940 ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
941
942 switch (params_format(params)) {
943 case SNDRV_PCM_FORMAT_S16_LE:
944 ctrl = ADAU1373_DAI_WLEN_16;
945 break;
946 case SNDRV_PCM_FORMAT_S20_3LE:
947 ctrl = ADAU1373_DAI_WLEN_20;
948 break;
949 case SNDRV_PCM_FORMAT_S24_LE:
950 ctrl = ADAU1373_DAI_WLEN_24;
951 break;
952 case SNDRV_PCM_FORMAT_S32_LE:
953 ctrl = ADAU1373_DAI_WLEN_32;
954 break;
955 default:
956 return -EINVAL;
957 }
958
959 return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
960 ADAU1373_DAI_WLEN_MASK, ctrl);
961}
962
963static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
964{
965 struct snd_soc_codec *codec = dai->codec;
966 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
967 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
968 unsigned int ctrl;
969
970 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
971 case SND_SOC_DAIFMT_CBM_CFM:
972 ctrl = ADAU1373_DAI_MASTER;
973 adau1373_dai->master = true;
974 break;
975 case SND_SOC_DAIFMT_CBS_CFS:
976 ctrl = 0;
977 adau1373_dai->master = true;
978 break;
979 default:
980 return -EINVAL;
981 }
982
983 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
984 case SND_SOC_DAIFMT_I2S:
985 ctrl |= ADAU1373_DAI_FORMAT_I2S;
986 break;
987 case SND_SOC_DAIFMT_LEFT_J:
988 ctrl |= ADAU1373_DAI_FORMAT_LEFT_J;
989 break;
990 case SND_SOC_DAIFMT_RIGHT_J:
991 ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J;
992 break;
993 case SND_SOC_DAIFMT_DSP_B:
994 ctrl |= ADAU1373_DAI_FORMAT_DSP;
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1001 case SND_SOC_DAIFMT_NB_NF:
1002 break;
1003 case SND_SOC_DAIFMT_IB_NF:
1004 ctrl |= ADAU1373_DAI_INVERT_BCLK;
1005 break;
1006 case SND_SOC_DAIFMT_NB_IF:
1007 ctrl |= ADAU1373_DAI_INVERT_LRCLK;
1008 break;
1009 case SND_SOC_DAIFMT_IB_IF:
1010 ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK;
1011 break;
1012 default:
1013 return -EINVAL;
1014 }
1015
1016 snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
1017 ~ADAU1373_DAI_WLEN_MASK, ctrl);
1018
1019 return 0;
1020}
1021
1022static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
1023 int clk_id, unsigned int freq, int dir)
1024{
1025 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
1026 struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
1027
1028 switch (clk_id) {
1029 case ADAU1373_CLK_SRC_PLL1:
1030 case ADAU1373_CLK_SRC_PLL2:
1031 break;
1032 default:
1033 return -EINVAL;
1034 }
1035
1036 adau1373_dai->sysclk = freq;
1037 adau1373_dai->clk_src = clk_id;
1038
1039 snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id),
1040 ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
1041
1042 return 0;
1043}
1044
1045static const struct snd_soc_dai_ops adau1373_dai_ops = {
1046 .hw_params = adau1373_hw_params,
1047 .set_sysclk = adau1373_set_dai_sysclk,
1048 .set_fmt = adau1373_set_dai_fmt,
1049};
1050
1051#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1052 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1053
1054static struct snd_soc_dai_driver adau1373_dai_driver[] = {
1055 {
1056 .id = 0,
1057 .name = "adau1373-aif1",
1058 .playback = {
1059 .stream_name = "AIF1 Playback",
1060 .channels_min = 2,
1061 .channels_max = 2,
1062 .rates = SNDRV_PCM_RATE_8000_48000,
1063 .formats = ADAU1373_FORMATS,
1064 },
1065 .capture = {
1066 .stream_name = "AIF1 Capture",
1067 .channels_min = 2,
1068 .channels_max = 2,
1069 .rates = SNDRV_PCM_RATE_8000_48000,
1070 .formats = ADAU1373_FORMATS,
1071 },
1072 .ops = &adau1373_dai_ops,
1073 .symmetric_rates = 1,
1074 },
1075 {
1076 .id = 1,
1077 .name = "adau1373-aif2",
1078 .playback = {
1079 .stream_name = "AIF2 Playback",
1080 .channels_min = 2,
1081 .channels_max = 2,
1082 .rates = SNDRV_PCM_RATE_8000_48000,
1083 .formats = ADAU1373_FORMATS,
1084 },
1085 .capture = {
1086 .stream_name = "AIF2 Capture",
1087 .channels_min = 2,
1088 .channels_max = 2,
1089 .rates = SNDRV_PCM_RATE_8000_48000,
1090 .formats = ADAU1373_FORMATS,
1091 },
1092 .ops = &adau1373_dai_ops,
1093 .symmetric_rates = 1,
1094 },
1095 {
1096 .id = 2,
1097 .name = "adau1373-aif3",
1098 .playback = {
1099 .stream_name = "AIF3 Playback",
1100 .channels_min = 2,
1101 .channels_max = 2,
1102 .rates = SNDRV_PCM_RATE_8000_48000,
1103 .formats = ADAU1373_FORMATS,
1104 },
1105 .capture = {
1106 .stream_name = "AIF3 Capture",
1107 .channels_min = 2,
1108 .channels_max = 2,
1109 .rates = SNDRV_PCM_RATE_8000_48000,
1110 .formats = ADAU1373_FORMATS,
1111 },
1112 .ops = &adau1373_dai_ops,
1113 .symmetric_rates = 1,
1114 },
1115};
1116
1117static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1118 int source, unsigned int freq_in, unsigned int freq_out)
1119{
1120 unsigned int dpll_div = 0;
1121 unsigned int x, r, n, m, i, j, mode;
1122
1123 switch (pll_id) {
1124 case ADAU1373_PLL1:
1125 case ADAU1373_PLL2:
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130
1131 switch (source) {
1132 case ADAU1373_PLL_SRC_BCLK1:
1133 case ADAU1373_PLL_SRC_BCLK2:
1134 case ADAU1373_PLL_SRC_BCLK3:
1135 case ADAU1373_PLL_SRC_LRCLK1:
1136 case ADAU1373_PLL_SRC_LRCLK2:
1137 case ADAU1373_PLL_SRC_LRCLK3:
1138 case ADAU1373_PLL_SRC_MCLK1:
1139 case ADAU1373_PLL_SRC_MCLK2:
1140 case ADAU1373_PLL_SRC_GPIO1:
1141 case ADAU1373_PLL_SRC_GPIO2:
1142 case ADAU1373_PLL_SRC_GPIO3:
1143 case ADAU1373_PLL_SRC_GPIO4:
1144 break;
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 if (freq_in < 7813 || freq_in > 27000000)
1150 return -EINVAL;
1151
1152 if (freq_out < 45158000 || freq_out > 49152000)
1153 return -EINVAL;
1154
1155 /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the
1156 * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */
1157 while (freq_in < 8000000) {
1158 freq_in *= 2;
1159 dpll_div++;
1160 }
1161
1162 if (freq_out % freq_in != 0) {
1163 /* fout = fin * (r + (n/m)) / x */
1164 x = DIV_ROUND_UP(freq_in, 13500000);
1165 freq_in /= x;
1166 r = freq_out / freq_in;
1167 i = freq_out % freq_in;
1168 j = gcd(i, freq_in);
1169 n = i / j;
1170 m = freq_in / j;
1171 x--;
1172 mode = 1;
1173 } else {
1174 /* fout = fin / r */
1175 r = freq_out / freq_in;
1176 n = 0;
1177 m = 0;
1178 x = 0;
1179 mode = 0;
1180 }
1181
1182 if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
1183 return -EINVAL;
1184
1185 if (dpll_div) {
1186 dpll_div = 11 - dpll_div;
1187 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1188 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
1189 } else {
1190 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
1191 ADAU1373_PLL_CTRL6_DPLL_BYPASS,
1192 ADAU1373_PLL_CTRL6_DPLL_BYPASS);
1193 }
1194
1195 snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id),
1196 (source << 4) | dpll_div);
1197 snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
1198 snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
1199 snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
1200 snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
1201 snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id),
1202 (r << 3) | (x << 1) | mode);
1203
1204 /* Set sysclk to pll_rate / 4 */
1205 snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
1206
1207 return 0;
1208}
1209
1210static void adau1373_load_drc_settings(struct snd_soc_codec *codec,
1211 unsigned int nr, uint8_t *drc)
1212{
1213 unsigned int i;
1214
1215 for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
1216 snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]);
1217}
1218
1219static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
1220{
1221 switch (micbias) {
1222 case ADAU1373_MICBIAS_2_9V:
1223 case ADAU1373_MICBIAS_2_2V:
1224 case ADAU1373_MICBIAS_2_6V:
1225 case ADAU1373_MICBIAS_1_8V:
1226 return true;
1227 default:
1228 break;
1229 }
1230 return false;
1231}
1232
1233static int adau1373_probe(struct snd_soc_codec *codec)
1234{
1235 struct adau1373_platform_data *pdata = codec->dev->platform_data;
1236 bool lineout_differential = false;
1237 unsigned int val;
1238 int ret;
1239 int i;
1240
1241 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
1242 if (ret) {
1243 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
1244 return ret;
1245 }
1246
1247 codec->dapm.idle_bias_off = true;
1248
1249 if (pdata) {
1250 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
1251 return -EINVAL;
1252
1253 if (!adau1373_valid_micbias(pdata->micbias1) ||
1254 !adau1373_valid_micbias(pdata->micbias2))
1255 return -EINVAL;
1256
1257 for (i = 0; i < pdata->num_drc; ++i) {
1258 adau1373_load_drc_settings(codec, i,
1259 pdata->drc_setting[i]);
1260 }
1261
1262 snd_soc_add_controls(codec, adau1373_drc_controls,
1263 pdata->num_drc);
1264
1265 val = 0;
1266 for (i = 0; i < 4; ++i) {
1267 if (pdata->input_differential[i])
1268 val |= BIT(i);
1269 }
1270 snd_soc_write(codec, ADAU1373_INPUT_MODE, val);
1271
1272 val = 0;
1273 if (pdata->lineout_differential)
1274 val |= ADAU1373_OUTPUT_CTRL_LDIFF;
1275 if (pdata->lineout_ground_sense)
1276 val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
1277 snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val);
1278
1279 lineout_differential = pdata->lineout_differential;
1280
1281 snd_soc_write(codec, ADAU1373_EP_CTRL,
1282 (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
1283 (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
1284 }
1285
1286 if (!lineout_differential) {
1287 snd_soc_add_controls(codec, adau1373_lineout2_controls,
1288 ARRAY_SIZE(adau1373_lineout2_controls));
1289 }
1290
1291 snd_soc_write(codec, ADAU1373_ADC_CTRL,
1292 ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
1293
1294 return 0;
1295}
1296
1297static int adau1373_set_bias_level(struct snd_soc_codec *codec,
1298 enum snd_soc_bias_level level)
1299{
1300 switch (level) {
1301 case SND_SOC_BIAS_ON:
1302 break;
1303 case SND_SOC_BIAS_PREPARE:
1304 break;
1305 case SND_SOC_BIAS_STANDBY:
1306 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1307 ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
1308 break;
1309 case SND_SOC_BIAS_OFF:
1310 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
1311 ADAU1373_PWDN_CTRL3_PWR_EN, 0);
1312 break;
1313 }
1314 codec->dapm.bias_level = level;
1315 return 0;
1316}
1317
1318static int adau1373_remove(struct snd_soc_codec *codec)
1319{
1320 adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1321 return 0;
1322}
1323
1324static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{
1326 return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327}
1328
1329static int adau1373_resume(struct snd_soc_codec *codec)
1330{
1331 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1332 snd_soc_cache_sync(codec);
1333
1334 return 0;
1335}
1336
1337static struct snd_soc_codec_driver adau1373_codec_driver = {
1338 .probe = adau1373_probe,
1339 .remove = adau1373_remove,
1340 .suspend = adau1373_suspend,
1341 .resume = adau1373_resume,
1342 .set_bias_level = adau1373_set_bias_level,
1343 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1344 .reg_cache_default = adau1373_default_regs,
1345 .reg_word_size = sizeof(uint8_t),
1346
1347 .set_pll = adau1373_set_pll,
1348
1349 .controls = adau1373_controls,
1350 .num_controls = ARRAY_SIZE(adau1373_controls),
1351 .dapm_widgets = adau1373_dapm_widgets,
1352 .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
1353 .dapm_routes = adau1373_dapm_routes,
1354 .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
1355};
1356
1357static int __devinit adau1373_i2c_probe(struct i2c_client *client,
1358 const struct i2c_device_id *id)
1359{
1360 struct adau1373 *adau1373;
1361 int ret;
1362
1363 adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL);
1364 if (!adau1373)
1365 return -ENOMEM;
1366
1367 dev_set_drvdata(&client->dev, adau1373);
1368
1369 ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
1370 adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
1371 if (ret < 0)
1372 kfree(adau1373);
1373
1374 return ret;
1375}
1376
1377static int __devexit adau1373_i2c_remove(struct i2c_client *client)
1378{
1379 snd_soc_unregister_codec(&client->dev);
1380 kfree(dev_get_drvdata(&client->dev));
1381 return 0;
1382}
1383
1384static const struct i2c_device_id adau1373_i2c_id[] = {
1385 { "adau1373", 0 },
1386 { }
1387};
1388MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
1389
1390static struct i2c_driver adau1373_i2c_driver = {
1391 .driver = {
1392 .name = "adau1373",
1393 .owner = THIS_MODULE,
1394 },
1395 .probe = adau1373_i2c_probe,
1396 .remove = __devexit_p(adau1373_i2c_remove),
1397 .id_table = adau1373_i2c_id,
1398};
1399
1400static int __init adau1373_init(void)
1401{
1402 return i2c_add_driver(&adau1373_i2c_driver);
1403}
1404module_init(adau1373_init);
1405
1406static void __exit adau1373_exit(void)
1407{
1408 i2c_del_driver(&adau1373_i2c_driver);
1409}
1410module_exit(adau1373_exit);
1411
1412MODULE_DESCRIPTION("ASoC ADAU1373 driver");
1413MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1414MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h
new file mode 100644
index 00000000000..c6ab5530760
--- /dev/null
+++ b/sound/soc/codecs/adau1373.h
@@ -0,0 +1,29 @@
1#ifndef __ADAU1373_H__
2#define __ADAU1373_H__
3
4enum adau1373_pll_src {
5 ADAU1373_PLL_SRC_MCLK1 = 0,
6 ADAU1373_PLL_SRC_BCLK1 = 1,
7 ADAU1373_PLL_SRC_BCLK2 = 2,
8 ADAU1373_PLL_SRC_BCLK3 = 3,
9 ADAU1373_PLL_SRC_LRCLK1 = 4,
10 ADAU1373_PLL_SRC_LRCLK2 = 5,
11 ADAU1373_PLL_SRC_LRCLK3 = 6,
12 ADAU1373_PLL_SRC_GPIO1 = 7,
13 ADAU1373_PLL_SRC_GPIO2 = 8,
14 ADAU1373_PLL_SRC_GPIO3 = 9,
15 ADAU1373_PLL_SRC_GPIO4 = 10,
16 ADAU1373_PLL_SRC_MCLK2 = 11,
17};
18
19enum adau1373_pll {
20 ADAU1373_PLL1 = 0,
21 ADAU1373_PLL2 = 1,
22};
23
24enum adau1373_clk_src {
25 ADAU1373_CLK_SRC_PLL1 = 0,
26 ADAU1373_CLK_SRC_PLL2 = 1,
27};
28
29#endif
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 300c04b70e7..f9f08948e5e 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -523,7 +523,8 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
523} 523}
524 524
525static int adav80x_set_sysclk(struct snd_soc_codec *codec, 525static int adav80x_set_sysclk(struct snd_soc_codec *codec,
526 int clk_id, unsigned int freq, int dir) 526 int clk_id, int source,
527 unsigned int freq, int dir)
527{ 528{
528 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 529 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
529 530
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index eecffb54894..05173159507 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
41struct alc5623_priv { 41struct alc5623_priv {
42 enum snd_soc_control_type control_type; 42 enum snd_soc_control_type control_type;
43 void *control_data; 43 void *control_data;
44 struct mutex mutex;
45 u8 id; 44 u8 id;
46 unsigned int sysclk; 45 unsigned int sysclk;
47 u16 reg_cache[ALC5623_VENDOR_ID2+2]; 46 u16 reg_cache[ALC5623_VENDOR_ID2+2];
@@ -1052,7 +1051,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
1052 i2c_set_clientdata(client, alc5623); 1051 i2c_set_clientdata(client, alc5623);
1053 alc5623->control_data = client; 1052 alc5623->control_data = client;
1054 alc5623->control_type = SND_SOC_I2C; 1053 alc5623->control_type = SND_SOC_I2C;
1055 mutex_init(&alc5623->mutex);
1056 1054
1057 ret = snd_soc_register_codec(&client->dev, 1055 ret = snd_soc_register_codec(&client->dev,
1058 &soc_codec_device_alc5623, &alc5623_dai, 1); 1056 &soc_codec_device_alc5623, &alc5623_dai, 1);
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7e4066e131e..91130fbc691 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/driver.h> 20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/tlv.h> 25#include <sound/tlv.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -1436,10 +1437,17 @@ static const struct i2c_device_id sgtl5000_id[] = {
1436 1437
1437MODULE_DEVICE_TABLE(i2c, sgtl5000_id); 1438MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1438 1439
1440static const struct of_device_id sgtl5000_dt_ids[] = {
1441 { .compatible = "fsl,sgtl5000", },
1442 { /* sentinel */ }
1443};
1444MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);
1445
1439static struct i2c_driver sgtl5000_i2c_driver = { 1446static struct i2c_driver sgtl5000_i2c_driver = {
1440 .driver = { 1447 .driver = {
1441 .name = "sgtl5000", 1448 .name = "sgtl5000",
1442 .owner = THIS_MODULE, 1449 .owner = THIS_MODULE,
1450 .of_match_table = sgtl5000_dt_ids,
1443 }, 1451 },
1444 .probe = sgtl5000_i2c_probe, 1452 .probe = sgtl5000_i2c_probe,
1445 .remove = __devexit_p(sgtl5000_i2c_remove), 1453 .remove = __devexit_p(sgtl5000_i2c_remove),
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 84ffdebb8a8..29945b00413 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -79,7 +79,7 @@ static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
79 */ 79 */
80static int find_free_channel(struct snd_soc_codec *sn95031_codec) 80static int find_free_channel(struct snd_soc_codec *sn95031_codec)
81{ 81{
82 int ret = 0, i, value; 82 int i, value;
83 83
84 /* check whether ADC is enabled */ 84 /* check whether ADC is enabled */
85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); 85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
@@ -91,12 +91,10 @@ static int find_free_channel(struct snd_soc_codec *sn95031_codec)
91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { 91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
92 value = snd_soc_read(sn95031_codec, 92 value = snd_soc_read(sn95031_codec,
93 SN95031_ADC_CHNL_START_ADDR + i); 93 SN95031_ADC_CHNL_START_ADDR + i);
94 if (value & SN95031_STOPBIT_MASK) { 94 if (value & SN95031_STOPBIT_MASK)
95 ret = i;
96 break; 95 break;
97 }
98 } 96 }
99 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret; 97 return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i;
100} 98}
101 99
102/* Initialize the ADC for reading micbias values. Can sleep. */ 100/* Initialize the ADC for reading micbias values. Can sleep. */
@@ -660,7 +658,7 @@ static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
660 return 0; 658 return 0;
661} 659}
662 660
663int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, 661static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
664 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 662 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
665{ 663{
666 unsigned int format, rate; 664 unsigned int format, rate;
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 84f4ad56855..cceb0022f02 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -294,7 +294,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 294 struct snd_soc_pcm_runtime *rtd = substream->private_data;
295 struct snd_soc_codec *codec = rtd->codec; 295 struct snd_soc_codec *codec = rtd->codec;
296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
297 struct i2c_client *i2c = codec->control_data;
298 struct snd_pcm_runtime *master_runtime; 297 struct snd_pcm_runtime *master_runtime;
299 298
300 /* The DAI has shared clocks so if we already have a playback or 299 /* The DAI has shared clocks so if we already have a playback or
@@ -303,7 +302,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
303 */ 302 */
304 if (ssm2602->master_substream) { 303 if (ssm2602->master_substream) {
305 master_runtime = ssm2602->master_substream->runtime; 304 master_runtime = ssm2602->master_substream->runtime;
306 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n", 305 dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n",
307 master_runtime->sample_bits, 306 master_runtime->sample_bits,
308 master_runtime->rate); 307 master_runtime->rate);
309 308
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index fbd7eb9e61c..5c7def3979c 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -524,13 +524,17 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
524 rate = params_rate(params); 524 rate = params_rate(params);
525 pr_debug("rate: %u\n", rate); 525 pr_debug("rate: %u\n", rate);
526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) 526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
527 if (interpolation_ratios[i].fs == rate) 527 if (interpolation_ratios[i].fs == rate) {
528 ir = interpolation_ratios[i].ir; 528 ir = interpolation_ratios[i].ir;
529 break;
530 }
529 if (ir < 0) 531 if (ir < 0)
530 return -EINVAL; 532 return -EINVAL;
531 for (i = 0; mclk_ratios[ir][i].ratio; i++) 533 for (i = 0; mclk_ratios[ir][i].ratio; i++)
532 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) 534 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
533 mcs = mclk_ratios[ir][i].mcs; 535 mcs = mclk_ratios[ir][i].mcs;
536 break;
537 }
534 if (mcs < 0) 538 if (mcs < 0)
535 return -EINVAL; 539 return -EINVAL;
536 540
@@ -808,6 +812,7 @@ static int sta32x_remove(struct snd_soc_codec *codec)
808{ 812{
809 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); 813 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
810 814
815 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
811 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 816 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
812 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 817 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
813 818
@@ -867,18 +872,8 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
867static __devexit int sta32x_i2c_remove(struct i2c_client *client) 872static __devexit int sta32x_i2c_remove(struct i2c_client *client)
868{ 873{
869 struct sta32x_priv *sta32x = i2c_get_clientdata(client); 874 struct sta32x_priv *sta32x = i2c_get_clientdata(client);
870 struct snd_soc_codec *codec = sta32x->codec;
871
872 if (codec)
873 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
874
875 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
876
877 if (codec) {
878 snd_soc_unregister_codec(&client->dev);
879 snd_soc_codec_set_drvdata(codec, NULL);
880 }
881 875
876 snd_soc_unregister_codec(&client->dev);
882 kfree(sta32x); 877 kfree(sta32x);
883 return 0; 878 return 0;
884} 879}
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 239e0c46106..b2572c451c3 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -446,7 +446,6 @@ err_regulator:
446 gpio_free(data->power_gpio); 446 gpio_free(data->power_gpio);
447err_gpio: 447err_gpio:
448 kfree(data); 448 kfree(data);
449 i2c_set_clientdata(tpa6130a2_client, NULL);
450 tpa6130a2_client = NULL; 449 tpa6130a2_client = NULL;
451 450
452 return ret; 451 return ret;
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 443032b3b32..81645c63244 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -118,8 +118,8 @@ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
118 0x4A, /* TWL6040_LPPLLDIV 0x09 */ 118 0x4A, /* TWL6040_LPPLLDIV 0x09 */
119 0x00, /* TWL6040_AMICBCTL 0x0A */ 119 0x00, /* TWL6040_AMICBCTL 0x0A */
120 0x00, /* TWL6040_DMICBCTL 0x0B */ 120 0x00, /* TWL6040_DMICBCTL 0x0B */
121 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ 121 0x00, /* TWL6040_MICLCTL 0x0C */
122 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ 122 0x00, /* TWL6040_MICRCTL 0x0D */
123 0x00, /* TWL6040_MICGAIN 0x0E */ 123 0x00, /* TWL6040_MICGAIN 0x0E */
124 0x1B, /* TWL6040_LINEGAIN 0x0F */ 124 0x1B, /* TWL6040_LINEGAIN 0x0F */
125 0x00, /* TWL6040_HSLCTL 0x10 */ 125 0x00, /* TWL6040_HSLCTL 0x10 */
@@ -155,41 +155,8 @@ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
155 0x00, /* TWL6040_STATUS (ro) 0x2E */ 155 0x00, /* TWL6040_STATUS (ro) 0x2E */
156}; 156};
157 157
158/* 158/* List of registers to be restored after power up */
159 * twl6040 vio/gnd registers: 159static const int twl6040_restore_list[] = {
160 * registers under vio/gnd supply can be accessed
161 * before the power-up sequence, after NRESPWRON goes high
162 */
163static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
164 TWL6040_REG_ASICID,
165 TWL6040_REG_ASICREV,
166 TWL6040_REG_INTID,
167 TWL6040_REG_INTMR,
168 TWL6040_REG_NCPCTL,
169 TWL6040_REG_LDOCTL,
170 TWL6040_REG_AMICBCTL,
171 TWL6040_REG_DMICBCTL,
172 TWL6040_REG_HKCTL1,
173 TWL6040_REG_HKCTL2,
174 TWL6040_REG_GPOCTL,
175 TWL6040_REG_TRIM1,
176 TWL6040_REG_TRIM2,
177 TWL6040_REG_TRIM3,
178 TWL6040_REG_HSOTRIM,
179 TWL6040_REG_HFOTRIM,
180 TWL6040_REG_ACCCTL,
181 TWL6040_REG_STATUS,
182};
183
184/*
185 * twl6040 vdd/vss registers:
186 * registers under vdd/vss supplies can only be accessed
187 * after the power-up sequence
188 */
189static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
190 TWL6040_REG_HPPLLCTL,
191 TWL6040_REG_LPPLLCTL,
192 TWL6040_REG_LPPLLDIV,
193 TWL6040_REG_MICLCTL, 160 TWL6040_REG_MICLCTL,
194 TWL6040_REG_MICRCTL, 161 TWL6040_REG_MICRCTL,
195 TWL6040_REG_MICGAIN, 162 TWL6040_REG_MICGAIN,
@@ -202,12 +169,6 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
202 TWL6040_REG_HFLGAIN, 169 TWL6040_REG_HFLGAIN,
203 TWL6040_REG_HFRCTL, 170 TWL6040_REG_HFRCTL,
204 TWL6040_REG_HFRGAIN, 171 TWL6040_REG_HFRGAIN,
205 TWL6040_REG_VIBCTLL,
206 TWL6040_REG_VIBDATL,
207 TWL6040_REG_VIBCTLR,
208 TWL6040_REG_VIBDATR,
209 TWL6040_REG_ALB,
210 TWL6040_REG_DLB,
211}; 172};
212 173
213/* set of rates for each pll: low-power and high-performance */ 174/* set of rates for each pll: low-power and high-performance */
@@ -296,56 +257,27 @@ static int twl6040_write(struct snd_soc_codec *codec,
296 return twl6040_reg_write(twl6040, reg, value); 257 return twl6040_reg_write(twl6040, reg, value);
297} 258}
298 259
299static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 260static void twl6040_init_chip(struct snd_soc_codec *codec)
300{ 261{
301 u8 *cache = codec->reg_cache; 262 struct twl6040 *twl6040 = codec->control_data;
302 int reg, i; 263 u8 val;
303 264
304 for (i = 0; i < TWL6040_VIOREGNUM; i++) { 265 val = twl6040_get_revid(twl6040);
305 reg = twl6040_vio_reg[i]; 266 twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
306 /* 267
307 * skip read-only registers (ASICID, ASICREV, STATUS) 268 /* Change chip defaults */
308 * and registers shared among MFD children 269 /* No imput selected for microphone amplifiers */
309 */ 270 twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
310 switch (reg) { 271 twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18);
311 case TWL6040_REG_ASICID:
312 case TWL6040_REG_ASICREV:
313 case TWL6040_REG_INTID:
314 case TWL6040_REG_INTMR:
315 case TWL6040_REG_NCPCTL:
316 case TWL6040_REG_LDOCTL:
317 case TWL6040_REG_GPOCTL:
318 case TWL6040_REG_ACCCTL:
319 case TWL6040_REG_STATUS:
320 continue;
321 default:
322 break;
323 }
324 twl6040_write(codec, reg, cache[reg]);
325 }
326} 272}
327 273
328static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) 274static void twl6040_restore_regs(struct snd_soc_codec *codec)
329{ 275{
330 u8 *cache = codec->reg_cache; 276 u8 *cache = codec->reg_cache;
331 int reg, i; 277 int reg, i;
332 278
333 for (i = 0; i < TWL6040_VDDREGNUM; i++) { 279 for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) {
334 reg = twl6040_vdd_reg[i]; 280 reg = twl6040_restore_list[i];
335 /* skip vibra and PLL registers */
336 switch (reg) {
337 case TWL6040_REG_VIBCTLL:
338 case TWL6040_REG_VIBDATL:
339 case TWL6040_REG_VIBCTLR:
340 case TWL6040_REG_VIBDATR:
341 case TWL6040_REG_HPPLLCTL:
342 case TWL6040_REG_LPPLLCTL:
343 case TWL6040_REG_LPPLLDIV:
344 continue;
345 default:
346 break;
347 }
348
349 twl6040_write(codec, reg, cache[reg]); 281 twl6040_write(codec, reg, cache[reg]);
350 } 282 }
351} 283}
@@ -1325,8 +1257,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1325 1257
1326 priv->codec_powered = 1; 1258 priv->codec_powered = 1;
1327 1259
1328 /* initialize vdd/vss registers with reg_cache */ 1260 twl6040_restore_regs(codec);
1329 twl6040_init_vdd_regs(codec);
1330 1261
1331 /* Set external boost GPO */ 1262 /* Set external boost GPO */
1332 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); 1263 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
@@ -1468,7 +1399,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1468 .playback = { 1399 .playback = {
1469 .stream_name = "Playback", 1400 .stream_name = "Playback",
1470 .channels_min = 1, 1401 .channels_min = 1,
1471 .channels_max = 2, 1402 .channels_max = 5,
1472 .rates = TWL6040_RATES, 1403 .rates = TWL6040_RATES,
1473 .formats = TWL6040_FORMATS, 1404 .formats = TWL6040_FORMATS,
1474 }, 1405 },
@@ -1518,8 +1449,8 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1518 .name = "twl6040-vib", 1449 .name = "twl6040-vib",
1519 .playback = { 1450 .playback = {
1520 .stream_name = "Vibra Playback", 1451 .stream_name = "Vibra Playback",
1521 .channels_min = 2, 1452 .channels_min = 1,
1522 .channels_max = 2, 1453 .channels_max = 1,
1523 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1454 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1524 .formats = TWL6040_FORMATS, 1455 .formats = TWL6040_FORMATS,
1525 }, 1456 },
@@ -1620,8 +1551,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1620 goto plugirq_err; 1551 goto plugirq_err;
1621 } 1552 }
1622 1553
1623 /* init vio registers */ 1554 twl6040_init_chip(codec);
1624 twl6040_init_vio_regs(codec);
1625 1555
1626 /* power on device */ 1556 /* power on device */
1627 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1557 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index bcc20896791..4523c4cec02 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -56,8 +56,26 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
56}; 56};
57 57
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, 58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id) 59 const struct i2c_device_id *i2c_id)
60{ 60{
61 int id, board, rev;
62
63 board = i2c_smbus_read_byte_data(i2c, 0);
64 if (board < 0) {
65 dev_err(&i2c->dev, "Failed to read ID: %d\n", board);
66 return board;
67 }
68
69 id = (board & 0xfe) >> 2;
70 rev = board & 0x3;
71
72 if (id != 1) {
73 dev_err(&i2c->dev, "Unknown board ID %d\n", id);
74 return -ENODEV;
75 }
76
77 dev_info(&i2c->dev, "revision %d\n", rev + 1);
78
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, 79 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
62 &wm1250_ev1_dai, 1); 80 &wm1250_ev1_dai, 1);
63} 81}
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index db0dced7484..55a4c830e11 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -598,6 +599,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
598 .reg_cache_default =wm8510_reg, 599 .reg_cache_default =wm8510_reg,
599}; 600};
600 601
602static const struct of_device_id wm8510_of_match[] = {
603 { .compatible = "wlf,wm8510" },
604 { },
605};
606
601#if defined(CONFIG_SPI_MASTER) 607#if defined(CONFIG_SPI_MASTER)
602static int __devinit wm8510_spi_probe(struct spi_device *spi) 608static int __devinit wm8510_spi_probe(struct spi_device *spi)
603{ 609{
@@ -628,6 +634,7 @@ static struct spi_driver wm8510_spi_driver = {
628 .driver = { 634 .driver = {
629 .name = "wm8510", 635 .name = "wm8510",
630 .owner = THIS_MODULE, 636 .owner = THIS_MODULE,
637 .of_match_table = wm8510_of_match,
631 }, 638 },
632 .probe = wm8510_spi_probe, 639 .probe = wm8510_spi_probe,
633 .remove = __devexit_p(wm8510_spi_remove), 640 .remove = __devexit_p(wm8510_spi_remove),
@@ -671,6 +678,7 @@ static struct i2c_driver wm8510_i2c_driver = {
671 .driver = { 678 .driver = {
672 .name = "wm8510-codec", 679 .name = "wm8510-codec",
673 .owner = THIS_MODULE, 680 .owner = THIS_MODULE,
681 .of_match_table = wm8510_of_match,
674 }, 682 },
675 .probe = wm8510_i2c_probe, 683 .probe = wm8510_i2c_probe,
676 .remove = __devexit_p(wm8510_i2c_remove), 684 .remove = __devexit_p(wm8510_i2c_remove),
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 4fd4d8dca0f..5355a7a944f 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -84,7 +85,7 @@ static const char *wm8523_zd_count_text[] = {
84static const struct soc_enum wm8523_zc_count = 85static const struct soc_enum wm8523_zc_count =
85 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); 86 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
86 87
87static const struct snd_kcontrol_new wm8523_snd_controls[] = { 88static const struct snd_kcontrol_new wm8523_controls[] = {
88SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, 89SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
89 0, 448, 0, dac_tlv), 90 0, 448, 0, dac_tlv),
90SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), 91SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
@@ -101,22 +102,11 @@ SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
101SND_SOC_DAPM_OUTPUT("LINEVOUTR"), 102SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
102}; 103};
103 104
104static const struct snd_soc_dapm_route intercon[] = { 105static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
105 { "LINEVOUTL", NULL, "DAC" }, 106 { "LINEVOUTL", NULL, "DAC" },
106 { "LINEVOUTR", NULL, "DAC" }, 107 { "LINEVOUTR", NULL, "DAC" },
107}; 108};
108 109
109static int wm8523_add_widgets(struct snd_soc_codec *codec)
110{
111 struct snd_soc_dapm_context *dapm = &codec->dapm;
112
113 snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
114 ARRAY_SIZE(wm8523_dapm_widgets));
115 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
116
117 return 0;
118}
119
120static struct { 110static struct {
121 int value; 111 int value;
122 int ratio; 112 int ratio;
@@ -479,10 +469,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
479 /* Bias level configuration will have done an extra enable */ 469 /* Bias level configuration will have done an extra enable */
480 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 470 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
481 471
482 snd_soc_add_controls(codec, wm8523_snd_controls,
483 ARRAY_SIZE(wm8523_snd_controls));
484 wm8523_add_widgets(codec);
485
486 return 0; 472 return 0;
487 473
488err_enable: 474err_enable:
@@ -512,6 +498,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
512 .reg_word_size = sizeof(u16), 498 .reg_word_size = sizeof(u16),
513 .reg_cache_default = wm8523_reg, 499 .reg_cache_default = wm8523_reg,
514 .volatile_register = wm8523_volatile_register, 500 .volatile_register = wm8523_volatile_register,
501
502 .controls = wm8523_controls,
503 .num_controls = ARRAY_SIZE(wm8523_controls),
504 .dapm_widgets = wm8523_dapm_widgets,
505 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
506 .dapm_routes = wm8523_dapm_routes,
507 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
508};
509
510static const struct of_device_id wm8523_of_match[] = {
511 { .compatible = "wlf,wm8523" },
512 { },
515}; 513};
516 514
517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 515#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -551,8 +549,9 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
551 549
552static struct i2c_driver wm8523_i2c_driver = { 550static struct i2c_driver wm8523_i2c_driver = {
553 .driver = { 551 .driver = {
554 .name = "wm8523-codec", 552 .name = "wm8523",
555 .owner = THIS_MODULE, 553 .owner = THIS_MODULE,
554 .of_match_table = wm8523_of_match,
556 }, 555 },
557 .probe = wm8523_i2c_probe, 556 .probe = wm8523_i2c_probe,
558 .remove = __devexit_p(wm8523_i2c_remove), 557 .remove = __devexit_p(wm8523_i2c_remove),
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 4bbc0a79f01..4664c3a76c7 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/of_device.h>
29 30
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -907,6 +908,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
907 .reg_cache_default = wm8580_reg, 908 .reg_cache_default = wm8580_reg,
908}; 909};
909 910
911static const struct of_device_id wm8580_of_match[] = {
912 { .compatible = "wlf,wm8580" },
913 { },
914};
915
910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 916#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
911static int wm8580_i2c_probe(struct i2c_client *i2c, 917static int wm8580_i2c_probe(struct i2c_client *i2c,
912 const struct i2c_device_id *id) 918 const struct i2c_device_id *id)
@@ -943,8 +949,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
943 949
944static struct i2c_driver wm8580_i2c_driver = { 950static struct i2c_driver wm8580_i2c_driver = {
945 .driver = { 951 .driver = {
946 .name = "wm8580-codec", 952 .name = "wm8580",
947 .owner = THIS_MODULE, 953 .owner = THIS_MODULE,
954 .of_match_table = wm8580_of_match,
948 }, 955 },
949 .probe = wm8580_i2c_probe, 956 .probe = wm8580_i2c_probe,
950 .remove = wm8580_i2c_remove, 957 .remove = wm8580_i2c_remove,
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index a537e4af6ae..8457d3cb596 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -414,6 +415,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), 415 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
415}; 416};
416 417
418static const struct of_device_id wm8711_of_match[] = {
419 { .compatible = "wlf,wm8711", },
420 { }
421};
422MODULE_DEVICE_TABLE(of, wm8711_of_match);
423
417#if defined(CONFIG_SPI_MASTER) 424#if defined(CONFIG_SPI_MASTER)
418static int __devinit wm8711_spi_probe(struct spi_device *spi) 425static int __devinit wm8711_spi_probe(struct spi_device *spi)
419{ 426{
@@ -443,8 +450,9 @@ static int __devexit wm8711_spi_remove(struct spi_device *spi)
443 450
444static struct spi_driver wm8711_spi_driver = { 451static struct spi_driver wm8711_spi_driver = {
445 .driver = { 452 .driver = {
446 .name = "wm8711-codec", 453 .name = "wm8711",
447 .owner = THIS_MODULE, 454 .owner = THIS_MODULE,
455 .of_match_table = wm8711_of_match,
448 }, 456 },
449 .probe = wm8711_spi_probe, 457 .probe = wm8711_spi_probe,
450 .remove = __devexit_p(wm8711_spi_remove), 458 .remove = __devexit_p(wm8711_spi_remove),
@@ -487,8 +495,9 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
487 495
488static struct i2c_driver wm8711_i2c_driver = { 496static struct i2c_driver wm8711_i2c_driver = {
489 .driver = { 497 .driver = {
490 .name = "wm8711-codec", 498 .name = "wm8711",
491 .owner = THIS_MODULE, 499 .owner = THIS_MODULE,
500 .of_match_table = wm8711_of_match,
492 }, 501 },
493 .probe = wm8711_i2c_probe, 502 .probe = wm8711_i2c_probe,
494 .remove = __devexit_p(wm8711_i2c_remove), 503 .remove = __devexit_p(wm8711_i2c_remove),
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 86d4718d3a7..04b027efd5c 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of_device.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -269,6 +270,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), 270 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
270}; 271};
271 272
273static const struct of_device_id wm8728_of_match[] = {
274 { .compatible = "wlf,wm8728", },
275 { }
276};
277MODULE_DEVICE_TABLE(of, wm8728_of_match);
278
272#if defined(CONFIG_SPI_MASTER) 279#if defined(CONFIG_SPI_MASTER)
273static int __devinit wm8728_spi_probe(struct spi_device *spi) 280static int __devinit wm8728_spi_probe(struct spi_device *spi)
274{ 281{
@@ -298,8 +305,9 @@ static int __devexit wm8728_spi_remove(struct spi_device *spi)
298 305
299static struct spi_driver wm8728_spi_driver = { 306static struct spi_driver wm8728_spi_driver = {
300 .driver = { 307 .driver = {
301 .name = "wm8728-codec", 308 .name = "wm8728",
302 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
310 .of_match_table = wm8728_of_match,
303 }, 311 },
304 .probe = wm8728_spi_probe, 312 .probe = wm8728_spi_probe,
305 .remove = __devexit_p(wm8728_spi_remove), 313 .remove = __devexit_p(wm8728_spi_remove),
@@ -342,8 +350,9 @@ MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
342 350
343static struct i2c_driver wm8728_i2c_driver = { 351static struct i2c_driver wm8728_i2c_driver = {
344 .driver = { 352 .driver = {
345 .name = "wm8728-codec", 353 .name = "wm8728",
346 .owner = THIS_MODULE, 354 .owner = THIS_MODULE,
355 .of_match_table = wm8728_of_match,
347 }, 356 },
348 .probe = wm8728_i2c_probe, 357 .probe = wm8728_i2c_probe,
349 .remove = __devexit_p(wm8728_i2c_remove), 358 .remove = __devexit_p(wm8728_i2c_remove),
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 76b4361e9b8..f76b6fc6766 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25#include <linux/of_device.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -607,6 +608,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
607 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 608 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
608}; 609};
609 610
611static const struct of_device_id wm8731_of_match[] = {
612 { .compatible = "wlf,wm8731", },
613 { }
614};
615
616MODULE_DEVICE_TABLE(of, wm8731_of_match);
617
610#if defined(CONFIG_SPI_MASTER) 618#if defined(CONFIG_SPI_MASTER)
611static int __devinit wm8731_spi_probe(struct spi_device *spi) 619static int __devinit wm8731_spi_probe(struct spi_device *spi)
612{ 620{
@@ -638,6 +646,7 @@ static struct spi_driver wm8731_spi_driver = {
638 .driver = { 646 .driver = {
639 .name = "wm8731", 647 .name = "wm8731",
640 .owner = THIS_MODULE, 648 .owner = THIS_MODULE,
649 .of_match_table = wm8731_of_match,
641 }, 650 },
642 .probe = wm8731_spi_probe, 651 .probe = wm8731_spi_probe,
643 .remove = __devexit_p(wm8731_spi_remove), 652 .remove = __devexit_p(wm8731_spi_remove),
@@ -682,6 +691,7 @@ static struct i2c_driver wm8731_i2c_driver = {
682 .driver = { 691 .driver = {
683 .name = "wm8731", 692 .name = "wm8731",
684 .owner = THIS_MODULE, 693 .owner = THIS_MODULE,
694 .of_match_table = wm8731_of_match,
685 }, 695 },
686 .probe = wm8731_i2c_probe, 696 .probe = wm8731_i2c_probe,
687 .remove = __devexit_p(wm8731_i2c_remove), 697 .remove = __devexit_p(wm8731_i2c_remove),
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 30c67d06a90..f6aef58845c 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -20,6 +20,7 @@
20#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/of_device.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -634,6 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
634 .reg_cache_default = wm8737_reg, 635 .reg_cache_default = wm8737_reg,
635}; 636};
636 637
638static const struct of_device_id wm8737_of_match[] = {
639 { .compatible = "wlf,wm8737", },
640 { }
641};
642
643MODULE_DEVICE_TABLE(of, wm8737_of_match);
644
637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 645#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, 646static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id) 647 const struct i2c_device_id *id)
@@ -673,6 +681,7 @@ static struct i2c_driver wm8737_i2c_driver = {
673 .driver = { 681 .driver = {
674 .name = "wm8737", 682 .name = "wm8737",
675 .owner = THIS_MODULE, 683 .owner = THIS_MODULE,
684 .of_match_table = wm8737_of_match,
676 }, 685 },
677 .probe = wm8737_i2c_probe, 686 .probe = wm8737_i2c_probe,
678 .remove = __devexit_p(wm8737_i2c_remove), 687 .remove = __devexit_p(wm8737_i2c_remove),
@@ -711,6 +720,7 @@ static struct spi_driver wm8737_spi_driver = {
711 .driver = { 720 .driver = {
712 .name = "wm8737", 721 .name = "wm8737",
713 .owner = THIS_MODULE, 722 .owner = THIS_MODULE,
723 .of_match_table = wm8737_of_match,
714 }, 724 },
715 .probe = wm8737_spi_probe, 725 .probe = wm8737_spi_probe,
716 .remove = __devexit_p(wm8737_spi_remove), 726 .remove = __devexit_p(wm8737_spi_remove),
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 25af901fe81..78c9e5ab3fa 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -17,9 +17,11 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
23#include <sound/core.h> 25#include <sound/core.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
25#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -422,17 +424,35 @@ static int wm8741_probe(struct snd_soc_codec *codec)
422{ 424{
423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 425 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
424 int ret = 0; 426 int ret = 0;
427 int i;
428
429 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
430 wm8741->supplies[i].supply = wm8741_supply_names[i];
431
432 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
433 wm8741->supplies);
434 if (ret != 0) {
435 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
436 goto err;
437 }
438
439 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
440 wm8741->supplies);
441 if (ret != 0) {
442 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
443 goto err_get;
444 }
425 445
426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); 446 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
427 if (ret != 0) { 447 if (ret != 0) {
428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 448 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
429 return ret; 449 goto err_enable;
430 } 450 }
431 451
432 ret = wm8741_reset(codec); 452 ret = wm8741_reset(codec);
433 if (ret < 0) { 453 if (ret < 0) {
434 dev_err(codec->dev, "Failed to issue reset\n"); 454 dev_err(codec->dev, "Failed to issue reset\n");
435 return ret; 455 goto err_enable;
436 } 456 }
437 457
438 /* Change some default settings - latch VU */ 458 /* Change some default settings - latch VU */
@@ -451,58 +471,61 @@ static int wm8741_probe(struct snd_soc_codec *codec)
451 471
452 dev_dbg(codec->dev, "Successful registration\n"); 472 dev_dbg(codec->dev, "Successful registration\n");
453 return ret; 473 return ret;
474
475err_enable:
476 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
477err_get:
478 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
479err:
480 return ret;
481}
482
483static int wm8741_remove(struct snd_soc_codec *codec)
484{
485 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
486
487 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
488 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489
490 return 0;
454} 491}
455 492
456static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { 493static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
457 .probe = wm8741_probe, 494 .probe = wm8741_probe,
495 .remove = wm8741_remove,
458 .resume = wm8741_resume, 496 .resume = wm8741_resume,
459 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), 497 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
460 .reg_word_size = sizeof(u16), 498 .reg_word_size = sizeof(u16),
461 .reg_cache_default = wm8741_reg_defaults, 499 .reg_cache_default = wm8741_reg_defaults,
462}; 500};
463 501
502static const struct of_device_id wm8741_of_match[] = {
503 { .compatible = "wlf,wm8741", },
504 { }
505};
506MODULE_DEVICE_TABLE(of, wm8741_of_match);
507
464#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
465static int wm8741_i2c_probe(struct i2c_client *i2c, 509static int wm8741_i2c_probe(struct i2c_client *i2c,
466 const struct i2c_device_id *id) 510 const struct i2c_device_id *id)
467{ 511{
468 struct wm8741_priv *wm8741; 512 struct wm8741_priv *wm8741;
469 int ret, i; 513 int ret;
470 514
471 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); 515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
472 if (wm8741 == NULL) 516 if (wm8741 == NULL)
473 return -ENOMEM; 517 return -ENOMEM;
474 518
475 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
476 wm8741->supplies[i].supply = wm8741_supply_names[i];
477
478 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
479 wm8741->supplies);
480 if (ret != 0) {
481 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
482 goto err;
483 }
484
485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
486 wm8741->supplies);
487 if (ret != 0) {
488 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
489 goto err_get;
490 }
491
492 i2c_set_clientdata(i2c, wm8741); 519 i2c_set_clientdata(i2c, wm8741);
493 wm8741->control_type = SND_SOC_I2C; 520 wm8741->control_type = SND_SOC_I2C;
494 521
495 ret = snd_soc_register_codec(&i2c->dev, 522 ret = snd_soc_register_codec(&i2c->dev,
496 &soc_codec_dev_wm8741, &wm8741_dai, 1); 523 &soc_codec_dev_wm8741, &wm8741_dai, 1);
497 if (ret < 0) 524 if (ret != 0)
498 goto err_enable; 525 goto err;
499 return ret;
500 526
501err_enable: 527 return ret;
502 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
503 528
504err_get:
505 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
506err: 529err:
507 kfree(wm8741); 530 kfree(wm8741);
508 return ret; 531 return ret;
@@ -510,10 +533,7 @@ err:
510 533
511static int wm8741_i2c_remove(struct i2c_client *client) 534static int wm8741_i2c_remove(struct i2c_client *client)
512{ 535{
513 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
514
515 snd_soc_unregister_codec(&client->dev); 536 snd_soc_unregister_codec(&client->dev);
516 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
517 kfree(i2c_get_clientdata(client)); 537 kfree(i2c_get_clientdata(client));
518 return 0; 538 return 0;
519} 539}
@@ -526,8 +546,9 @@ MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
526 546
527static struct i2c_driver wm8741_i2c_driver = { 547static struct i2c_driver wm8741_i2c_driver = {
528 .driver = { 548 .driver = {
529 .name = "wm8741-codec", 549 .name = "wm8741",
530 .owner = THIS_MODULE, 550 .owner = THIS_MODULE,
551 .of_match_table = wm8741_of_match,
531 }, 552 },
532 .probe = wm8741_i2c_probe, 553 .probe = wm8741_i2c_probe,
533 .remove = wm8741_i2c_remove, 554 .remove = wm8741_i2c_remove,
@@ -535,6 +556,44 @@ static struct i2c_driver wm8741_i2c_driver = {
535}; 556};
536#endif 557#endif
537 558
559#if defined(CONFIG_SPI_MASTER)
560static int __devinit wm8741_spi_probe(struct spi_device *spi)
561{
562 struct wm8741_priv *wm8741;
563 int ret;
564
565 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
566 if (wm8741 == NULL)
567 return -ENOMEM;
568
569 wm8741->control_type = SND_SOC_SPI;
570 spi_set_drvdata(spi, wm8741);
571
572 ret = snd_soc_register_codec(&spi->dev,
573 &soc_codec_dev_wm8741, &wm8741_dai, 1);
574 if (ret < 0)
575 kfree(wm8741);
576 return ret;
577}
578
579static int __devexit wm8741_spi_remove(struct spi_device *spi)
580{
581 snd_soc_unregister_codec(&spi->dev);
582 kfree(spi_get_drvdata(spi));
583 return 0;
584}
585
586static struct spi_driver wm8741_spi_driver = {
587 .driver = {
588 .name = "wm8741",
589 .owner = THIS_MODULE,
590 .of_match_table = wm8741_of_match,
591 },
592 .probe = wm8741_spi_probe,
593 .remove = __devexit_p(wm8741_spi_remove),
594};
595#endif /* CONFIG_SPI_MASTER */
596
538static int __init wm8741_modinit(void) 597static int __init wm8741_modinit(void)
539{ 598{
540 int ret = 0; 599 int ret = 0;
@@ -544,6 +603,13 @@ static int __init wm8741_modinit(void)
544 if (ret != 0) 603 if (ret != 0)
545 pr_err("Failed to register WM8741 I2C driver: %d\n", ret); 604 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
546#endif 605#endif
606#if defined(CONFIG_SPI_MASTER)
607 ret = spi_register_driver(&wm8741_spi_driver);
608 if (ret != 0) {
609 printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
610 ret);
611 }
612#endif
547 613
548 return ret; 614 return ret;
549} 615}
@@ -551,6 +617,9 @@ module_init(wm8741_modinit);
551 617
552static void __exit wm8741_exit(void) 618static void __exit wm8741_exit(void)
553{ 619{
620#if defined(CONFIG_SPI_MASTER)
621 spi_unregister_driver(&wm8741_spi_driver);
622#endif
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 623#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555 i2c_del_driver(&wm8741_i2c_driver); 624 i2c_del_driver(&wm8741_i2c_driver);
556#endif 625#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index d0003cc3bcd..15f03721ec6 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of_device.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -751,6 +752,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
751 .reg_cache_default = wm8750_reg, 752 .reg_cache_default = wm8750_reg,
752}; 753};
753 754
755static const struct of_device_id wm8750_of_match[] = {
756 { .compatible = "wlf,wm8750", },
757 { .compatible = "wlf,wm8987", },
758 { }
759};
760MODULE_DEVICE_TABLE(of, wm8750_of_match);
761
754#if defined(CONFIG_SPI_MASTER) 762#if defined(CONFIG_SPI_MASTER)
755static int __devinit wm8750_spi_probe(struct spi_device *spi) 763static int __devinit wm8750_spi_probe(struct spi_device *spi)
756{ 764{
@@ -787,8 +795,9 @@ MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
787 795
788static struct spi_driver wm8750_spi_driver = { 796static struct spi_driver wm8750_spi_driver = {
789 .driver = { 797 .driver = {
790 .name = "wm8750-codec", 798 .name = "wm8750",
791 .owner = THIS_MODULE, 799 .owner = THIS_MODULE,
800 .of_match_table = wm8750_of_match,
792 }, 801 },
793 .id_table = wm8750_spi_ids, 802 .id_table = wm8750_spi_ids,
794 .probe = wm8750_spi_probe, 803 .probe = wm8750_spi_probe,
@@ -833,8 +842,9 @@ MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
833 842
834static struct i2c_driver wm8750_i2c_driver = { 843static struct i2c_driver wm8750_i2c_driver = {
835 .driver = { 844 .driver = {
836 .name = "wm8750-codec", 845 .name = "wm8750",
837 .owner = THIS_MODULE, 846 .owner = THIS_MODULE,
847 .of_match_table = wm8750_of_match,
838 }, 848 },
839 .probe = wm8750_i2c_probe, 849 .probe = wm8750_i2c_probe,
840 .remove = __devexit_p(wm8750_i2c_remove), 850 .remove = __devexit_p(wm8750_i2c_remove),
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index ffa2ffe5ec1..fe04a101d65 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/of_device.h>
41#include <linux/platform_device.h> 42#include <linux/platform_device.h>
42#include <linux/spi/spi.h> 43#include <linux/spi/spi.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
@@ -1490,6 +1491,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1490 .reg_cache_default = wm8753_reg, 1491 .reg_cache_default = wm8753_reg,
1491}; 1492};
1492 1493
1494static const struct of_device_id wm8753_of_match[] = {
1495 { .compatible = "wlf,wm8753", },
1496 { }
1497};
1498MODULE_DEVICE_TABLE(of, wm8753_of_match);
1499
1493#if defined(CONFIG_SPI_MASTER) 1500#if defined(CONFIG_SPI_MASTER)
1494static int __devinit wm8753_spi_probe(struct spi_device *spi) 1501static int __devinit wm8753_spi_probe(struct spi_device *spi)
1495{ 1502{
@@ -1519,8 +1526,9 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1519 1526
1520static struct spi_driver wm8753_spi_driver = { 1527static struct spi_driver wm8753_spi_driver = {
1521 .driver = { 1528 .driver = {
1522 .name = "wm8753-codec", 1529 .name = "wm8753",
1523 .owner = THIS_MODULE, 1530 .owner = THIS_MODULE,
1531 .of_match_table = wm8753_of_match,
1524 }, 1532 },
1525 .probe = wm8753_spi_probe, 1533 .probe = wm8753_spi_probe,
1526 .remove = __devexit_p(wm8753_spi_remove), 1534 .remove = __devexit_p(wm8753_spi_remove),
@@ -1563,8 +1571,9 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1563 1571
1564static struct i2c_driver wm8753_i2c_driver = { 1572static struct i2c_driver wm8753_i2c_driver = {
1565 .driver = { 1573 .driver = {
1566 .name = "wm8753-codec", 1574 .name = "wm8753",
1567 .owner = THIS_MODULE, 1575 .owner = THIS_MODULE,
1576 .of_match_table = wm8753_of_match,
1568 }, 1577 },
1569 .probe = wm8753_i2c_probe, 1578 .probe = wm8753_i2c_probe,
1570 .remove = __devexit_p(wm8753_i2c_remove), 1579 .remove = __devexit_p(wm8753_i2c_remove),
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19b92baa9e8..aa05e6507f8 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -14,6 +14,7 @@
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/of_device.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
@@ -684,6 +685,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
684 .reg_cache_default = wm8770_reg_defs 685 .reg_cache_default = wm8770_reg_defs
685}; 686};
686 687
688static const struct of_device_id wm8770_of_match[] = {
689 { .compatible = "wlf,wm8770", },
690 { }
691};
692MODULE_DEVICE_TABLE(of, wm8770_of_match);
693
687#if defined(CONFIG_SPI_MASTER) 694#if defined(CONFIG_SPI_MASTER)
688static int __devinit wm8770_spi_probe(struct spi_device *spi) 695static int __devinit wm8770_spi_probe(struct spi_device *spi)
689{ 696{
@@ -715,6 +722,7 @@ static struct spi_driver wm8770_spi_driver = {
715 .driver = { 722 .driver = {
716 .name = "wm8770", 723 .name = "wm8770",
717 .owner = THIS_MODULE, 724 .owner = THIS_MODULE,
725 .of_match_table = wm8770_of_match,
718 }, 726 },
719 .probe = wm8770_spi_probe, 727 .probe = wm8770_spi_probe,
720 .remove = __devexit_p(wm8770_spi_remove) 728 .remove = __devexit_p(wm8770_spi_remove)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 8e7953b1b79..00d8846fae8 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/of_device.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -215,8 +216,6 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
215 int ratio_shift, master; 216 int ratio_shift, master;
216 int i; 217 int i;
217 218
218 iface = 0;
219
220 switch (dai->driver->id) { 219 switch (dai->driver->id) {
221 case WM8776_DAI_DAC: 220 case WM8776_DAI_DAC:
222 iface_reg = WM8776_DACIFCTRL; 221 iface_reg = WM8776_DACIFCTRL;
@@ -232,20 +231,23 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
232 return -EINVAL; 231 return -EINVAL;
233 } 232 }
234 233
235
236 /* Set word length */ 234 /* Set word length */
237 switch (params_format(params)) { 235 switch (snd_pcm_format_width(params_format(params))) {
238 case SNDRV_PCM_FORMAT_S16_LE: 236 case 16:
237 iface = 0;
238 case 20:
239 iface = 0x10;
239 break; 240 break;
240 case SNDRV_PCM_FORMAT_S20_3LE: 241 case 24:
241 iface |= 0x10; 242 iface = 0x20;
242 break; 243 break;
243 case SNDRV_PCM_FORMAT_S24_LE: 244 case 32:
244 iface |= 0x20; 245 iface = 0x30;
245 break;
246 case SNDRV_PCM_FORMAT_S32_LE:
247 iface |= 0x30;
248 break; 246 break;
247 default:
248 dev_err(codec->dev, "Unsupported sample size: %i\n",
249 snd_pcm_format_width(params_format(params)));
250 return -EINVAL;
249 } 251 }
250 252
251 /* Only need to set MCLK/LRCLK ratio if we're master */ 253 /* Only need to set MCLK/LRCLK ratio if we're master */
@@ -320,11 +322,6 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
320 return 0; 322 return 0;
321} 323}
322 324
323#define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
324 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
325 SNDRV_PCM_RATE_96000)
326
327
328#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 325#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
329 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 326 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
330 327
@@ -349,7 +346,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
349 .stream_name = "Playback", 346 .stream_name = "Playback",
350 .channels_min = 2, 347 .channels_min = 2,
351 .channels_max = 2, 348 .channels_max = 2,
352 .rates = WM8776_RATES, 349 .rates = SNDRV_PCM_RATE_CONTINUOUS,
350 .rate_min = 32000,
351 .rate_max = 192000,
353 .formats = WM8776_FORMATS, 352 .formats = WM8776_FORMATS,
354 }, 353 },
355 .ops = &wm8776_dac_ops, 354 .ops = &wm8776_dac_ops,
@@ -361,7 +360,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = {
361 .stream_name = "Capture", 360 .stream_name = "Capture",
362 .channels_min = 2, 361 .channels_min = 2,
363 .channels_max = 2, 362 .channels_max = 2,
364 .rates = WM8776_RATES, 363 .rates = SNDRV_PCM_RATE_CONTINUOUS,
364 .rate_min = 32000,
365 .rate_max = 96000,
365 .formats = WM8776_FORMATS, 366 .formats = WM8776_FORMATS,
366 }, 367 },
367 .ops = &wm8776_adc_ops, 368 .ops = &wm8776_adc_ops,
@@ -452,6 +453,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
452 .reg_cache_default = wm8776_reg, 453 .reg_cache_default = wm8776_reg,
453}; 454};
454 455
456static const struct of_device_id wm8776_of_match[] = {
457 { .compatible = "wlf,wm8776", },
458 { }
459};
460MODULE_DEVICE_TABLE(of, wm8776_of_match);
461
455#if defined(CONFIG_SPI_MASTER) 462#if defined(CONFIG_SPI_MASTER)
456static int __devinit wm8776_spi_probe(struct spi_device *spi) 463static int __devinit wm8776_spi_probe(struct spi_device *spi)
457{ 464{
@@ -481,8 +488,9 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
481 488
482static struct spi_driver wm8776_spi_driver = { 489static struct spi_driver wm8776_spi_driver = {
483 .driver = { 490 .driver = {
484 .name = "wm8776-codec", 491 .name = "wm8776",
485 .owner = THIS_MODULE, 492 .owner = THIS_MODULE,
493 .of_match_table = wm8776_of_match,
486 }, 494 },
487 .probe = wm8776_spi_probe, 495 .probe = wm8776_spi_probe,
488 .remove = __devexit_p(wm8776_spi_remove), 496 .remove = __devexit_p(wm8776_spi_remove),
@@ -525,8 +533,9 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
525 533
526static struct i2c_driver wm8776_i2c_driver = { 534static struct i2c_driver wm8776_i2c_driver = {
527 .driver = { 535 .driver = {
528 .name = "wm8776-codec", 536 .name = "wm8776",
529 .owner = THIS_MODULE, 537 .owner = THIS_MODULE,
538 .of_match_table = wm8776_of_match,
530 }, 539 },
531 .probe = wm8776_i2c_probe, 540 .probe = wm8776_i2c_probe,
532 .remove = __devexit_p(wm8776_i2c_remove), 541 .remove = __devexit_p(wm8776_i2c_remove),
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 9a5e67c5a6b..9ee072b8597 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_device.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -717,6 +718,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
717 .volatile_register = wm8804_volatile 718 .volatile_register = wm8804_volatile
718}; 719};
719 720
721static const struct of_device_id wm8804_of_match[] = {
722 { .compatible = "wlf,wm8804", },
723 { }
724};
725MODULE_DEVICE_TABLE(of, wm8804_of_match);
726
720#if defined(CONFIG_SPI_MASTER) 727#if defined(CONFIG_SPI_MASTER)
721static int __devinit wm8804_spi_probe(struct spi_device *spi) 728static int __devinit wm8804_spi_probe(struct spi_device *spi)
722{ 729{
@@ -748,6 +755,7 @@ static struct spi_driver wm8804_spi_driver = {
748 .driver = { 755 .driver = {
749 .name = "wm8804", 756 .name = "wm8804",
750 .owner = THIS_MODULE, 757 .owner = THIS_MODULE,
758 .of_match_table = wm8804_of_match,
751 }, 759 },
752 .probe = wm8804_spi_probe, 760 .probe = wm8804_spi_probe,
753 .remove = __devexit_p(wm8804_spi_remove) 761 .remove = __devexit_p(wm8804_spi_remove)
@@ -792,6 +800,7 @@ static struct i2c_driver wm8804_i2c_driver = {
792 .driver = { 800 .driver = {
793 .name = "wm8804", 801 .name = "wm8804",
794 .owner = THIS_MODULE, 802 .owner = THIS_MODULE,
803 .of_match_table = wm8804_of_match,
795 }, 804 },
796 .probe = wm8804_i2c_probe, 805 .probe = wm8804_i2c_probe,
797 .remove = __devexit_p(wm8804_i2c_remove), 806 .remove = __devexit_p(wm8804_i2c_remove),
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 1725550c293..3676b38838d 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -63,6 +63,8 @@ struct wm8962_priv {
63 int fll_fref; 63 int fll_fref;
64 int fll_fout; 64 int fll_fout;
65 65
66 u16 dsp2_ena;
67
66 struct delayed_work mic_work; 68 struct delayed_work mic_work;
67 struct snd_soc_jack *jack; 69 struct snd_soc_jack *jack;
68 70
@@ -837,7 +839,7 @@ static const struct wm8962_reg_access {
837 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ 839 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
838 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ 840 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
839 841
840 [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */ 842 [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */
841 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ 843 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
842 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ 844 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
843 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ 845 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
@@ -965,7 +967,7 @@ static const struct wm8962_reg_access {
965 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ 967 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
966 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ 968 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
967 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ 969 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
968 [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */ 970 [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */
969 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ 971 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
970 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ 972 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
971 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ 973 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
@@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = {
1986}; 1988};
1987static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 1989static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1988 1990
1991static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1992{
1993 return 0;
1994}
1995
1996static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
1997{
1998 u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
1999 u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
2000 u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
2001
2002 /* Mute the ADCs and DACs */
2003 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
2004 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
2005 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2006 WM8962_DAC_MUTE, WM8962_DAC_MUTE);
2007
2008 snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
2009
2010 /* Restore the ADCs and DACs */
2011 snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
2012 snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
2013 snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
2014 WM8962_DAC_MUTE, dac);
2015
2016 return 0;
2017}
2018
2019static int wm8962_dsp2_start(struct snd_soc_codec *codec)
2020{
2021 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2022
2023 wm8962_dsp2_write_config(codec);
2024
2025 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
2026
2027 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2028
2029 return 0;
2030}
2031
2032static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
2033{
2034 wm8962_dsp2_set_enable(codec, 0);
2035
2036 snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
2037
2038 return 0;
2039}
2040
2041#define WM8962_DSP2_ENABLE(xname, xshift) \
2042{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2043 .info = wm8962_dsp2_ena_info, \
2044 .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
2045 .private_value = xshift }
2046
2047static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
2048 struct snd_ctl_elem_info *uinfo)
2049{
2050 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2051
2052 uinfo->count = 1;
2053 uinfo->value.integer.min = 0;
2054 uinfo->value.integer.max = 1;
2055
2056 return 0;
2057}
2058
2059static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 int shift = kcontrol->private_value;
2063 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2064 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2065
2066 ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
2067
2068 return 0;
2069}
2070
2071static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
2072 struct snd_ctl_elem_value *ucontrol)
2073{
2074 int shift = kcontrol->private_value;
2075 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2077 int old = wm8962->dsp2_ena;
2078 int ret = 0;
2079 int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
2080 WM8962_DSP2_ENA;
2081
2082 mutex_lock(&codec->mutex);
2083
2084 if (ucontrol->value.integer.value[0])
2085 wm8962->dsp2_ena |= 1 << shift;
2086 else
2087 wm8962->dsp2_ena &= ~(1 << shift);
2088
2089 if (wm8962->dsp2_ena == old)
2090 goto out;
2091
2092 ret = 1;
2093
2094 if (dsp2_running) {
2095 if (wm8962->dsp2_ena)
2096 wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
2097 else
2098 wm8962_dsp2_stop(codec);
2099 }
2100
2101out:
2102 mutex_unlock(&codec->mutex);
2103
2104 return ret;
2105}
2106
1989/* The VU bits for the headphones are in a different register to the mute 2107/* The VU bits for the headphones are in a different register to the mute
1990 * bits and only take effect on the PGA if it is actually powered. 2108 * bits and only take effect on the PGA if it is actually powered.
1991 */ 2109 */
@@ -2049,6 +2167,14 @@ static const char *cap_hpf_mode_text[] = {
2049static const struct soc_enum cap_hpf_mode = 2167static const struct soc_enum cap_hpf_mode =
2050 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); 2168 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2051 2169
2170
2171static const char *cap_lhpf_mode_text[] = {
2172 "LPF", "HPF"
2173};
2174
2175static const struct soc_enum cap_lhpf_mode =
2176 SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
2177
2052static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2178static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2053SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2179SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2054 2180
@@ -2077,6 +2203,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2077SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), 2203SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2078SOC_ENUM("Capture HPF Mode", cap_hpf_mode), 2204SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2079SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), 2205SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2206SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
2207SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
2080 2208
2081SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2209SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2082 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2210 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2134,6 +2262,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
2134 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), 2262 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
2135SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 2263SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
2136 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 2264 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
2265
2266WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
2267WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
2268WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
2269WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
2137}; 2270};
2138 2271
2139static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 2272static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2395,6 +2528,31 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2395 } 2528 }
2396} 2529}
2397 2530
2531static int dsp2_event(struct snd_soc_dapm_widget *w,
2532 struct snd_kcontrol *kcontrol, int event)
2533{
2534 struct snd_soc_codec *codec = w->codec;
2535 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2536
2537 switch (event) {
2538 case SND_SOC_DAPM_POST_PMU:
2539 if (wm8962->dsp2_ena)
2540 wm8962_dsp2_start(codec);
2541 break;
2542
2543 case SND_SOC_DAPM_PRE_PMD:
2544 if (wm8962->dsp2_ena)
2545 wm8962_dsp2_stop(codec);
2546 break;
2547
2548 default:
2549 BUG();
2550 return -EINVAL;
2551 }
2552
2553 return 0;
2554}
2555
2398static const char *st_text[] = { "None", "Right", "Left" }; 2556static const char *st_text[] = { "None", "Right", "Left" };
2399 2557
2400static const struct soc_enum str_enum = 2558static const struct soc_enum str_enum =
@@ -2517,6 +2675,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
2517SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2675SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2518 SND_SOC_DAPM_POST_PMU), 2676 SND_SOC_DAPM_POST_PMU),
2519SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2677SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
2678SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
2679 WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
2680 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2520 2681
2521SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, 2682SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
2522 inpgal, ARRAY_SIZE(inpgal)), 2683 inpgal, ARRAY_SIZE(inpgal)),
@@ -2612,11 +2773,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2612 { "ADCL", NULL, "TOCLK" }, 2773 { "ADCL", NULL, "TOCLK" },
2613 { "ADCL", NULL, "MIXINL" }, 2774 { "ADCL", NULL, "MIXINL" },
2614 { "ADCL", NULL, "DMIC" }, 2775 { "ADCL", NULL, "DMIC" },
2776 { "ADCL", NULL, "DSP2" },
2615 2777
2616 { "ADCR", NULL, "SYSCLK" }, 2778 { "ADCR", NULL, "SYSCLK" },
2617 { "ADCR", NULL, "TOCLK" }, 2779 { "ADCR", NULL, "TOCLK" },
2618 { "ADCR", NULL, "MIXINR" }, 2780 { "ADCR", NULL, "MIXINR" },
2619 { "ADCR", NULL, "DMIC" }, 2781 { "ADCR", NULL, "DMIC" },
2782 { "ADCR", NULL, "DSP2" },
2620 2783
2621 { "STL", "Left", "ADCL" }, 2784 { "STL", "Left", "ADCL" },
2622 { "STL", "Right", "ADCR" }, 2785 { "STL", "Right", "ADCR" },
@@ -2628,11 +2791,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2628 { "DACL", NULL, "TOCLK" }, 2791 { "DACL", NULL, "TOCLK" },
2629 { "DACL", NULL, "Beep" }, 2792 { "DACL", NULL, "Beep" },
2630 { "DACL", NULL, "STL" }, 2793 { "DACL", NULL, "STL" },
2794 { "DACL", NULL, "DSP2" },
2631 2795
2632 { "DACR", NULL, "SYSCLK" }, 2796 { "DACR", NULL, "SYSCLK" },
2633 { "DACR", NULL, "TOCLK" }, 2797 { "DACR", NULL, "TOCLK" },
2634 { "DACR", NULL, "Beep" }, 2798 { "DACR", NULL, "Beep" },
2635 { "DACR", NULL, "STR" }, 2799 { "DACR", NULL, "STR" },
2800 { "DACR", NULL, "DSP2" },
2636 2801
2637 { "HPMIXL", "IN4L Switch", "IN4L" }, 2802 { "HPMIXL", "IN4L Switch", "IN4L" },
2638 { "HPMIXL", "IN4R Switch", "IN4R" }, 2803 { "HPMIXL", "IN4R Switch", "IN4R" },
@@ -3403,12 +3568,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3403 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3568 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3404 int mask; 3569 int mask;
3405 int active; 3570 int active;
3571 int reg;
3406 3572
3407 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 3573 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
3408 3574
3409 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3575 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3410 active &= ~mask; 3576 active &= ~mask;
3411 3577
3578 if (!active)
3579 return IRQ_NONE;
3580
3412 /* Acknowledge the interrupts */ 3581 /* Acknowledge the interrupts */
3413 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 3582 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
3414 3583
@@ -3420,9 +3589,21 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3420 if (active & WM8962_FIFOS_ERR_EINT) 3589 if (active & WM8962_FIFOS_ERR_EINT)
3421 dev_err(codec->dev, "FIFO error\n"); 3590 dev_err(codec->dev, "FIFO error\n");
3422 3591
3423 if (active & WM8962_TEMP_SHUT_EINT) 3592 if (active & WM8962_TEMP_SHUT_EINT) {
3424 dev_crit(codec->dev, "Thermal shutdown\n"); 3593 dev_crit(codec->dev, "Thermal shutdown\n");
3425 3594
3595 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS);
3596
3597 if (reg & WM8962_TEMP_ERR_HP)
3598 dev_crit(codec->dev, "Headphone thermal error\n");
3599 if (reg & WM8962_TEMP_WARN_HP)
3600 dev_crit(codec->dev, "Headphone thermal warning\n");
3601 if (reg & WM8962_TEMP_ERR_SPK)
3602 dev_crit(codec->dev, "Speaker thermal error\n");
3603 if (reg & WM8962_TEMP_WARN_SPK)
3604 dev_crit(codec->dev, "Speaker thermal warning\n");
3605 }
3606
3426 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3607 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3427 dev_dbg(codec->dev, "Microphone event detected\n"); 3608 dev_dbg(codec->dev, "Microphone event detected\n");
3428 3609
@@ -3479,31 +3660,6 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3479} 3660}
3480EXPORT_SYMBOL_GPL(wm8962_mic_detect); 3661EXPORT_SYMBOL_GPL(wm8962_mic_detect);
3481 3662
3482#ifdef CONFIG_PM
3483static int wm8962_resume(struct snd_soc_codec *codec)
3484{
3485 u16 *reg_cache = codec->reg_cache;
3486 int i;
3487
3488 /* Restore the registers */
3489 for (i = 1; i < codec->driver->reg_cache_size; i++) {
3490 switch (i) {
3491 case WM8962_SOFTWARE_RESET:
3492 continue;
3493 default:
3494 break;
3495 }
3496
3497 if (reg_cache[i] != wm8962_reg[i])
3498 snd_soc_write(codec, i, reg_cache[i]);
3499 }
3500
3501 return 0;
3502}
3503#else
3504#define wm8962_resume NULL
3505#endif
3506
3507#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 3663#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3508static int beep_rates[] = { 3664static int beep_rates[] = {
3509 500, 1000, 2000, 4000, 3665 500, 1000, 2000, 4000,
@@ -4015,7 +4171,6 @@ static int wm8962_remove(struct snd_soc_codec *codec)
4015static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { 4171static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
4016 .probe = wm8962_probe, 4172 .probe = wm8962_probe,
4017 .remove = wm8962_remove, 4173 .remove = wm8962_remove,
4018 .resume = wm8962_resume,
4019 .set_bias_level = wm8962_set_bias_level, 4174 .set_bias_level = wm8962_set_bias_level,
4020 .reg_cache_size = WM8962_MAX_REGISTER + 1, 4175 .reg_cache_size = WM8962_MAX_REGISTER + 1,
4021 .reg_word_size = sizeof(u16), 4176 .reg_word_size = sizeof(u16),
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 6e85b8869af..eec8e143511 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -847,6 +847,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 847 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0), 848SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0), 849SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
850SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0),
850 851
851SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0), 852SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
852SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0), 853SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
@@ -880,6 +881,9 @@ SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
880}; 881};
881 882
882static const struct snd_soc_dapm_route routes[] = { 883static const struct snd_soc_dapm_route routes[] = {
884 { "MICBIAS1", NULL, "VMID" },
885 { "MICBIAS2", NULL, "VMID" },
886
883 { "ADCL", NULL, "CLK_SYS" }, 887 { "ADCL", NULL, "CLK_SYS" },
884 { "ADCL", NULL, "CLK_DSP" }, 888 { "ADCL", NULL, "CLK_DSP" },
885 { "ADCR", NULL, "CLK_SYS" }, 889 { "ADCR", NULL, "CLK_SYS" },
@@ -1433,7 +1437,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1433 int ret, i, val; 1437 int ret, i, val;
1434 1438
1435 wm8993->hubs_data.hp_startup_mode = 1; 1439 wm8993->hubs_data.hp_startup_mode = 1;
1436 wm8993->hubs_data.dcs_codes = -2; 1440 wm8993->hubs_data.dcs_codes_l = -2;
1441 wm8993->hubs_data.dcs_codes_r = -2;
1437 wm8993->hubs_data.series_startup = 1; 1442 wm8993->hubs_data.series_startup = 1;
1438 1443
1439 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1444 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index a87adbd05ee..df5a8b9a250 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -1073,8 +1073,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1073 { 0x0000, 0x0000 }, /* R1069 */ 1073 { 0x0000, 0x0000 }, /* R1069 */
1074 { 0x0000, 0x0000 }, /* R1070 */ 1074 { 0x0000, 0x0000 }, /* R1070 */
1075 { 0x0000, 0x0000 }, /* R1071 */ 1075 { 0x0000, 0x0000 }, /* R1071 */
1076 { 0x0000, 0x0000 }, /* R1072 */ 1076 { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */
1077 { 0x0000, 0x0000 }, /* R1073 */ 1077 { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */
1078 { 0x0000, 0x0000 }, /* R1074 */ 1078 { 0x0000, 0x0000 }, /* R1074 */
1079 { 0x0000, 0x0000 }, /* R1075 */ 1079 { 0x0000, 0x0000 }, /* R1075 */
1080 { 0x0000, 0x0000 }, /* R1076 */ 1080 { 0x0000, 0x0000 }, /* R1076 */
@@ -1329,7 +1329,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1329 { 0x0000, 0x0000 }, /* R1325 */ 1329 { 0x0000, 0x0000 }, /* R1325 */
1330 { 0x0000, 0x0000 }, /* R1326 */ 1330 { 0x0000, 0x0000 }, /* R1326 */
1331 { 0x0000, 0x0000 }, /* R1327 */ 1331 { 0x0000, 0x0000 }, /* R1327 */
1332 { 0x0000, 0x0000 }, /* R1328 */ 1332 { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */
1333 { 0x0000, 0x0000 }, /* R1329 */ 1333 { 0x0000, 0x0000 }, /* R1329 */
1334 { 0x0000, 0x0000 }, /* R1330 */ 1334 { 0x0000, 0x0000 }, /* R1330 */
1335 { 0x0000, 0x0000 }, /* R1331 */ 1335 { 0x0000, 0x0000 }, /* R1331 */
@@ -1635,8 +1635,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1635 0x0000, /* R58 - MICBIAS */ 1635 0x0000, /* R58 - MICBIAS */
1636 0x000D, /* R59 - LDO 1 */ 1636 0x000D, /* R59 - LDO 1 */
1637 0x0003, /* R60 - LDO 2 */ 1637 0x0003, /* R60 - LDO 2 */
1638 0x0000, /* R61 */ 1638 0x0039, /* R61 - MICBIAS1 */
1639 0x0000, /* R62 */ 1639 0x0039, /* R62 - MICBIAS2 */
1640 0x0000, /* R63 */ 1640 0x0000, /* R63 */
1641 0x0000, /* R64 */ 1641 0x0000, /* R64 */
1642 0x0000, /* R65 */ 1642 0x0000, /* R65 */
@@ -2646,8 +2646,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2646 0x0000, /* R1069 */ 2646 0x0000, /* R1069 */
2647 0x0000, /* R1070 */ 2647 0x0000, /* R1070 */
2648 0x0000, /* R1071 */ 2648 0x0000, /* R1071 */
2649 0x0000, /* R1072 */ 2649 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */
2650 0x0000, /* R1073 */ 2650 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */
2651 0x0000, /* R1074 */ 2651 0x0000, /* R1074 */
2652 0x0000, /* R1075 */ 2652 0x0000, /* R1075 */
2653 0x0000, /* R1076 */ 2653 0x0000, /* R1076 */
@@ -2902,7 +2902,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
2902 0x0000, /* R1325 */ 2902 0x0000, /* R1325 */
2903 0x0000, /* R1326 */ 2903 0x0000, /* R1326 */
2904 0x0000, /* R1327 */ 2904 0x0000, /* R1327 */
2905 0x0000, /* R1328 */ 2905 0x0068, /* R1328 - AIF2 DAC Noise Gate */
2906 0x0000, /* R1329 */ 2906 0x0000, /* R1329 */
2907 0x0000, /* R1330 */ 2907 0x0000, /* R1330 */
2908 0x0000, /* R1331 */ 2908 0x0000, /* R1331 */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b393f9fac97..e5372675123 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -107,6 +107,7 @@ static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
107 case WM8994_LDO_2: 107 case WM8994_LDO_2:
108 case WM8958_DSP2_EXECCONTROL: 108 case WM8958_DSP2_EXECCONTROL:
109 case WM8958_MIC_DETECT_3: 109 case WM8958_MIC_DETECT_3:
110 case WM8994_DC_SERVO_4E:
110 return 1; 111 return 1;
111 default: 112 default:
112 return 0; 113 return 0;
@@ -281,6 +282,7 @@ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
281static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); 282static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
282static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); 283static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
283static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 284static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
285static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
284 286
285#define WM8994_DRC_SWITCH(xname, reg, shift) \ 287#define WM8994_DRC_SWITCH(xname, reg, shift) \
286{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 288{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -660,8 +662,45 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
660 eq_tlv), 662 eq_tlv),
661}; 663};
662 664
665static const char *wm8958_ng_text[] = {
666 "30ms", "125ms", "250ms", "500ms",
667};
668
669static const struct soc_enum wm8958_aif1dac1_ng_hold =
670 SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
671 WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
672
673static const struct soc_enum wm8958_aif1dac2_ng_hold =
674 SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
675 WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
676
677static const struct soc_enum wm8958_aif2dac_ng_hold =
678 SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
679 WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
680
663static const struct snd_kcontrol_new wm8958_snd_controls[] = { 681static const struct snd_kcontrol_new wm8958_snd_controls[] = {
664SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 682SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
683
684SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE,
685 WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0),
686SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold),
687SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume",
688 WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT,
689 7, 1, ng_tlv),
690
691SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE,
692 WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0),
693SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold),
694SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume",
695 WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT,
696 7, 1, ng_tlv),
697
698SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE,
699 WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0),
700SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold),
701SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
702 WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT,
703 7, 1, ng_tlv),
665}; 704};
666 705
667static int clk_sys_event(struct snd_soc_dapm_widget *w, 706static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -681,6 +720,97 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
681 return 0; 720 return 0;
682} 721}
683 722
723static void vmid_reference(struct snd_soc_codec *codec)
724{
725 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
726
727 wm8994->vmid_refcount++;
728
729 dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
730 wm8994->vmid_refcount);
731
732 if (wm8994->vmid_refcount == 1) {
733 /* Startup bias, VMID ramp & buffer */
734 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
735 WM8994_STARTUP_BIAS_ENA |
736 WM8994_VMID_BUF_ENA |
737 WM8994_VMID_RAMP_MASK,
738 WM8994_STARTUP_BIAS_ENA |
739 WM8994_VMID_BUF_ENA |
740 (0x11 << WM8994_VMID_RAMP_SHIFT));
741
742 /* Main bias enable, VMID=2x40k */
743 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
744 WM8994_BIAS_ENA |
745 WM8994_VMID_SEL_MASK,
746 WM8994_BIAS_ENA | 0x2);
747
748 msleep(20);
749 }
750}
751
752static void vmid_dereference(struct snd_soc_codec *codec)
753{
754 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
755
756 wm8994->vmid_refcount--;
757
758 dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
759 wm8994->vmid_refcount);
760
761 if (wm8994->vmid_refcount == 0) {
762 /* Switch over to startup biases */
763 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
764 WM8994_BIAS_SRC |
765 WM8994_STARTUP_BIAS_ENA |
766 WM8994_VMID_BUF_ENA |
767 WM8994_VMID_RAMP_MASK,
768 WM8994_BIAS_SRC |
769 WM8994_STARTUP_BIAS_ENA |
770 WM8994_VMID_BUF_ENA |
771 (1 << WM8994_VMID_RAMP_SHIFT));
772
773 /* Disable main biases */
774 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
775 WM8994_BIAS_ENA |
776 WM8994_VMID_SEL_MASK, 0);
777
778 /* Discharge line */
779 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
780 WM8994_LINEOUT1_DISCH |
781 WM8994_LINEOUT2_DISCH,
782 WM8994_LINEOUT1_DISCH |
783 WM8994_LINEOUT2_DISCH);
784
785 msleep(5);
786
787 /* Switch off startup biases */
788 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
789 WM8994_BIAS_SRC |
790 WM8994_STARTUP_BIAS_ENA |
791 WM8994_VMID_BUF_ENA |
792 WM8994_VMID_RAMP_MASK, 0);
793 }
794}
795
796static int vmid_event(struct snd_soc_dapm_widget *w,
797 struct snd_kcontrol *kcontrol, int event)
798{
799 struct snd_soc_codec *codec = w->codec;
800
801 switch (event) {
802 case SND_SOC_DAPM_PRE_PMU:
803 vmid_reference(codec);
804 break;
805
806 case SND_SOC_DAPM_POST_PMD:
807 vmid_dereference(codec);
808 break;
809 }
810
811 return 0;
812}
813
684static void wm8994_update_class_w(struct snd_soc_codec *codec) 814static void wm8994_update_class_w(struct snd_soc_codec *codec)
685{ 815{
686 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 816 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1208,6 +1338,8 @@ SND_SOC_DAPM_INPUT("Clock"),
1208 1338
1209SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, 1339SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1210 SND_SOC_DAPM_PRE_PMU), 1340 SND_SOC_DAPM_PRE_PMU),
1341SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
1342 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1211 1343
1212SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1344SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1213 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1345 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1525,6 +1657,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1525static const struct snd_soc_dapm_route wm8994_intercon[] = { 1657static const struct snd_soc_dapm_route wm8994_intercon[] = {
1526 { "AIF2DACL", NULL, "AIF2DAC Mux" }, 1658 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1527 { "AIF2DACR", NULL, "AIF2DAC Mux" }, 1659 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1660 { "MICBIAS1", NULL, "VMID" },
1661 { "MICBIAS2", NULL, "VMID" },
1528}; 1662};
1529 1663
1530static const struct snd_soc_dapm_route wm8958_intercon[] = { 1664static const struct snd_soc_dapm_route wm8958_intercon[] = {
@@ -1629,10 +1763,12 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1629 unsigned int freq_in, unsigned int freq_out) 1763 unsigned int freq_in, unsigned int freq_out)
1630{ 1764{
1631 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1765 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1766 struct wm8994 *control = codec->control_data;
1632 int reg_offset, ret; 1767 int reg_offset, ret;
1633 struct fll_div fll; 1768 struct fll_div fll;
1634 u16 reg, aif1, aif2; 1769 u16 reg, aif1, aif2;
1635 unsigned long timeout; 1770 unsigned long timeout;
1771 bool was_enabled;
1636 1772
1637 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) 1773 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1638 & WM8994_AIF1CLK_ENA; 1774 & WM8994_AIF1CLK_ENA;
@@ -1653,6 +1789,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1653 return -EINVAL; 1789 return -EINVAL;
1654 } 1790 }
1655 1791
1792 reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
1793 was_enabled = reg & WM8994_FLL1_ENA;
1794
1656 switch (src) { 1795 switch (src) {
1657 case 0: 1796 case 0:
1658 /* Allow no source specification when stopping */ 1797 /* Allow no source specification when stopping */
@@ -1719,6 +1858,21 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1719 1858
1720 /* Enable (with fractional mode if required) */ 1859 /* Enable (with fractional mode if required) */
1721 if (freq_out) { 1860 if (freq_out) {
1861 /* Enable VMID if we need it */
1862 if (!was_enabled) {
1863 switch (control->type) {
1864 case WM8994:
1865 vmid_reference(codec);
1866 break;
1867 case WM8958:
1868 if (wm8994->revision < 1)
1869 vmid_reference(codec);
1870 break;
1871 default:
1872 break;
1873 }
1874 }
1875
1722 if (fll.k) 1876 if (fll.k)
1723 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; 1877 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
1724 else 1878 else
@@ -1736,6 +1890,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1736 } else { 1890 } else {
1737 msleep(5); 1891 msleep(5);
1738 } 1892 }
1893 } else {
1894 if (was_enabled) {
1895 switch (control->type) {
1896 case WM8994:
1897 vmid_dereference(codec);
1898 break;
1899 case WM8958:
1900 if (wm8994->revision < 1)
1901 vmid_dereference(codec);
1902 break;
1903 default:
1904 break;
1905 }
1906 }
1739 } 1907 }
1740 1908
1741 wm8994->fll[id].in = freq_in; 1909 wm8994->fll[id].in = freq_in;
@@ -1852,9 +2020,6 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1852 break; 2020 break;
1853 2021
1854 case SND_SOC_BIAS_PREPARE: 2022 case SND_SOC_BIAS_PREPARE:
1855 /* VMID=2x40k */
1856 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1857 WM8994_VMID_SEL_MASK, 0x2);
1858 break; 2023 break;
1859 2024
1860 case SND_SOC_BIAS_STANDBY: 2025 case SND_SOC_BIAS_STANDBY:
@@ -1896,65 +2061,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1896 WM8994_LINEOUT2_DISCH, 2061 WM8994_LINEOUT2_DISCH,
1897 WM8994_LINEOUT1_DISCH | 2062 WM8994_LINEOUT1_DISCH |
1898 WM8994_LINEOUT2_DISCH); 2063 WM8994_LINEOUT2_DISCH);
1899
1900 /* Startup bias, VMID ramp & buffer */
1901 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1902 WM8994_STARTUP_BIAS_ENA |
1903 WM8994_VMID_BUF_ENA |
1904 WM8994_VMID_RAMP_MASK,
1905 WM8994_STARTUP_BIAS_ENA |
1906 WM8994_VMID_BUF_ENA |
1907 (0x11 << WM8994_VMID_RAMP_SHIFT));
1908
1909 /* Main bias enable, VMID=2x40k */
1910 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1911 WM8994_BIAS_ENA |
1912 WM8994_VMID_SEL_MASK,
1913 WM8994_BIAS_ENA | 0x2);
1914
1915 msleep(20);
1916 } 2064 }
1917 2065
1918 /* VMID=2x500k */
1919 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1920 WM8994_VMID_SEL_MASK, 0x4);
1921 2066
1922 break; 2067 break;
1923 2068
1924 case SND_SOC_BIAS_OFF: 2069 case SND_SOC_BIAS_OFF:
1925 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { 2070 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1926 /* Switch over to startup biases */
1927 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1928 WM8994_BIAS_SRC |
1929 WM8994_STARTUP_BIAS_ENA |
1930 WM8994_VMID_BUF_ENA |
1931 WM8994_VMID_RAMP_MASK,
1932 WM8994_BIAS_SRC |
1933 WM8994_STARTUP_BIAS_ENA |
1934 WM8994_VMID_BUF_ENA |
1935 (1 << WM8994_VMID_RAMP_SHIFT));
1936
1937 /* Disable main biases */
1938 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
1939 WM8994_BIAS_ENA |
1940 WM8994_VMID_SEL_MASK, 0);
1941
1942 /* Discharge line */
1943 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
1944 WM8994_LINEOUT1_DISCH |
1945 WM8994_LINEOUT2_DISCH,
1946 WM8994_LINEOUT1_DISCH |
1947 WM8994_LINEOUT2_DISCH);
1948
1949 msleep(5);
1950
1951 /* Switch off startup biases */
1952 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
1953 WM8994_BIAS_SRC |
1954 WM8994_STARTUP_BIAS_ENA |
1955 WM8994_VMID_BUF_ENA |
1956 WM8994_VMID_RAMP_MASK, 0);
1957
1958 wm8994->cur_fw = NULL; 2071 wm8994->cur_fw = NULL;
1959 2072
1960 pm_runtime_put(codec->dev); 2073 pm_runtime_put(codec->dev);
@@ -2384,6 +2497,21 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
2384 return snd_soc_update_bits(codec, reg, mask, val); 2497 return snd_soc_update_bits(codec, reg, mask, val);
2385} 2498}
2386 2499
2500static int wm8994_aif2_probe(struct snd_soc_dai *dai)
2501{
2502 struct snd_soc_codec *codec = dai->codec;
2503
2504 /* Disable the pulls on the AIF if we're using it to save power. */
2505 snd_soc_update_bits(codec, WM8994_GPIO_3,
2506 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2507 snd_soc_update_bits(codec, WM8994_GPIO_4,
2508 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2509 snd_soc_update_bits(codec, WM8994_GPIO_5,
2510 WM8994_GPN_PU | WM8994_GPN_PD, 0);
2511
2512 return 0;
2513}
2514
2387#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 2515#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
2388 2516
2389#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2517#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -2451,6 +2579,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2451 .rates = WM8994_RATES, 2579 .rates = WM8994_RATES,
2452 .formats = WM8994_FORMATS, 2580 .formats = WM8994_FORMATS,
2453 }, 2581 },
2582 .probe = wm8994_aif2_probe,
2454 .ops = &wm8994_aif2_dai_ops, 2583 .ops = &wm8994_aif2_dai_ops,
2455 }, 2584 },
2456 { 2585 {
@@ -2916,6 +3045,24 @@ static irqreturn_t wm8994_fifo_error(int irq, void *data)
2916 return IRQ_HANDLED; 3045 return IRQ_HANDLED;
2917} 3046}
2918 3047
3048static irqreturn_t wm8994_temp_warn(int irq, void *data)
3049{
3050 struct snd_soc_codec *codec = data;
3051
3052 dev_err(codec->dev, "Thermal warning\n");
3053
3054 return IRQ_HANDLED;
3055}
3056
3057static irqreturn_t wm8994_temp_shut(int irq, void *data)
3058{
3059 struct snd_soc_codec *codec = data;
3060
3061 dev_crit(codec->dev, "Thermal shutdown\n");
3062
3063 return IRQ_HANDLED;
3064}
3065
2919static int wm8994_codec_probe(struct snd_soc_codec *codec) 3066static int wm8994_codec_probe(struct snd_soc_codec *codec)
2920{ 3067{
2921 struct wm8994 *control; 3068 struct wm8994 *control;
@@ -2972,13 +3119,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2972 switch (wm8994->revision) { 3119 switch (wm8994->revision) {
2973 case 2: 3120 case 2:
2974 case 3: 3121 case 3:
2975 wm8994->hubs.dcs_codes = -5; 3122 wm8994->hubs.dcs_codes_l = -5;
3123 wm8994->hubs.dcs_codes_r = -5;
2976 wm8994->hubs.hp_startup_mode = 1; 3124 wm8994->hubs.hp_startup_mode = 1;
2977 wm8994->hubs.dcs_readback_mode = 1; 3125 wm8994->hubs.dcs_readback_mode = 1;
2978 wm8994->hubs.series_startup = 1; 3126 wm8994->hubs.series_startup = 1;
2979 break; 3127 break;
2980 default: 3128 default:
2981 wm8994->hubs.dcs_readback_mode = 1; 3129 wm8994->hubs.dcs_readback_mode = 2;
2982 break; 3130 break;
2983 } 3131 }
2984 break; 3132 break;
@@ -2993,6 +3141,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2993 3141
2994 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, 3142 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
2995 wm8994_fifo_error, "FIFO error", codec); 3143 wm8994_fifo_error, "FIFO error", codec);
3144 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
3145 wm8994_temp_warn, "Thermal warning", codec);
3146 wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
3147 wm8994_temp_shut, "Thermal shutdown", codec);
2996 3148
2997 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3149 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
2998 wm_hubs_dcs_done, "DC servo done", 3150 wm_hubs_dcs_done, "DC servo done",
@@ -3257,6 +3409,8 @@ err_irq:
3257 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3409 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3258 &wm8994->hubs); 3410 &wm8994->hubs);
3259 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3411 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3412 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3413 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3260err: 3414err:
3261 kfree(wm8994); 3415 kfree(wm8994);
3262 return ret; 3416 return ret;
@@ -3279,6 +3433,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3279 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, 3433 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3280 &wm8994->hubs); 3434 &wm8994->hubs);
3281 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); 3435 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3436 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
3437 wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
3282 3438
3283 switch (control->type) { 3439 switch (control->type) {
3284 case WM8994: 3440 case WM8994:
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 1ab2266039f..f4f1355efc8 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -83,6 +83,8 @@ struct wm8994_priv {
83 struct completion fll_locked[2]; 83 struct completion fll_locked[2];
84 bool fll_locked_irq; 84 bool fll_locked_irq;
85 85
86 int vmid_refcount;
87
86 int dac_rates[2]; 88 int dac_rates[2];
87 int lrclk_shared[2]; 89 int lrclk_shared[2];
88 90
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 5ad873fda81..74ae5995a78 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -1573,9 +1573,7 @@ static int wm8995_resume(struct snd_soc_codec *codec)
1573static int wm8995_remove(struct snd_soc_codec *codec) 1573static int wm8995_remove(struct snd_soc_codec *codec)
1574{ 1574{
1575 struct wm8995_priv *wm8995; 1575 struct wm8995_priv *wm8995;
1576 struct i2c_client *i2c;
1577 1576
1578 i2c = container_of(codec->dev, struct i2c_client, dev);
1579 wm8995 = snd_soc_codec_get_drvdata(codec); 1577 wm8995 = snd_soc_codec_get_drvdata(codec);
1580 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); 1578 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1581 return 0; 1579 return 0;
@@ -1642,6 +1640,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1642 1640
1643 if (ret != 0x8995) { 1641 if (ret != 0x8995) {
1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret); 1642 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1643 ret = -EINVAL;
1645 goto err_reg_enable; 1644 goto err_reg_enable;
1646 } 1645 }
1647 1646
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 0cdb9d10567..833df74c558 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -41,12 +41,11 @@
41#define HPOUT2L 4 41#define HPOUT2L 4
42#define HPOUT2R 8 42#define HPOUT2R 8
43 43
44#define WM8996_NUM_SUPPLIES 4 44#define WM8996_NUM_SUPPLIES 3
45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { 45static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
46 "DBVDD", 46 "DBVDD",
47 "AVDD1", 47 "AVDD1",
48 "AVDD2", 48 "AVDD2",
49 "CPVDD",
50}; 49};
51 50
52struct wm8996_priv { 51struct wm8996_priv {
@@ -71,6 +70,8 @@ struct wm8996_priv {
71 70
72 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 71 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
73 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 72 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
73 struct regulator *cpvdd;
74 int bg_ena;
74 75
75 struct wm8996_pdata pdata; 76 struct wm8996_pdata pdata;
76 77
@@ -112,7 +113,6 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
112WM8996_REGULATOR_EVENT(0) 113WM8996_REGULATOR_EVENT(0)
113WM8996_REGULATOR_EVENT(1) 114WM8996_REGULATOR_EVENT(1)
114WM8996_REGULATOR_EVENT(2) 115WM8996_REGULATOR_EVENT(2)
115WM8996_REGULATOR_EVENT(3)
116 116
117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { 117static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
118 [WM8996_SOFTWARE_RESET] = 0x8996, 118 [WM8996_SOFTWARE_RESET] = 0x8996,
@@ -414,6 +414,7 @@ static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); 414static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); 415static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 416static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
417static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);
417 418
418static const char *sidetone_hpf_text[] = { 419static const char *sidetone_hpf_text[] = {
419 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" 420 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
@@ -608,6 +609,14 @@ SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
608SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), 609SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
609SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), 610SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
610 611
612SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),
613SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),
614
615SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,
616 0, threedstereo_tlv),
617SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,
618 0, threedstereo_tlv),
619
611SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, 620SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
612 8, 0, out_digital_tlv), 621 8, 0, out_digital_tlv),
613SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, 622SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
@@ -658,19 +667,75 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
658 eq_tlv), 667 eq_tlv),
659}; 668};
660 669
670static void wm8996_bg_enable(struct snd_soc_codec *codec)
671{
672 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
673
674 wm8996->bg_ena++;
675 if (wm8996->bg_ena == 1) {
676 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
677 WM8996_BG_ENA, WM8996_BG_ENA);
678 msleep(2);
679 }
680}
681
682static void wm8996_bg_disable(struct snd_soc_codec *codec)
683{
684 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
685
686 wm8996->bg_ena--;
687 if (!wm8996->bg_ena)
688 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
689 WM8996_BG_ENA, 0);
690}
691
692static int bg_event(struct snd_soc_dapm_widget *w,
693 struct snd_kcontrol *kcontrol, int event)
694{
695 struct snd_soc_codec *codec = w->codec;
696 int ret = 0;
697
698 switch (event) {
699 case SND_SOC_DAPM_PRE_PMU:
700 wm8996_bg_enable(codec);
701 break;
702 case SND_SOC_DAPM_POST_PMD:
703 wm8996_bg_disable(codec);
704 break;
705 default:
706 BUG();
707 ret = -EINVAL;
708 }
709
710 return ret;
711}
712
661static int cp_event(struct snd_soc_dapm_widget *w, 713static int cp_event(struct snd_soc_dapm_widget *w,
662 struct snd_kcontrol *kcontrol, int event) 714 struct snd_kcontrol *kcontrol, int event)
663{ 715{
716 struct snd_soc_codec *codec = w->codec;
717 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
718 int ret = 0;
719
664 switch (event) { 720 switch (event) {
721 case SND_SOC_DAPM_PRE_PMU:
722 ret = regulator_enable(wm8996->cpvdd);
723 if (ret != 0)
724 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
725 ret);
726 break;
665 case SND_SOC_DAPM_POST_PMU: 727 case SND_SOC_DAPM_POST_PMU:
666 msleep(5); 728 msleep(5);
667 break; 729 break;
730 case SND_SOC_DAPM_POST_PMD:
731 regulator_disable_deferred(wm8996->cpvdd, 20);
732 break;
668 default: 733 default:
669 BUG(); 734 BUG();
670 return -EINVAL; 735 ret = -EINVAL;
671 } 736 }
672 737
673 return 0; 738 return ret;
674} 739}
675 740
676static int rmv_short_event(struct snd_soc_dapm_widget *w, 741static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -698,7 +763,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
698{ 763{
699 struct i2c_client *i2c = to_i2c_client(codec->dev); 764 struct i2c_client *i2c = to_i2c_client(codec->dev);
700 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 765 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
701 int i, ret; 766 int ret;
702 unsigned long timeout = 200; 767 unsigned long timeout = 200;
703 768
704 snd_soc_write(codec, WM8996_DC_SERVO_2, mask); 769 snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
@@ -713,15 +778,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
713 778
714 } else { 779 } else {
715 msleep(1); 780 msleep(1);
716 if (--i) { 781 timeout--;
717 timeout = 0;
718 break;
719 }
720 } 782 }
721 783
722 ret = snd_soc_read(codec, WM8996_DC_SERVO_2); 784 ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
723 dev_dbg(codec->dev, "DC servo state: %x\n", ret); 785 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
724 } while (ret & mask); 786 } while (timeout && ret & mask);
725 787
726 if (timeout == 0) 788 if (timeout == 0)
727 dev_err(codec->dev, "DC servo timed out for %x\n", mask); 789 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
@@ -979,9 +1041,12 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
979SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1041SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
980SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1042SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
981SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1043SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
982 SND_SOC_DAPM_POST_PMU), 1044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
983 1045SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1046 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
984SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1047SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
1048SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
1049SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
985SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), 1050SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
986SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), 1051SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
987 1052
@@ -1035,14 +1100,14 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1035SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1100SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1036SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1101SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1037 1102
1038SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, 1103SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
1039 WM8996_POWER_MANAGEMENT_4, 9, 0), 1104 WM8996_POWER_MANAGEMENT_4, 9, 0),
1040SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, 1105SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1,
1041 WM8996_POWER_MANAGEMENT_4, 8, 0), 1106 WM8996_POWER_MANAGEMENT_4, 8, 0),
1042 1107
1043SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, 1108SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 0,
1044 WM8996_POWER_MANAGEMENT_6, 9, 0), 1109 WM8996_POWER_MANAGEMENT_6, 9, 0),
1045SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, 1110SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 1,
1046 WM8996_POWER_MANAGEMENT_6, 8, 0), 1111 WM8996_POWER_MANAGEMENT_6, 8, 0),
1047 1112
1048SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1113SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
@@ -1137,17 +1202,23 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1137 { "Charge Pump", NULL, "SYSCLK" }, 1202 { "Charge Pump", NULL, "SYSCLK" },
1138 1203
1139 { "MICB1", NULL, "LDO2" }, 1204 { "MICB1", NULL, "LDO2" },
1205 { "MICB1", NULL, "MICB1 Audio" },
1206 { "MICB1", NULL, "Bandgap" },
1140 { "MICB2", NULL, "LDO2" }, 1207 { "MICB2", NULL, "LDO2" },
1208 { "MICB2", NULL, "MICB2 Audio" },
1209 { "MICB2", NULL, "Bandgap" },
1141 1210
1142 { "IN1L PGA", NULL, "IN2LN" }, 1211 { "IN1L PGA", NULL, "IN2LN" },
1143 { "IN1L PGA", NULL, "IN2LP" }, 1212 { "IN1L PGA", NULL, "IN2LP" },
1144 { "IN1L PGA", NULL, "IN1LN" }, 1213 { "IN1L PGA", NULL, "IN1LN" },
1145 { "IN1L PGA", NULL, "IN1LP" }, 1214 { "IN1L PGA", NULL, "IN1LP" },
1215 { "IN1L PGA", NULL, "Bandgap" },
1146 1216
1147 { "IN1R PGA", NULL, "IN2RN" }, 1217 { "IN1R PGA", NULL, "IN2RN" },
1148 { "IN1R PGA", NULL, "IN2RP" }, 1218 { "IN1R PGA", NULL, "IN2RP" },
1149 { "IN1R PGA", NULL, "IN1RN" }, 1219 { "IN1R PGA", NULL, "IN1RN" },
1150 { "IN1R PGA", NULL, "IN1RP" }, 1220 { "IN1R PGA", NULL, "IN1RP" },
1221 { "IN1R PGA", NULL, "Bandgap" },
1151 1222
1152 { "ADCL", NULL, "IN1L PGA" }, 1223 { "ADCL", NULL, "IN1L PGA" },
1153 1224
@@ -1281,6 +1352,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1281 { "DAC2R", NULL, "DAC2R Mixer" }, 1352 { "DAC2R", NULL, "DAC2R Mixer" },
1282 1353
1283 { "HPOUT2L PGA", NULL, "Charge Pump" }, 1354 { "HPOUT2L PGA", NULL, "Charge Pump" },
1355 { "HPOUT2L PGA", NULL, "Bandgap" },
1284 { "HPOUT2L PGA", NULL, "DAC2L" }, 1356 { "HPOUT2L PGA", NULL, "DAC2L" },
1285 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, 1357 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1286 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, 1358 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
@@ -1288,6 +1360,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1288 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, 1360 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1289 1361
1290 { "HPOUT2R PGA", NULL, "Charge Pump" }, 1362 { "HPOUT2R PGA", NULL, "Charge Pump" },
1363 { "HPOUT2R PGA", NULL, "Bandgap" },
1291 { "HPOUT2R PGA", NULL, "DAC2R" }, 1364 { "HPOUT2R PGA", NULL, "DAC2R" },
1292 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, 1365 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1293 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, 1366 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
@@ -1295,6 +1368,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1295 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, 1368 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1296 1369
1297 { "HPOUT1L PGA", NULL, "Charge Pump" }, 1370 { "HPOUT1L PGA", NULL, "Charge Pump" },
1371 { "HPOUT1L PGA", NULL, "Bandgap" },
1298 { "HPOUT1L PGA", NULL, "DAC1L" }, 1372 { "HPOUT1L PGA", NULL, "DAC1L" },
1299 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, 1373 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1300 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, 1374 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
@@ -1302,6 +1376,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1302 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, 1376 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1303 1377
1304 { "HPOUT1R PGA", NULL, "Charge Pump" }, 1378 { "HPOUT1R PGA", NULL, "Charge Pump" },
1379 { "HPOUT1R PGA", NULL, "Bandgap" },
1305 { "HPOUT1R PGA", NULL, "DAC1R" }, 1380 { "HPOUT1R PGA", NULL, "DAC1R" },
1306 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, 1381 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1307 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, 1382 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
@@ -1620,14 +1695,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1620 1695
1621 switch (level) { 1696 switch (level) {
1622 case SND_SOC_BIAS_ON: 1697 case SND_SOC_BIAS_ON:
1623 break;
1624
1625 case SND_SOC_BIAS_PREPARE: 1698 case SND_SOC_BIAS_PREPARE:
1626 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1627 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1628 WM8996_BG_ENA, WM8996_BG_ENA);
1629 msleep(2);
1630 }
1631 break; 1699 break;
1632 1700
1633 case SND_SOC_BIAS_STANDBY: 1701 case SND_SOC_BIAS_STANDBY:
@@ -1650,9 +1718,6 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1650 codec->cache_only = false; 1718 codec->cache_only = false;
1651 snd_soc_cache_sync(codec); 1719 snd_soc_cache_sync(codec);
1652 } 1720 }
1653
1654 snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
1655 WM8996_BG_ENA, 0);
1656 break; 1721 break;
1657 1722
1658 case SND_SOC_BIAS_OFF: 1723 case SND_SOC_BIAS_OFF:
@@ -2041,7 +2106,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2041 struct i2c_client *i2c = to_i2c_client(codec->dev); 2106 struct i2c_client *i2c = to_i2c_client(codec->dev);
2042 struct _fll_div fll_div; 2107 struct _fll_div fll_div;
2043 unsigned long timeout; 2108 unsigned long timeout;
2044 int ret, reg; 2109 int ret, reg, retry;
2045 2110
2046 /* Any change? */ 2111 /* Any change? */
2047 if (source == wm8996->fll_src && Fref == wm8996->fll_fref && 2112 if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
@@ -2057,6 +2122,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2057 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, 2122 snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
2058 WM8996_FLL_ENA, 0); 2123 WM8996_FLL_ENA, 0);
2059 2124
2125 wm8996_bg_disable(codec);
2126
2060 return 0; 2127 return 0;
2061 } 2128 }
2062 2129
@@ -2111,6 +2178,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2111 2178
2112 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); 2179 snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
2113 2180
2181 /* Enable the bandgap if it's not already enabled */
2182 ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
2183 if (!(ret & WM8996_FLL_ENA))
2184 wm8996_bg_enable(codec);
2185
2114 /* Clear any pending completions (eg, from failed startups) */ 2186 /* Clear any pending completions (eg, from failed startups) */
2115 try_wait_for_completion(&wm8996->fll_lock); 2187 try_wait_for_completion(&wm8996->fll_lock);
2116 2188
@@ -2128,17 +2200,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2128 else 2200 else
2129 timeout = msecs_to_jiffies(2); 2201 timeout = msecs_to_jiffies(2);
2130 2202
2131 /* Allow substantially longer if we've actually got the IRQ */ 2203 /* Allow substantially longer if we've actually got the IRQ, poll
2204 * at a slightly higher rate if we don't.
2205 */
2132 if (i2c->irq) 2206 if (i2c->irq)
2133 timeout *= 1000; 2207 timeout *= 10;
2208 else
2209 timeout /= 2;
2134 2210
2135 ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); 2211 for (retry = 0; retry < 10; retry++) {
2212 ret = wait_for_completion_timeout(&wm8996->fll_lock,
2213 timeout);
2214 if (ret != 0) {
2215 WARN_ON(!i2c->irq);
2216 break;
2217 }
2136 2218
2137 if (ret == 0 && i2c->irq) { 2219 ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
2220 if (ret & WM8996_FLL_LOCK_STS)
2221 break;
2222 }
2223 if (retry == 10) {
2138 dev_err(codec->dev, "Timed out waiting for FLL\n"); 2224 dev_err(codec->dev, "Timed out waiting for FLL\n");
2139 ret = -ETIMEDOUT; 2225 ret = -ETIMEDOUT;
2140 } else {
2141 ret = 0;
2142 } 2226 }
2143 2227
2144 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2228 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
@@ -2297,12 +2381,94 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2297 2381
2298 /* Enable interrupts and we're off */ 2382 /* Enable interrupts and we're off */
2299 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, 2383 snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
2300 WM8996_IM_MICD_EINT, 0); 2384 WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
2301 2385
2302 return 0; 2386 return 0;
2303} 2387}
2304EXPORT_SYMBOL_GPL(wm8996_detect); 2388EXPORT_SYMBOL_GPL(wm8996_detect);
2305 2389
2390static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
2391{
2392 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2393 int val, reg, report;
2394
2395 /* Assume headphone in error conditions; we need to report
2396 * something or we stall our state machine.
2397 */
2398 report = SND_JACK_HEADPHONE;
2399
2400 reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
2401 if (reg < 0) {
2402 dev_err(codec->dev, "Failed to read HPDET status\n");
2403 goto out;
2404 }
2405
2406 if (!(reg & WM8996_HP_DONE)) {
2407 dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
2408 goto out;
2409 }
2410
2411 val = reg & WM8996_HP_LVL_MASK;
2412
2413 dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
2414
2415 /* If we've got high enough impedence then report as line,
2416 * otherwise assume headphone.
2417 */
2418 if (val >= 126)
2419 report = SND_JACK_LINEOUT;
2420 else
2421 report = SND_JACK_HEADPHONE;
2422
2423out:
2424 if (wm8996->jack_mic)
2425 report |= SND_JACK_MICROPHONE;
2426
2427 snd_soc_jack_report(wm8996->jack, report,
2428 SND_JACK_LINEOUT | SND_JACK_HEADSET);
2429
2430 wm8996->detecting = false;
2431
2432 /* If the output isn't running re-clamp it */
2433 if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
2434 (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
2435 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2436 WM8996_HPOUT1L_RMV_SHORT |
2437 WM8996_HPOUT1R_RMV_SHORT, 0);
2438
2439 /* Go back to looking at the microphone */
2440 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2441 WM8996_JD_MODE_MASK, 0);
2442 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
2443 WM8996_MICD_ENA);
2444
2445 snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap");
2446 snd_soc_dapm_sync(&codec->dapm);
2447}
2448
2449static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2450{
2451 /* Unclamp the output, we can't measure while we're shorting it */
2452 snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
2453 WM8996_HPOUT1L_RMV_SHORT |
2454 WM8996_HPOUT1R_RMV_SHORT,
2455 WM8996_HPOUT1L_RMV_SHORT |
2456 WM8996_HPOUT1R_RMV_SHORT);
2457
2458 /* We need bandgap for HPDET */
2459 snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap");
2460 snd_soc_dapm_sync(&codec->dapm);
2461
2462 /* Go into headphone detect left mode */
2463 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
2464 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
2465 WM8996_JD_MODE_MASK, 1);
2466
2467 /* Trigger a measurement */
2468 snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
2469 WM8996_HP_POLL, WM8996_HP_POLL);
2470}
2471
2306static void wm8996_micd(struct snd_soc_codec *codec) 2472static void wm8996_micd(struct snd_soc_codec *codec)
2307{ 2473{
2308 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2474 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2323,28 +2489,36 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2323 wm8996->jack_mic = false; 2489 wm8996->jack_mic = false;
2324 wm8996->detecting = true; 2490 wm8996->detecting = true;
2325 snd_soc_jack_report(wm8996->jack, 0, 2491 snd_soc_jack_report(wm8996->jack, 0,
2326 SND_JACK_HEADSET | SND_JACK_BTN_0); 2492 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2493 SND_JACK_BTN_0);
2494
2327 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2495 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2328 WM8996_MICD_RATE_MASK, 2496 WM8996_MICD_RATE_MASK,
2329 WM8996_MICD_RATE_MASK); 2497 WM8996_MICD_RATE_MASK);
2330 return; 2498 return;
2331 } 2499 }
2332 2500
2333 /* If the measurement is very high we've got a microphone but 2501 /* If the measurement is very high we've got a microphone,
2334 * do a little debounce to account for mechanical issues. 2502 * either we just detected one or if we already reported then
2503 * we've got a button release event.
2335 */ 2504 */
2336 if (val & 0x400) { 2505 if (val & 0x400) {
2337 dev_dbg(codec->dev, "Microphone detected\n"); 2506 if (wm8996->detecting) {
2338 snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, 2507 dev_dbg(codec->dev, "Microphone detected\n");
2339 SND_JACK_HEADSET | SND_JACK_BTN_0); 2508 wm8996->jack_mic = true;
2340 wm8996->jack_mic = true; 2509 wm8996_hpdet_start(codec);
2341 wm8996->detecting = false; 2510
2342 2511 /* Increase poll rate to give better responsiveness
2343 /* Increase poll rate to give better responsiveness 2512 * for buttons */
2344 * for buttons */ 2513 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2345 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2514 WM8996_MICD_RATE_MASK,
2346 WM8996_MICD_RATE_MASK, 2515 5 << WM8996_MICD_RATE_SHIFT);
2347 5 << WM8996_MICD_RATE_SHIFT); 2516 } else {
2517 dev_dbg(codec->dev, "Mic button up\n");
2518 snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
2519 }
2520
2521 return;
2348 } 2522 }
2349 2523
2350 /* If we detected a lower impedence during initial startup 2524 /* If we detected a lower impedence during initial startup
@@ -2376,15 +2550,11 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2376 if (val & 0x3fc) { 2550 if (val & 0x3fc) {
2377 if (wm8996->jack_mic) { 2551 if (wm8996->jack_mic) {
2378 dev_dbg(codec->dev, "Mic button detected\n"); 2552 dev_dbg(codec->dev, "Mic button detected\n");
2379 snd_soc_jack_report(wm8996->jack, 2553 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2380 SND_JACK_HEADSET | SND_JACK_BTN_0,
2381 SND_JACK_HEADSET | SND_JACK_BTN_0);
2382 } else {
2383 dev_dbg(codec->dev, "Headphone detected\n");
2384 snd_soc_jack_report(wm8996->jack,
2385 SND_JACK_HEADPHONE,
2386 SND_JACK_HEADSET |
2387 SND_JACK_BTN_0); 2554 SND_JACK_BTN_0);
2555 } else if (wm8996->detecting) {
2556 dev_dbg(codec->dev, "Headphone detected\n");
2557 wm8996_hpdet_start(codec);
2388 2558
2389 /* Increase the detection rate a bit for 2559 /* Increase the detection rate a bit for
2390 * responsiveness. 2560 * responsiveness.
@@ -2392,8 +2562,6 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2392 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, 2562 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2393 WM8996_MICD_RATE_MASK, 2563 WM8996_MICD_RATE_MASK,
2394 7 << WM8996_MICD_RATE_SHIFT); 2564 7 << WM8996_MICD_RATE_SHIFT);
2395
2396 wm8996->detecting = false;
2397 } 2565 }
2398 } 2566 }
2399} 2567}
@@ -2412,6 +2580,9 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2412 } 2580 }
2413 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); 2581 irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
2414 2582
2583 if (!irq_val)
2584 return IRQ_NONE;
2585
2415 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); 2586 snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
2416 2587
2417 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { 2588 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
@@ -2430,10 +2601,10 @@ static irqreturn_t wm8996_irq(int irq, void *data)
2430 if (irq_val & WM8996_MICD_EINT) 2601 if (irq_val & WM8996_MICD_EINT)
2431 wm8996_micd(codec); 2602 wm8996_micd(codec);
2432 2603
2433 if (irq_val) 2604 if (irq_val & WM8996_HP_DONE_EINT)
2434 return IRQ_HANDLED; 2605 wm8996_hpdet_irq(codec);
2435 else 2606
2436 return IRQ_NONE; 2607 return IRQ_HANDLED;
2437} 2608}
2438 2609
2439static irqreturn_t wm8996_edge_irq(int irq, void *data) 2610static irqreturn_t wm8996_edge_irq(int irq, void *data)
@@ -2548,7 +2719,13 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2548 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; 2719 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2549 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; 2720 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2550 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; 2721 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2551 wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; 2722
2723 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2724 if (IS_ERR(wm8996->cpvdd)) {
2725 ret = PTR_ERR(wm8996->cpvdd);
2726 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2727 goto err_get;
2728 }
2552 2729
2553 /* This should really be moved into the regulator core */ 2730 /* This should really be moved into the regulator core */
2554 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { 2731 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
@@ -2565,7 +2742,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2565 wm8996->supplies); 2742 wm8996->supplies);
2566 if (ret != 0) { 2743 if (ret != 0) {
2567 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 2744 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2568 goto err_get; 2745 goto err_cpvdd;
2569 } 2746 }
2570 2747
2571 if (wm8996->pdata.ldo_ena >= 0) { 2748 if (wm8996->pdata.ldo_ena >= 0) {
@@ -2808,6 +2985,8 @@ err_enable:
2808 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 2985 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
2809 2986
2810 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2987 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2988err_cpvdd:
2989 regulator_put(wm8996->cpvdd);
2811err_get: 2990err_get:
2812 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2991 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2813err: 2992err:
@@ -2831,6 +3010,7 @@ static int wm8996_remove(struct snd_soc_codec *codec)
2831 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3010 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
2832 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3011 regulator_unregister_notifier(wm8996->supplies[i].consumer,
2833 &wm8996->disable_nb[i]); 3012 &wm8996->disable_nb[i]);
3013 regulator_put(wm8996->cpvdd);
2834 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3014 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
2835 3015
2836 return 0; 3016 return 0;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a4691321f9b..f32ab1ee964 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1120,8 +1120,8 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1120 return 0; 1120 return 0;
1121} 1121}
1122 1122
1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1124 int clk_id, unsigned int freq, int dir) 1124 int source, unsigned int freq, int dir)
1125{ 1125{
1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1127 1127
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 4de12203e61..f2f3077928d 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -139,7 +139,6 @@ static const u16 wm9090_reg_defaults[] = {
139 139
140/* This struct is used to save the context */ 140/* This struct is used to save the context */
141struct wm9090_priv { 141struct wm9090_priv {
142 struct mutex mutex;
143 struct wm9090_platform_data pdata; 142 struct wm9090_platform_data pdata;
144 void *control_data; 143 void *control_data;
145}; 144};
@@ -663,7 +662,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
663 662
664 i2c_set_clientdata(i2c, wm9090); 663 i2c_set_clientdata(i2c, wm9090);
665 wm9090->control_data = i2c; 664 wm9090->control_data = i2c;
666 mutex_init(&wm9090->mutex);
667 665
668 ret = snd_soc_register_codec(&i2c->dev, 666 ret = snd_soc_register_codec(&i2c->dev,
669 &soc_codec_dev_wm9090, NULL, 0); 667 &soc_codec_dev_wm9090, NULL, 0);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e763c54c55d..ca8ce03510f 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mfd/wm8994/registers.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
116{ 117{
117 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 118 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
118 s8 offset; 119 s8 offset;
119 u16 reg, reg_l, reg_r, dcs_cfg; 120 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
121
122 switch (hubs->dcs_readback_mode) {
123 case 2:
124 dcs_reg = WM8994_DC_SERVO_4E;
125 break;
126 default:
127 dcs_reg = WM8993_DC_SERVO_3;
128 break;
129 }
120 130
121 /* If we're using a digital only path and have a previously 131 /* If we're using a digital only path and have a previously
122 * callibrated DC servo offset stored then use that. */ 132 * callibrated DC servo offset stored then use that. */
123 if (hubs->class_w && hubs->class_w_dcs) { 133 if (hubs->class_w && hubs->class_w_dcs) {
124 dev_dbg(codec->dev, "Using cached DC servo offset %x\n", 134 dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
125 hubs->class_w_dcs); 135 hubs->class_w_dcs);
126 snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); 136 snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
127 wait_for_dc_servo(codec, 137 wait_for_dc_servo(codec,
128 WM8993_DCS_TRIG_DAC_WR_0 | 138 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1); 139 WM8993_DCS_TRIG_DAC_WR_1);
@@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
154 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) 164 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
155 & WM8993_DCS_INTEG_CHAN_1_MASK; 165 & WM8993_DCS_INTEG_CHAN_1_MASK;
156 break; 166 break;
167 case 2:
157 case 1: 168 case 1:
158 reg = snd_soc_read(codec, WM8993_DC_SERVO_3); 169 reg = snd_soc_read(codec, dcs_reg);
159 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) 170 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
160 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; 171 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
161 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; 172 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
168 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 179 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
169 180
170 /* Apply correction to DC servo result */ 181 /* Apply correction to DC servo result */
171 if (hubs->dcs_codes) { 182 if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
172 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 183 dev_dbg(codec->dev,
173 hubs->dcs_codes); 184 "Applying %d/%d code DC servo correction\n",
185 hubs->dcs_codes_l, hubs->dcs_codes_r);
174 186
175 /* HPOUT1R */ 187 /* HPOUT1R */
176 offset = reg_r; 188 offset = reg_r;
177 offset += hubs->dcs_codes; 189 offset += hubs->dcs_codes_r;
178 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 190 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
179 191
180 /* HPOUT1L */ 192 /* HPOUT1L */
181 offset = reg_l; 193 offset = reg_l;
182 offset += hubs->dcs_codes; 194 offset += hubs->dcs_codes_l;
183 dcs_cfg |= (u8)offset; 195 dcs_cfg |= (u8)offset;
184 196
185 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); 197 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
186 198
187 /* Do it */ 199 /* Do it */
188 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 200 snd_soc_write(codec, dcs_reg, dcs_cfg);
189 wait_for_dc_servo(codec, 201 wait_for_dc_servo(codec,
190 WM8993_DCS_TRIG_DAC_WR_0 | 202 WM8993_DCS_TRIG_DAC_WR_0 |
191 WM8993_DCS_TRIG_DAC_WR_1); 203 WM8993_DCS_TRIG_DAC_WR_1);
@@ -217,7 +229,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
217 229
218 /* If we're applying an offset correction then updating the 230 /* If we're applying an offset correction then updating the
219 * callibration would be likely to introduce further offsets. */ 231 * callibration would be likely to introduce further offsets. */
220 if (hubs->dcs_codes || hubs->no_series_update) 232 if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
221 return ret; 233 return ret;
222 234
223 /* Only need to do this if the outputs are active */ 235 /* Only need to do this if the outputs are active */
@@ -699,6 +711,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
699 { "IN1L PGA", "IN1LP Switch", "IN1LP" }, 711 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
700 { "IN1L PGA", "IN1LN Switch", "IN1LN" }, 712 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
701 713
714 { "IN1L PGA", NULL, "VMID" },
715 { "IN1R PGA", NULL, "VMID" },
716 { "IN2L PGA", NULL, "VMID" },
717 { "IN2R PGA", NULL, "VMID" },
718
702 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 719 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
703 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 720 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
704 721
@@ -716,12 +733,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
716 { "MIXINL", NULL, "Direct Voice" }, 733 { "MIXINL", NULL, "Direct Voice" },
717 { "MIXINL", NULL, "IN1LP" }, 734 { "MIXINL", NULL, "IN1LP" },
718 { "MIXINL", NULL, "Left Output Mixer" }, 735 { "MIXINL", NULL, "Left Output Mixer" },
736 { "MIXINL", NULL, "VMID" },
719 737
720 { "MIXINR", "IN1R Switch", "IN1R PGA" }, 738 { "MIXINR", "IN1R Switch", "IN1R PGA" },
721 { "MIXINR", "IN2R Switch", "IN2R PGA" }, 739 { "MIXINR", "IN2R Switch", "IN2R PGA" },
722 { "MIXINR", NULL, "Direct Voice" }, 740 { "MIXINR", NULL, "Direct Voice" },
723 { "MIXINR", NULL, "IN1RP" }, 741 { "MIXINR", NULL, "IN1RP" },
724 { "MIXINR", NULL, "Right Output Mixer" }, 742 { "MIXINR", NULL, "Right Output Mixer" },
743 { "MIXINR", NULL, "VMID" },
725 744
726 { "ADCL", NULL, "MIXINL" }, 745 { "ADCL", NULL, "MIXINL" },
727 { "ADCR", NULL, "MIXINR" }, 746 { "ADCR", NULL, "MIXINR" },
@@ -752,6 +771,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
752 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" }, 771 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
753 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" }, 772 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
754 773
774 { "Earpiece Driver", NULL, "VMID" },
755 { "Earpiece Driver", NULL, "Earpiece Mixer" }, 775 { "Earpiece Driver", NULL, "Earpiece Mixer" },
756 { "HPOUT2N", NULL, "Earpiece Driver" }, 776 { "HPOUT2N", NULL, "Earpiece Driver" },
757 { "HPOUT2P", NULL, "Earpiece Driver" }, 777 { "HPOUT2P", NULL, "Earpiece Driver" },
@@ -774,9 +794,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
774 { "SPKR Boost", "SPKR Switch", "SPKR" }, 794 { "SPKR Boost", "SPKR Switch", "SPKR" },
775 { "SPKR Boost", "SPKL Switch", "SPKL" }, 795 { "SPKR Boost", "SPKL Switch", "SPKL" },
776 796
797 { "SPKL Driver", NULL, "VMID" },
777 { "SPKL Driver", NULL, "SPKL Boost" }, 798 { "SPKL Driver", NULL, "SPKL Boost" },
778 { "SPKL Driver", NULL, "CLK_SYS" }, 799 { "SPKL Driver", NULL, "CLK_SYS" },
779 800
801 { "SPKR Driver", NULL, "VMID" },
780 { "SPKR Driver", NULL, "SPKR Boost" }, 802 { "SPKR Driver", NULL, "SPKR Boost" },
781 { "SPKR Driver", NULL, "CLK_SYS" }, 803 { "SPKR Driver", NULL, "CLK_SYS" },
782 804
@@ -790,12 +812,18 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
790 812
791 { "Headphone PGA", NULL, "Left Headphone Mux" }, 813 { "Headphone PGA", NULL, "Left Headphone Mux" },
792 { "Headphone PGA", NULL, "Right Headphone Mux" }, 814 { "Headphone PGA", NULL, "Right Headphone Mux" },
815 { "Headphone PGA", NULL, "VMID" },
793 { "Headphone PGA", NULL, "CLK_SYS" }, 816 { "Headphone PGA", NULL, "CLK_SYS" },
794 { "Headphone PGA", NULL, "Headphone Supply" }, 817 { "Headphone PGA", NULL, "Headphone Supply" },
795 818
796 { "HPOUT1L", NULL, "Headphone PGA" }, 819 { "HPOUT1L", NULL, "Headphone PGA" },
797 { "HPOUT1R", NULL, "Headphone PGA" }, 820 { "HPOUT1R", NULL, "Headphone PGA" },
798 821
822 { "LINEOUT1N Driver", NULL, "VMID" },
823 { "LINEOUT1P Driver", NULL, "VMID" },
824 { "LINEOUT2N Driver", NULL, "VMID" },
825 { "LINEOUT2P Driver", NULL, "VMID" },
826
799 { "LINEOUT1N", NULL, "LINEOUT1N Driver" }, 827 { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
800 { "LINEOUT1P", NULL, "LINEOUT1P Driver" }, 828 { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
801 { "LINEOUT2N", NULL, "LINEOUT2N Driver" }, 829 { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 676b1252ab9..c674c7a502a 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,7 +23,8 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
23 23
24/* This *must* be the first element of the codec->private_data struct */ 24/* This *must* be the first element of the codec->private_data struct */
25struct wm_hubs_data { 25struct wm_hubs_data {
26 int dcs_codes; 26 int dcs_codes_l;
27 int dcs_codes_r;
27 int dcs_readback_mode; 28 int dcs_readback_mode;
28 int hp_startup_mode; 29 int hp_startup_mode;
29 int series_startup; 30 int series_startup;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 8566238db2a..7173df254a9 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -732,16 +732,19 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
732 davinci_hw_param(dev, substream->stream); 732 davinci_hw_param(dev, substream->stream);
733 733
734 switch (params_format(params)) { 734 switch (params_format(params)) {
735 case SNDRV_PCM_FORMAT_U8:
735 case SNDRV_PCM_FORMAT_S8: 736 case SNDRV_PCM_FORMAT_S8:
736 dma_params->data_type = 1; 737 dma_params->data_type = 1;
737 word_length = DAVINCI_AUDIO_WORD_8; 738 word_length = DAVINCI_AUDIO_WORD_8;
738 break; 739 break;
739 740
741 case SNDRV_PCM_FORMAT_U16_LE:
740 case SNDRV_PCM_FORMAT_S16_LE: 742 case SNDRV_PCM_FORMAT_S16_LE:
741 dma_params->data_type = 2; 743 dma_params->data_type = 2;
742 word_length = DAVINCI_AUDIO_WORD_16; 744 word_length = DAVINCI_AUDIO_WORD_16;
743 break; 745 break;
744 746
747 case SNDRV_PCM_FORMAT_U32_LE:
745 case SNDRV_PCM_FORMAT_S32_LE: 748 case SNDRV_PCM_FORMAT_S32_LE:
746 dma_params->data_type = 4; 749 dma_params->data_type = 4;
747 word_length = DAVINCI_AUDIO_WORD_32; 750 word_length = DAVINCI_AUDIO_WORD_32;
@@ -818,6 +821,13 @@ static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
818 821
819}; 822};
820 823
824#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
825 SNDRV_PCM_FMTBIT_U8 | \
826 SNDRV_PCM_FMTBIT_S16_LE | \
827 SNDRV_PCM_FMTBIT_U16_LE | \
828 SNDRV_PCM_FMTBIT_S32_LE | \
829 SNDRV_PCM_FMTBIT_U32_LE)
830
821static struct snd_soc_dai_driver davinci_mcasp_dai[] = { 831static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
822 { 832 {
823 .name = "davinci-mcasp.0", 833 .name = "davinci-mcasp.0",
@@ -825,17 +835,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
825 .channels_min = 2, 835 .channels_min = 2,
826 .channels_max = 2, 836 .channels_max = 2,
827 .rates = DAVINCI_MCASP_RATES, 837 .rates = DAVINCI_MCASP_RATES,
828 .formats = SNDRV_PCM_FMTBIT_S8 | 838 .formats = DAVINCI_MCASP_PCM_FMTS,
829 SNDRV_PCM_FMTBIT_S16_LE |
830 SNDRV_PCM_FMTBIT_S32_LE,
831 }, 839 },
832 .capture = { 840 .capture = {
833 .channels_min = 2, 841 .channels_min = 2,
834 .channels_max = 2, 842 .channels_max = 2,
835 .rates = DAVINCI_MCASP_RATES, 843 .rates = DAVINCI_MCASP_RATES,
836 .formats = SNDRV_PCM_FMTBIT_S8 | 844 .formats = DAVINCI_MCASP_PCM_FMTS,
837 SNDRV_PCM_FMTBIT_S16_LE |
838 SNDRV_PCM_FMTBIT_S32_LE,
839 }, 845 },
840 .ops = &davinci_mcasp_dai_ops, 846 .ops = &davinci_mcasp_dai_ops,
841 847
@@ -846,7 +852,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
846 .channels_min = 1, 852 .channels_min = 1,
847 .channels_max = 384, 853 .channels_max = 384,
848 .rates = DAVINCI_MCASP_RATES, 854 .rates = DAVINCI_MCASP_RATES,
849 .formats = SNDRV_PCM_FMTBIT_S16_LE, 855 .formats = DAVINCI_MCASP_PCM_FMTS,
850 }, 856 },
851 .ops = &davinci_mcasp_dai_ops, 857 .ops = &davinci_mcasp_dai_ops,
852 }, 858 },
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a49e667373b..d5fe08cc5db 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
180{ 180{
181 struct davinci_runtime_data *prtd = substream->runtime->private_data; 181 struct davinci_runtime_data *prtd = substream->runtime->private_data;
182 struct snd_pcm_runtime *runtime = substream->runtime; 182 struct snd_pcm_runtime *runtime = substream->runtime;
183 int link = prtd->asp_link[0];
184 unsigned int period_size; 183 unsigned int period_size;
185 unsigned int dma_offset; 184 unsigned int dma_offset;
186 dma_addr_t dma_pos; 185 dma_addr_t dma_pos;
@@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
198 fifo_level = prtd->params->fifo_level; 197 fifo_level = prtd->params->fifo_level;
199 198
200 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 199 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
201 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); 200 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
201 period_size);
202 202
203 data_type = prtd->params->data_type; 203 data_type = prtd->params->data_type;
204 count = period_size / data_type; 204 count = period_size / data_type;
@@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
222 } 222 }
223 223
224 acnt = prtd->params->acnt; 224 acnt = prtd->params->acnt;
225 edma_set_src(link, src, INCR, W8BIT); 225 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
226 edma_set_dest(link, dst, INCR, W8BIT); 226 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
227 227
228 edma_set_src_index(link, src_bidx, src_cidx); 228 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
229 edma_set_dest_index(link, dst_bidx, dst_cidx); 229 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
230 230
231 if (!fifo_level) 231 if (!fifo_level)
232 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); 232 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
233 ASYNC);
233 else 234 else
234 edma_set_transfer_params(link, acnt, fifo_level, count, 235 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
235 fifo_level, ABSYNC); 236 count, fifo_level,
237 ABSYNC);
236} 238}
237 239
238static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
@@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
305 unsigned int acnt = params->acnt; 307 unsigned int acnt = params->acnt;
306 /* divide by 2 for ping/pong */ 308 /* divide by 2 for ping/pong */
307 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; 309 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
308 int link = prtd->asp_link[1];
309 unsigned int fifo_level = prtd->params->fifo_level; 310 unsigned int fifo_level = prtd->params->fifo_level;
310 unsigned int count; 311 unsigned int count;
311 if ((data_type == 0) || (data_type > 4)) { 312 if ((data_type == 0) || (data_type > 4)) {
@@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
316 dma_addr_t asp_src_pong = iram_dma->addr + ping_size; 317 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
317 ram_src_cidx = ping_size; 318 ram_src_cidx = ping_size;
318 ram_dst_cidx = -ping_size; 319 ram_dst_cidx = -ping_size;
319 edma_set_src(link, asp_src_pong, INCR, W8BIT); 320 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
320 321
321 link = prtd->asp_link[0]; 322 edma_set_src_index(prtd->asp_link[0], data_type,
322 edma_set_src_index(link, data_type, data_type * fifo_level); 323 data_type * fifo_level);
323 link = prtd->asp_link[1]; 324 edma_set_src_index(prtd->asp_link[1], data_type,
324 edma_set_src_index(link, data_type, data_type * fifo_level); 325 data_type * fifo_level);
325 326
326 link = prtd->ram_link; 327 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
327 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
328 } else { 328 } else {
329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; 329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
330 ram_src_cidx = -ping_size; 330 ram_src_cidx = -ping_size;
331 ram_dst_cidx = ping_size; 331 ram_dst_cidx = ping_size;
332 edma_set_dest(link, asp_dst_pong, INCR, W8BIT); 332 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
333 333
334 link = prtd->asp_link[0]; 334 edma_set_dest_index(prtd->asp_link[0], data_type,
335 edma_set_dest_index(link, data_type, data_type * fifo_level); 335 data_type * fifo_level);
336 link = prtd->asp_link[1]; 336 edma_set_dest_index(prtd->asp_link[1], data_type,
337 edma_set_dest_index(link, data_type, data_type * fifo_level); 337 data_type * fifo_level);
338 338
339 link = prtd->ram_link; 339 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
340 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
341 } 340 }
342 341
343 if (!fifo_level) { 342 if (!fifo_level) {
@@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
354 count, fifo_level, ABSYNC); 353 count, fifo_level, ABSYNC);
355 } 354 }
356 355
357 link = prtd->ram_link; 356 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
358 edma_set_src_index(link, ping_size, ram_src_cidx); 357 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
359 edma_set_dest_index(link, ping_size, ram_dst_cidx); 358 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
360 edma_set_transfer_params(link, ping_size, 2,
361 runtime->periods, 2, ASYNC); 359 runtime->periods, 2, ASYNC);
362 360
363 /* init master params */ 361 /* init master params */
@@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
406{ 404{
407 dma_addr_t asp_src_ping; 405 dma_addr_t asp_src_ping;
408 dma_addr_t asp_dst_ping; 406 dma_addr_t asp_dst_ping;
409 int link; 407 int ret;
410 struct davinci_pcm_dma_params *params = prtd->params; 408 struct davinci_pcm_dma_params *params = prtd->params;
411 409
412 /* Request ram master channel */ 410 /* Request ram master channel */
413 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, 411 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
414 davinci_pcm_dma_irq, substream, 412 davinci_pcm_dma_irq, substream,
415 prtd->params->ram_chan_q); 413 prtd->params->ram_chan_q);
416 if (link < 0) 414 if (ret < 0)
417 goto exit1; 415 goto exit1;
418 416
419 /* Request ram link channel */ 417 /* Request ram link channel */
420 link = prtd->ram_link = edma_alloc_slot( 418 ret = prtd->ram_link = edma_alloc_slot(
421 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 419 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
422 if (link < 0) 420 if (ret < 0)
423 goto exit2; 421 goto exit2;
424 422
425 link = prtd->asp_link[1] = edma_alloc_slot( 423 ret = prtd->asp_link[1] = edma_alloc_slot(
426 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 424 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
427 if (link < 0) 425 if (ret < 0)
428 goto exit3; 426 goto exit3;
429 427
430 prtd->ram_link2 = -1; 428 prtd->ram_link2 = -1;
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
432 link = prtd->ram_link2 = edma_alloc_slot( 430 ret = prtd->ram_link2 = edma_alloc_slot(
433 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); 431 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
434 if (link < 0) 432 if (ret < 0)
435 goto exit4; 433 goto exit4;
436 } 434 }
437 /* circle ping-pong buffers */ 435 /* circle ping-pong buffers */
@@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
448 asp_dst_ping = iram_dma->addr; 446 asp_dst_ping = iram_dma->addr;
449 } 447 }
450 /* ping */ 448 /* ping */
451 link = prtd->asp_link[0]; 449 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
452 edma_set_src(link, asp_src_ping, INCR, W16BIT); 450 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
453 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 451 edma_set_src_index(prtd->asp_link[0], 0, 0);
454 edma_set_src_index(link, 0, 0); 452 edma_set_dest_index(prtd->asp_link[0], 0, 0);
455 edma_set_dest_index(link, 0, 0);
456 453
457 edma_read_slot(link, &prtd->asp_params); 454 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
458 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); 455 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
459 prtd->asp_params.opt |= TCCHEN | 456 prtd->asp_params.opt |= TCCHEN |
460 EDMA_TCC(prtd->ram_channel & 0x3f); 457 EDMA_TCC(prtd->ram_channel & 0x3f);
461 edma_write_slot(link, &prtd->asp_params); 458 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
462 459
463 /* pong */ 460 /* pong */
464 link = prtd->asp_link[1]; 461 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
465 edma_set_src(link, asp_src_ping, INCR, W16BIT); 462 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
466 edma_set_dest(link, asp_dst_ping, INCR, W16BIT); 463 edma_set_src_index(prtd->asp_link[1], 0, 0);
467 edma_set_src_index(link, 0, 0); 464 edma_set_dest_index(prtd->asp_link[1], 0, 0);
468 edma_set_dest_index(link, 0, 0);
469 465
470 edma_read_slot(link, &prtd->asp_params); 466 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
471 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); 467 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
472 /* interrupt after every pong completion */ 468 /* interrupt after every pong completion */
473 prtd->asp_params.opt |= TCINTEN | TCCHEN | 469 prtd->asp_params.opt |= TCINTEN | TCCHEN |
474 EDMA_TCC(prtd->ram_channel & 0x3f); 470 EDMA_TCC(prtd->ram_channel & 0x3f);
475 edma_write_slot(link, &prtd->asp_params); 471 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
476 472
477 /* ram */ 473 /* ram */
478 link = prtd->ram_link; 474 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
479 edma_set_src(link, iram_dma->addr, INCR, W32BIT); 475 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
480 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
481 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," 476 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
482 "for asp:%u %u %u\n", __func__, 477 "for asp:%u %u %u\n", __func__,
483 prtd->ram_channel, prtd->ram_link, prtd->ram_link2, 478 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
@@ -494,7 +489,7 @@ exit2:
494 edma_free_channel(prtd->ram_channel); 489 edma_free_channel(prtd->ram_channel);
495 prtd->ram_channel = -1; 490 prtd->ram_channel = -1;
496exit1: 491exit1:
497 return link; 492 return ret;
498} 493}
499 494
500static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
@@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
502 struct snd_dma_buffer *iram_dma; 497 struct snd_dma_buffer *iram_dma;
503 struct davinci_runtime_data *prtd = substream->runtime->private_data; 498 struct davinci_runtime_data *prtd = substream->runtime->private_data;
504 struct davinci_pcm_dma_params *params = prtd->params; 499 struct davinci_pcm_dma_params *params = prtd->params;
505 int link; 500 int ret;
506 501
507 if (!params) 502 if (!params)
508 return -ENODEV; 503 return -ENODEV;
509 504
510 /* Request asp master DMA channel */ 505 /* Request asp master DMA channel */
511 link = prtd->asp_channel = edma_alloc_channel(params->channel, 506 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
512 davinci_pcm_dma_irq, substream, 507 davinci_pcm_dma_irq, substream,
513 prtd->params->asp_chan_q); 508 prtd->params->asp_chan_q);
514 if (link < 0) 509 if (ret < 0)
515 goto exit1; 510 goto exit1;
516 511
517 /* Request asp link channels */ 512 /* Request asp link channels */
518 link = prtd->asp_link[0] = edma_alloc_slot( 513 ret = prtd->asp_link[0] = edma_alloc_slot(
519 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); 514 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
520 if (link < 0) 515 if (ret < 0)
521 goto exit2; 516 goto exit2;
522 517
523 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; 518 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
@@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
537 * the buffer and its length (ccnt) ... use it as a template 532 * the buffer and its length (ccnt) ... use it as a template
538 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 533 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
539 */ 534 */
540 edma_read_slot(link, &prtd->asp_params); 535 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
541 prtd->asp_params.opt |= TCINTEN | 536 prtd->asp_params.opt |= TCINTEN |
542 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); 537 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
543 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; 538 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
544 edma_write_slot(link, &prtd->asp_params); 539 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
545 return 0; 540 return 0;
546exit2: 541exit2:
547 edma_free_channel(prtd->asp_channel); 542 edma_free_channel(prtd->asp_channel);
548 prtd->asp_channel = -1; 543 prtd->asp_channel = -1;
549exit1: 544exit1:
550 return link; 545 return ret;
551} 546}
552 547
553static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index d3aa15119d2..0134d4e9131 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -28,12 +28,6 @@
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include "ep93xx-pcm.h" 29#include "ep93xx-pcm.h"
30 30
31#define edb93xx_has_audio() (machine_is_edb9301() || \
32 machine_is_edb9302() || \
33 machine_is_edb9302a() || \
34 machine_is_edb9307a() || \
35 machine_is_edb9315a())
36
37static int edb93xx_hw_params(struct snd_pcm_substream *substream, 31static int edb93xx_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
39{ 33{
@@ -94,49 +88,61 @@ static struct snd_soc_card snd_soc_edb93xx = {
94 .num_links = 1, 88 .num_links = 1,
95}; 89};
96 90
97static struct platform_device *edb93xx_snd_device; 91static int __devinit edb93xx_probe(struct platform_device *pdev)
98
99static int __init edb93xx_init(void)
100{ 92{
93 struct snd_soc_card *card = &snd_soc_edb93xx;
101 int ret; 94 int ret;
102 95
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 96 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 97 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL); 98 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret) 99 if (ret)
110 return ret; 100 return ret;
111 101
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1); 102 card->dev = &pdev->dev;
113 if (!edb93xx_snd_device) { 103
114 ret = -ENOMEM; 104 ret = snd_soc_register_card(card);
115 goto free_i2s; 105 if (ret) {
106 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
107 ret);
108 ep93xx_i2s_release();
116 } 109 }
117 110
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx); 111 return ret;
119 ret = platform_device_add(edb93xx_snd_device); 112}
120 if (ret)
121 goto device_put;
122 113
123 return 0; 114static int __devexit edb93xx_remove(struct platform_device *pdev)
115{
116 struct snd_soc_card *card = platform_get_drvdata(pdev);
124 117
125device_put: 118 snd_soc_unregister_card(card);
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release(); 119 ep93xx_i2s_release();
129 return ret; 120
121 return 0;
122}
123
124static struct platform_driver edb93xx_driver = {
125 .driver = {
126 .name = "edb93xx-audio",
127 .owner = THIS_MODULE,
128 },
129 .probe = edb93xx_probe,
130 .remove = __devexit_p(edb93xx_remove),
131};
132
133static int __init edb93xx_init(void)
134{
135 return platform_driver_register(&edb93xx_driver);
130} 136}
131module_init(edb93xx_init); 137module_init(edb93xx_init);
132 138
133static void __exit edb93xx_exit(void) 139static void __exit edb93xx_exit(void)
134{ 140{
135 platform_device_unregister(edb93xx_snd_device); 141 platform_driver_unregister(&edb93xx_driver);
136 ep93xx_i2s_release();
137} 142}
138module_exit(edb93xx_exit); 143module_exit(edb93xx_exit);
139 144
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 145MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx"); 146MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL"); 147MODULE_LICENSE("GPL");
148MODULE_ALIAS("platform:edb93xx-audio");
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 8dfd3ad84b1..d00230a591b 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -355,3 +355,4 @@ module_exit(ep93xx_soc_platform_exit);
355MODULE_AUTHOR("Ryan Mallon"); 355MODULE_AUTHOR("Ryan Mallon");
356MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); 356MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
357MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
358MODULE_ALIAS("platform:ep93xx-pcm-audio");
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c
index 286817946c5..968cb316d51 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/ep93xx/simone.c
@@ -39,53 +39,61 @@ static struct snd_soc_card snd_soc_simone = {
39}; 39};
40 40
41static struct platform_device *simone_snd_ac97_device; 41static struct platform_device *simone_snd_ac97_device;
42static struct platform_device *simone_snd_device;
43 42
44static int __init simone_init(void) 43static int __devinit simone_probe(struct platform_device *pdev)
45{ 44{
45 struct snd_soc_card *card = &snd_soc_simone;
46 int ret; 46 int ret;
47 47
48 if (!machine_is_sim_one()) 48 simone_snd_ac97_device = platform_device_register_simple("ac97-codec",
49 return -ENODEV; 49 -1, NULL, 0);
50 50 if (IS_ERR(simone_snd_ac97_device))
51 simone_snd_ac97_device = platform_device_alloc("ac97-codec", -1); 51 return PTR_ERR(simone_snd_ac97_device);
52 if (!simone_snd_ac97_device)
53 return -ENOMEM;
54 52
55 ret = platform_device_add(simone_snd_ac97_device); 53 card->dev = &pdev->dev;
56 if (ret)
57 goto fail1;
58 54
59 simone_snd_device = platform_device_alloc("soc-audio", -1); 55 ret = snd_soc_register_card(card);
60 if (!simone_snd_device) { 56 if (ret) {
61 ret = -ENOMEM; 57 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
62 goto fail2; 58 ret);
59 platform_device_unregister(simone_snd_ac97_device);
63 } 60 }
64 61
65 platform_set_drvdata(simone_snd_device, &snd_soc_simone); 62 return ret;
66 ret = platform_device_add(simone_snd_device); 63}
67 if (ret) 64
68 goto fail3; 65static int __devexit simone_remove(struct platform_device *pdev)
66{
67 struct snd_soc_card *card = platform_get_drvdata(pdev);
68
69 snd_soc_unregister_card(card);
70 platform_device_unregister(simone_snd_ac97_device);
69 71
70 return 0; 72 return 0;
73}
71 74
72fail3: 75static struct platform_driver simone_driver = {
73 platform_device_put(simone_snd_device); 76 .driver = {
74fail2: 77 .name = "simone-audio",
75 platform_device_del(simone_snd_ac97_device); 78 .owner = THIS_MODULE,
76fail1: 79 },
77 platform_device_put(simone_snd_ac97_device); 80 .probe = simone_probe,
78 return ret; 81 .remove = __devexit_p(simone_remove),
82};
83
84static int __init simone_init(void)
85{
86 return platform_driver_register(&simone_driver);
79} 87}
80module_init(simone_init); 88module_init(simone_init);
81 89
82static void __exit simone_exit(void) 90static void __exit simone_exit(void)
83{ 91{
84 platform_device_unregister(simone_snd_device); 92 platform_driver_unregister(&simone_driver);
85 platform_device_unregister(simone_snd_ac97_device);
86} 93}
87module_exit(simone_exit); 94module_exit(simone_exit);
88 95
89MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); 96MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
90MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); 97MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
91MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
99MODULE_ALIAS("platform:simone-audio");
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index c8aa8a5003c..f74ac54c285 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -104,37 +104,56 @@ static struct snd_soc_card snd_soc_snappercl15 = {
104 .num_links = 1, 104 .num_links = 1,
105}; 105};
106 106
107static struct platform_device *snappercl15_snd_device; 107static int __devinit snappercl15_probe(struct platform_device *pdev)
108
109static int __init snappercl15_init(void)
110{ 108{
109 struct snd_soc_card *card = &snd_soc_snappercl15;
111 int ret; 110 int ret;
112 111
113 if (!machine_is_snapper_cl15())
114 return -ENODEV;
115
116 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, 112 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
117 EP93XX_SYSCON_I2SCLKDIV_ORIDE | 113 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
118 EP93XX_SYSCON_I2SCLKDIV_SPOL); 114 EP93XX_SYSCON_I2SCLKDIV_SPOL);
119 if (ret) 115 if (ret)
120 return ret; 116 return ret;
121 117
122 snappercl15_snd_device = platform_device_alloc("soc-audio", -1); 118 card->dev = &pdev->dev;
123 if (!snappercl15_snd_device) 119
124 return -ENOMEM; 120 ret = snd_soc_register_card(card);
125 121 if (ret) {
126 platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); 122 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
127 ret = platform_device_add(snappercl15_snd_device); 123 ret);
128 if (ret) 124 ep93xx_i2s_release();
129 platform_device_put(snappercl15_snd_device); 125 }
130 126
131 return ret; 127 return ret;
132} 128}
133 129
134static void __exit snappercl15_exit(void) 130static int __devexit snappercl15_remove(struct platform_device *pdev)
135{ 131{
136 platform_device_unregister(snappercl15_snd_device); 132 struct snd_soc_card *card = platform_get_drvdata(pdev);
133
134 snd_soc_unregister_card(card);
137 ep93xx_i2s_release(); 135 ep93xx_i2s_release();
136
137 return 0;
138}
139
140static struct platform_driver snappercl15_driver = {
141 .driver = {
142 .name = "snappercl15-audio",
143 .owner = THIS_MODULE,
144 },
145 .probe = snappercl15_probe,
146 .remove = __devexit_p(snappercl15_remove),
147};
148
149static int __init snappercl15_init(void)
150{
151 return platform_driver_register(&snappercl15_driver);
152}
153
154static void __exit snappercl15_exit(void)
155{
156 platform_driver_unregister(&snappercl15_driver);
138} 157}
139 158
140module_init(snappercl15_init); 159module_init(snappercl15_init);
@@ -143,4 +162,4 @@ module_exit(snappercl15_exit);
143MODULE_AUTHOR("Ryan Mallon"); 162MODULE_AUTHOR("Ryan Mallon");
144MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); 163MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
145MODULE_LICENSE("GPL"); 164MODULE_LICENSE("GPL");
146 165MODULE_ALIAS("platform:snappercl15-audio");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index cb50598338e..ef15402a3bc 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -297,7 +297,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) 297static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
298{ 298{
299 struct snd_card *card = rtd->card->snd_card; 299 struct snd_card *card = rtd->card->snd_card;
300 struct snd_soc_dai *dai = rtd->cpu_dai;
301 struct snd_pcm *pcm = rtd->pcm; 300 struct snd_pcm *pcm = rtd->pcm;
302 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); 301 static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
303 int ret; 302 int ret;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d48afea5d93..0268cf98973 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -78,7 +78,6 @@
78 * @second_stream: pointer to second stream 78 * @second_stream: pointer to second stream
79 * @playback: the number of playback streams opened 79 * @playback: the number of playback streams opened
80 * @capture: the number of capture streams opened 80 * @capture: the number of capture streams opened
81 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
82 * @cpu_dai: the CPU DAI for this device 81 * @cpu_dai: the CPU DAI for this device
83 * @dev_attr: the sysfs device attribute structure 82 * @dev_attr: the sysfs device attribute structure
84 * @stats: SSI statistics 83 * @stats: SSI statistics
@@ -90,9 +89,6 @@ struct fsl_ssi_private {
90 unsigned int irq; 89 unsigned int irq;
91 struct snd_pcm_substream *first_stream; 90 struct snd_pcm_substream *first_stream;
92 struct snd_pcm_substream *second_stream; 91 struct snd_pcm_substream *second_stream;
93 unsigned int playback;
94 unsigned int capture;
95 int asynchronous;
96 unsigned int fifo_depth; 92 unsigned int fifo_depth;
97 struct snd_soc_dai_driver cpu_dai_drv; 93 struct snd_soc_dai_driver cpu_dai_drv;
98 struct device_attribute dev_attr; 94 struct device_attribute dev_attr;
@@ -281,24 +277,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
281 struct snd_soc_dai *dai) 277 struct snd_soc_dai *dai)
282{ 278{
283 struct snd_soc_pcm_runtime *rtd = substream->private_data; 279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 280 struct fsl_ssi_private *ssi_private =
281 snd_soc_dai_get_drvdata(rtd->cpu_dai);
282 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
285 283
286 /* 284 /*
287 * If this is the first stream opened, then request the IRQ 285 * If this is the first stream opened, then request the IRQ
288 * and initialize the SSI registers. 286 * and initialize the SSI registers.
289 */ 287 */
290 if (!ssi_private->playback && !ssi_private->capture) { 288 if (!ssi_private->first_stream) {
291 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 289 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
292 int ret; 290
293 291 ssi_private->first_stream = substream;
294 /* The 'name' should not have any slashes in it. */
295 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
296 ssi_private->name, ssi_private);
297 if (ret < 0) {
298 dev_err(substream->pcm->card->dev,
299 "could not claim irq %u\n", ssi_private->irq);
300 return ret;
301 }
302 292
303 /* 293 /*
304 * Section 16.5 of the MPC8610 reference manual says that the 294 * Section 16.5 of the MPC8610 reference manual says that the
@@ -316,7 +306,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
316 clrsetbits_be32(&ssi->scr, 306 clrsetbits_be32(&ssi->scr,
317 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
318 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
319 | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN)); 309 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
320 310
321 out_be32(&ssi->stcr, 311 out_be32(&ssi->stcr,
322 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
@@ -333,7 +323,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
333 * master. 323 * master.
334 */ 324 */
335 325
336 /* 4. Enable the interrupts and DMA requests */ 326 /* Enable the interrupts and DMA requests */
337 out_be32(&ssi->sier, SIER_FLAGS); 327 out_be32(&ssi->sier, SIER_FLAGS);
338 328
339 /* 329 /*
@@ -362,58 +352,47 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
362 * this is bad is because at this point, the PCM driver has not 352 * this is bad is because at this point, the PCM driver has not
363 * finished initializing the DMA controller. 353 * finished initializing the DMA controller.
364 */ 354 */
365 } 355 } else {
356 if (synchronous) {
357 struct snd_pcm_runtime *first_runtime =
358 ssi_private->first_stream->runtime;
359 /*
360 * This is the second stream open, and we're in
361 * synchronous mode, so we need to impose sample
362 * sample size constraints. This is because STCCR is
363 * used for playback and capture in synchronous mode,
364 * so there's no way to specify different word
365 * lengths.
366 *
367 * Note that this can cause a race condition if the
368 * second stream is opened before the first stream is
369 * fully initialized. We provide some protection by
370 * checking to make sure the first stream is
371 * initialized, but it's not perfect. ALSA sometimes
372 * re-initializes the driver with a different sample
373 * rate or size. If the second stream is opened
374 * before the first stream has received its final
375 * parameters, then the second stream may be
376 * constrained to the wrong sample rate or size.
377 */
378 if (!first_runtime->sample_bits) {
379 dev_err(substream->pcm->card->dev,
380 "set sample size in %s stream first\n",
381 substream->stream ==
382 SNDRV_PCM_STREAM_PLAYBACK
383 ? "capture" : "playback");
384 return -EAGAIN;
385 }
366 386
367 if (!ssi_private->first_stream)
368 ssi_private->first_stream = substream;
369 else {
370 /* This is the second stream open, so we need to impose sample
371 * rate and maybe sample size constraints. Note that this can
372 * cause a race condition if the second stream is opened before
373 * the first stream is fully initialized.
374 *
375 * We provide some protection by checking to make sure the first
376 * stream is initialized, but it's not perfect. ALSA sometimes
377 * re-initializes the driver with a different sample rate or
378 * size. If the second stream is opened before the first stream
379 * has received its final parameters, then the second stream may
380 * be constrained to the wrong sample rate or size.
381 *
382 * FIXME: This code does not handle opening and closing streams
383 * repeatedly. If you open two streams and then close the first
384 * one, you may not be able to open another stream until you
385 * close the second one as well.
386 */
387 struct snd_pcm_runtime *first_runtime =
388 ssi_private->first_stream->runtime;
389
390 if (!first_runtime->sample_bits) {
391 dev_err(substream->pcm->card->dev,
392 "set sample size in %s stream first\n",
393 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
394 ? "capture" : "playback");
395 return -EAGAIN;
396 }
397
398 /* If we're in synchronous mode, then we need to constrain
399 * the sample size as well. We don't support independent sample
400 * rates in asynchronous mode.
401 */
402 if (!ssi_private->asynchronous)
403 snd_pcm_hw_constraint_minmax(substream->runtime, 387 snd_pcm_hw_constraint_minmax(substream->runtime,
404 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 388 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
405 first_runtime->sample_bits, 389 first_runtime->sample_bits,
406 first_runtime->sample_bits); 390 first_runtime->sample_bits);
391 }
407 392
408 ssi_private->second_stream = substream; 393 ssi_private->second_stream = substream;
409 } 394 }
410 395
411 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
412 ssi_private->playback++;
413
414 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
415 ssi_private->capture++;
416
417 return 0; 396 return 0;
418} 397}
419 398
@@ -434,24 +413,35 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) 413 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
435{ 414{
436 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 415 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
416 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
417 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
437 421
438 if (substream == ssi_private->first_stream) { 422 /*
439 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 423 * If we're in synchronous mode, and the SSI is already enabled,
440 unsigned int sample_size = 424 * then STCCR is already set properly.
441 snd_pcm_format_width(params_format(hw_params)); 425 */
442 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 426 if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
427 return 0;
443 428
444 /* The SSI should always be disabled at this points (SSIEN=0) */ 429 /*
430 * FIXME: The documentation says that SxCCR[WL] should not be
431 * modified while the SSI is enabled. The only time this can
432 * happen is if we're trying to do simultaneous playback and
433 * capture in asynchronous mode. Unfortunately, I have been enable
434 * to get that to work at all on the P1022DS. Therefore, we don't
435 * bother to disable/enable the SSI when setting SxCCR[WL], because
436 * the SSI will stop anyway. Maybe one day, this will get fixed.
437 */
445 438
446 /* In synchronous mode, the SSI uses STCCR for capture */ 439 /* In synchronous mode, the SSI uses STCCR for capture */
447 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
448 !ssi_private->asynchronous) 441 ssi_private->cpu_dai_drv.symmetric_rates)
449 clrsetbits_be32(&ssi->stccr, 442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
450 CCSR_SSI_SxCCR_WL_MASK, wl); 443 else
451 else 444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
452 clrsetbits_be32(&ssi->srccr,
453 CCSR_SSI_SxCCR_WL_MASK, wl);
454 }
455 445
456 return 0; 446 return 0;
457} 447}
@@ -474,7 +464,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
474 464
475 switch (cmd) { 465 switch (cmd) {
476 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
477 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
478 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
480 setbits32(&ssi->scr, 469 setbits32(&ssi->scr,
@@ -510,27 +499,18 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
511 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 500 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
512 501
513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
514 ssi_private->playback--;
515
516 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
517 ssi_private->capture--;
518
519 if (ssi_private->first_stream == substream) 502 if (ssi_private->first_stream == substream)
520 ssi_private->first_stream = ssi_private->second_stream; 503 ssi_private->first_stream = ssi_private->second_stream;
521 504
522 ssi_private->second_stream = NULL; 505 ssi_private->second_stream = NULL;
523 506
524 /* 507 /*
525 * If this is the last active substream, disable the SSI and release 508 * If this is the last active substream, disable the SSI.
526 * the IRQ.
527 */ 509 */
528 if (!ssi_private->playback && !ssi_private->capture) { 510 if (!ssi_private->first_stream) {
529 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
530 512
531 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
532
533 free_irq(ssi_private->irq, ssi_private);
534 } 514 }
535} 515}
536 516
@@ -675,22 +655,33 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
675 ret = of_address_to_resource(np, 0, &res); 655 ret = of_address_to_resource(np, 0, &res);
676 if (ret) { 656 if (ret) {
677 dev_err(&pdev->dev, "could not determine device resources\n"); 657 dev_err(&pdev->dev, "could not determine device resources\n");
678 kfree(ssi_private); 658 goto error_kmalloc;
679 return ret;
680 } 659 }
681 ssi_private->ssi = of_iomap(np, 0); 660 ssi_private->ssi = of_iomap(np, 0);
682 if (!ssi_private->ssi) { 661 if (!ssi_private->ssi) {
683 dev_err(&pdev->dev, "could not map device resources\n"); 662 dev_err(&pdev->dev, "could not map device resources\n");
684 kfree(ssi_private); 663 ret = -ENOMEM;
685 return -ENOMEM; 664 goto error_kmalloc;
686 } 665 }
687 ssi_private->ssi_phys = res.start; 666 ssi_private->ssi_phys = res.start;
667
688 ssi_private->irq = irq_of_parse_and_map(np, 0); 668 ssi_private->irq = irq_of_parse_and_map(np, 0);
669 if (ssi_private->irq == NO_IRQ) {
670 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
671 ret = -ENXIO;
672 goto error_iomap;
673 }
674
675 /* The 'name' should not have any slashes in it. */
676 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
677 ssi_private);
678 if (ret < 0) {
679 dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
680 goto error_irqmap;
681 }
689 682
690 /* Are the RX and the TX clocks locked? */ 683 /* Are the RX and the TX clocks locked? */
691 if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) 684 if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
692 ssi_private->asynchronous = 1;
693 else
694 ssi_private->cpu_dai_drv.symmetric_rates = 1; 685 ssi_private->cpu_dai_drv.symmetric_rates = 1;
695 686
696 /* Determine the FIFO depth. */ 687 /* Determine the FIFO depth. */
@@ -711,7 +702,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
711 if (ret) { 702 if (ret) {
712 dev_err(&pdev->dev, "could not create sysfs %s file\n", 703 dev_err(&pdev->dev, "could not create sysfs %s file\n",
713 ssi_private->dev_attr.attr.name); 704 ssi_private->dev_attr.attr.name);
714 goto error; 705 goto error_irq;
715 } 706 }
716 707
717 /* Register with ASoC */ 708 /* Register with ASoC */
@@ -720,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
720 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); 711 ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
721 if (ret) { 712 if (ret) {
722 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 713 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
723 goto error; 714 goto error_dev;
724 } 715 }
725 716
726 /* Trigger the machine driver's probe function. The platform driver 717 /* Trigger the machine driver's probe function. The platform driver
@@ -741,18 +732,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
741 if (IS_ERR(ssi_private->pdev)) { 732 if (IS_ERR(ssi_private->pdev)) {
742 ret = PTR_ERR(ssi_private->pdev); 733 ret = PTR_ERR(ssi_private->pdev);
743 dev_err(&pdev->dev, "failed to register platform: %d\n", ret); 734 dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
744 goto error; 735 goto error_dai;
745 } 736 }
746 737
747 return 0; 738 return 0;
748 739
749error: 740error_dai:
750 snd_soc_unregister_dai(&pdev->dev); 741 snd_soc_unregister_dai(&pdev->dev);
742
743error_dev:
751 dev_set_drvdata(&pdev->dev, NULL); 744 dev_set_drvdata(&pdev->dev, NULL);
752 if (dev_attr) 745 device_remove_file(&pdev->dev, dev_attr);
753 device_remove_file(&pdev->dev, dev_attr); 746
747error_irq:
748 free_irq(ssi_private->irq, ssi_private);
749
750error_irqmap:
754 irq_dispose_mapping(ssi_private->irq); 751 irq_dispose_mapping(ssi_private->irq);
752
753error_iomap:
755 iounmap(ssi_private->ssi); 754 iounmap(ssi_private->ssi);
755
756error_kmalloc:
756 kfree(ssi_private); 757 kfree(ssi_private);
757 758
758 return ret; 759 return ret;
@@ -766,6 +767,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
766 snd_soc_unregister_dai(&pdev->dev); 767 snd_soc_unregister_dai(&pdev->dev);
767 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 768 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
768 769
770 free_irq(ssi_private->irq, ssi_private);
771 irq_dispose_mapping(ssi_private->irq);
772
769 kfree(ssi_private); 773 kfree(ssi_private);
770 dev_set_drvdata(&pdev->dev, NULL); 774 dev_set_drvdata(&pdev->dev, NULL);
771 775
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 358f0baaf71..31af405bda8 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -505,7 +505,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
505 return 0; 505 return 0;
506 506
507error_sound: 507error_sound:
508 platform_device_unregister(sound_device); 508 platform_device_put(sound_device);
509error: 509error:
510 kfree(machine_data); 510 kfree(machine_data);
511error_alloc: 511error_alloc:
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index fcb862eb0c7..2c064a9824a 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -267,7 +267,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
267 if (bus < 0) 267 if (bus < 0)
268 return bus; 268 return bus;
269 269
270 snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr); 270 snprintf(buf, len, "%s.%u-%04x", temp, bus, addr);
271 271
272 return 0; 272 return 0;
273} 273}
@@ -506,7 +506,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
506 506
507error: 507error:
508 if (sound_device) 508 if (sound_device)
509 platform_device_unregister(sound_device); 509 platform_device_put(sound_device);
510 510
511 kfree(mdata); 511 kfree(mdata);
512error_put: 512error_put:
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index 7945625e0e0..c8527ead373 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -242,23 +242,22 @@ static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
242{ 242{
243 struct snd_soc_dai *dai = rtd->cpu_dai; 243 struct snd_soc_dai *dai = rtd->cpu_dai;
244 struct snd_pcm *pcm = rtd->pcm; 244 struct snd_pcm *pcm = rtd->pcm;
245 struct snd_pcm_substream *substream;
245 int ret; 246 int ret;
246 247
247 ret = imx_pcm_new(rtd); 248 ret = imx_pcm_new(rtd);
248 if (ret) 249 if (ret)
249 return ret; 250 return ret;
250 251
251 if (dai->driver->playback.channels_min) { 252 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
252 struct snd_pcm_substream *substream = 253 if (substream) {
253 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
254 struct snd_dma_buffer *buf = &substream->dma_buffer; 254 struct snd_dma_buffer *buf = &substream->dma_buffer;
255 255
256 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; 256 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
257 } 257 }
258 258
259 if (dai->driver->capture.channels_min) { 259 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
260 struct snd_pcm_substream *substream = 260 if (substream) {
261 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
262 struct snd_dma_buffer *buf = &substream->dma_buffer; 261 struct snd_dma_buffer *buf = &substream->dma_buffer;
263 262
264 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area; 263 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 10a8e278375..4297cb6af42 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -357,8 +357,8 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
357 struct snd_pcm_runtime *runtime = substream->runtime; 357 struct snd_pcm_runtime *runtime = substream->runtime;
358 int ret; 358 int ret;
359 359
360 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area, 360 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
361 runtime->dma_addr, runtime->dma_bytes); 361 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
362 362
363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 363 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
364 runtime->dma_area, 364 runtime->dma_area,
@@ -399,14 +399,14 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
399 card->dev->dma_mask = &imx_pcm_dmamask; 399 card->dev->dma_mask = &imx_pcm_dmamask;
400 if (!card->dev->coherent_dma_mask) 400 if (!card->dev->coherent_dma_mask)
401 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 401 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
402 if (dai->driver->playback.channels_min) { 402 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
403 ret = imx_pcm_preallocate_dma_buffer(pcm, 403 ret = imx_pcm_preallocate_dma_buffer(pcm,
404 SNDRV_PCM_STREAM_PLAYBACK); 404 SNDRV_PCM_STREAM_PLAYBACK);
405 if (ret) 405 if (ret)
406 goto out; 406 goto out;
407 } 407 }
408 408
409 if (dai->driver->capture.channels_min) { 409 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
410 ret = imx_pcm_preallocate_dma_buffer(pcm, 410 ret = imx_pcm_preallocate_dma_buffer(pcm,
411 SNDRV_PCM_STREAM_CAPTURE); 411 SNDRV_PCM_STREAM_CAPTURE);
412 if (ret) 412 if (ret)
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 3e7826058ef..9925d20ab0a 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -226,13 +226,18 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
226 226
227static int sst_platform_open(struct snd_pcm_substream *substream) 227static int sst_platform_open(struct snd_pcm_substream *substream)
228{ 228{
229 struct snd_pcm_runtime *runtime; 229 struct snd_pcm_runtime *runtime = substream->runtime;
230 struct sst_runtime_stream *stream; 230 struct sst_runtime_stream *stream;
231 int ret_val = 0; 231 int ret_val = 0;
232 232
233 pr_debug("sst_platform_open called\n"); 233 pr_debug("sst_platform_open called\n");
234 runtime = substream->runtime; 234
235 runtime->hw = sst_platform_pcm_hw; 235 snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
236 ret_val = snd_pcm_hw_constraint_integer(runtime,
237 SNDRV_PCM_HW_PARAM_PERIODS);
238 if (ret_val < 0)
239 return ret_val;
240
236 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 241 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
237 if (!stream) 242 if (!stream)
238 return -ENOMEM; 243 return -ENOMEM;
@@ -259,8 +264,8 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
259 return ret_val; 264 return ret_val;
260 } 265 }
261 runtime->private_data = stream; 266 runtime->private_data = stream;
262 return snd_pcm_hw_constraint_integer(runtime, 267
263 SNDRV_PCM_HW_PARAM_PERIODS); 268 return 0;
264} 269}
265 270
266static int sst_platform_close(struct snd_pcm_substream *substream) 271static int sst_platform_close(struct snd_pcm_substream *substream)
@@ -469,7 +474,7 @@ static struct platform_driver sst_platform_driver = {
469static int __init sst_soc_platform_init(void) 474static int __init sst_soc_platform_init(void)
470{ 475{
471 pr_debug("sst_soc_platform_init called\n"); 476 pr_debug("sst_soc_platform_init called\n");
472 return platform_driver_register(&sst_platform_driver); 477 return platform_driver_register(&sst_platform_driver);
473} 478}
474module_init(sst_soc_platform_init); 479module_init(sst_soc_platform_init);
475 480
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
new file mode 100644
index 00000000000..e4ba8d5f25f
--- /dev/null
+++ b/sound/soc/mxs/Kconfig
@@ -0,0 +1,20 @@
1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS
4 select SND_PCM
5 help
6 Say Y or M if you want to add support for codecs attached to
7 the MXS SAIF interface.
8
9
10if SND_MXS_SOC
11
12config SND_SOC_MXS_SGTL5000
13 tristate "SoC Audio support for i.MX boards with sgtl5000"
14 depends on I2C
15 select SND_SOC_SGTL5000
16 help
17 Say Y if you want to add support for SoC audio on an MXS board with
18 a sgtl5000 codec.
19
20endif # SND_MXS_SOC
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
new file mode 100644
index 00000000000..565b5b51e8b
--- /dev/null
+++ b/sound/soc/mxs/Makefile
@@ -0,0 +1,10 @@
1# MXS Platform Support
2snd-soc-mxs-objs := mxs-saif.o
3snd-soc-mxs-pcm-objs := mxs-pcm.o
4
5obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o
6
7# i.MX Machine Support
8snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
9
10obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
new file mode 100644
index 00000000000..dea5aa4aa64
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -0,0 +1,359 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Based on sound/soc/imx/imx-pcm-dma-mx2.c
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/dma-mapping.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <linux/dmaengine.h>
31
32#include <sound/core.h>
33#include <sound/initval.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37
38#include <mach/dma.h>
39#include "mxs-pcm.h"
40
41static struct snd_pcm_hardware snd_mxs_hardware = {
42 .info = SNDRV_PCM_INFO_MMAP |
43 SNDRV_PCM_INFO_MMAP_VALID |
44 SNDRV_PCM_INFO_PAUSE |
45 SNDRV_PCM_INFO_RESUME |
46 SNDRV_PCM_INFO_INTERLEAVED,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE |
48 SNDRV_PCM_FMTBIT_S20_3LE |
49 SNDRV_PCM_FMTBIT_S24_LE,
50 .channels_min = 2,
51 .channels_max = 2,
52 .period_bytes_min = 32,
53 .period_bytes_max = 8192,
54 .periods_min = 1,
55 .periods_max = 52,
56 .buffer_bytes_max = 64 * 1024,
57 .fifo_size = 32,
58
59};
60
61static void audio_dma_irq(void *data)
62{
63 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
64 struct snd_pcm_runtime *runtime = substream->runtime;
65 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
66
67 iprtd->offset += iprtd->period_bytes;
68 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
69 snd_pcm_period_elapsed(substream);
70}
71
72static bool filter(struct dma_chan *chan, void *param)
73{
74 struct mxs_pcm_runtime_data *iprtd = param;
75 struct mxs_pcm_dma_params *dma_params = iprtd->dma_params;
76
77 if (!mxs_dma_is_apbx(chan))
78 return false;
79
80 if (chan->chan_id != dma_params->chan_num)
81 return false;
82
83 chan->private = &iprtd->dma_data;
84
85 return true;
86}
87
88static int mxs_dma_alloc(struct snd_pcm_substream *substream,
89 struct snd_pcm_hw_params *params)
90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data;
92 struct snd_pcm_runtime *runtime = substream->runtime;
93 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
94 dma_cap_mask_t mask;
95
96 iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
97
98 dma_cap_zero(mask);
99 dma_cap_set(DMA_SLAVE, mask);
100 iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
101 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
102 if (!iprtd->dma_chan)
103 return -EINVAL;
104
105 return 0;
106}
107
108static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params)
110{
111 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
113 unsigned long dma_addr;
114 struct dma_chan *chan;
115 int ret;
116
117 ret = mxs_dma_alloc(substream, params);
118 if (ret)
119 return ret;
120 chan = iprtd->dma_chan;
121
122 iprtd->size = params_buffer_bytes(params);
123 iprtd->periods = params_periods(params);
124 iprtd->period_bytes = params_period_bytes(params);
125 iprtd->offset = 0;
126 iprtd->period_time = HZ / (params_rate(params) /
127 params_period_size(params));
128
129 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
130
131 dma_addr = runtime->dma_addr;
132
133 iprtd->buf = substream->dma_buffer.area;
134
135 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
136 iprtd->period_bytes * iprtd->periods,
137 iprtd->period_bytes,
138 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
139 DMA_TO_DEVICE : DMA_FROM_DEVICE);
140 if (!iprtd->desc) {
141 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
142 return -EINVAL;
143 }
144
145 iprtd->desc->callback = audio_dma_irq;
146 iprtd->desc->callback_param = substream;
147
148 return 0;
149}
150
151static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
152{
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
155
156 if (iprtd->dma_chan) {
157 dma_release_channel(iprtd->dma_chan);
158 iprtd->dma_chan = NULL;
159 }
160
161 return 0;
162}
163
164static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct snd_pcm_runtime *runtime = substream->runtime;
167 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 case SNDRV_PCM_TRIGGER_RESUME:
172 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
173 dmaengine_submit(iprtd->desc);
174
175 break;
176 case SNDRV_PCM_TRIGGER_STOP:
177 case SNDRV_PCM_TRIGGER_SUSPEND:
178 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179 dmaengine_terminate_all(iprtd->dma_chan);
180
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 return 0;
187}
188
189static snd_pcm_uframes_t snd_mxs_pcm_pointer(
190 struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
194
195 return bytes_to_frames(substream->runtime, iprtd->offset);
196}
197
198static int snd_mxs_open(struct snd_pcm_substream *substream)
199{
200 struct snd_pcm_runtime *runtime = substream->runtime;
201 struct mxs_pcm_runtime_data *iprtd;
202 int ret;
203
204 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
205 if (iprtd == NULL)
206 return -ENOMEM;
207 runtime->private_data = iprtd;
208
209 ret = snd_pcm_hw_constraint_integer(substream->runtime,
210 SNDRV_PCM_HW_PARAM_PERIODS);
211 if (ret < 0) {
212 kfree(iprtd);
213 return ret;
214 }
215
216 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
217
218 return 0;
219}
220
221static int snd_mxs_close(struct snd_pcm_substream *substream)
222{
223 struct snd_pcm_runtime *runtime = substream->runtime;
224 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
225
226 kfree(iprtd);
227
228 return 0;
229}
230
231static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
232 struct vm_area_struct *vma)
233{
234 struct snd_pcm_runtime *runtime = substream->runtime;
235
236 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
237 runtime->dma_area,
238 runtime->dma_addr,
239 runtime->dma_bytes);
240}
241
242static struct snd_pcm_ops mxs_pcm_ops = {
243 .open = snd_mxs_open,
244 .close = snd_mxs_close,
245 .ioctl = snd_pcm_lib_ioctl,
246 .hw_params = snd_mxs_pcm_hw_params,
247 .hw_free = snd_mxs_pcm_hw_free,
248 .trigger = snd_mxs_pcm_trigger,
249 .pointer = snd_mxs_pcm_pointer,
250 .mmap = snd_mxs_pcm_mmap,
251};
252
253static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
254{
255 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
256 struct snd_dma_buffer *buf = &substream->dma_buffer;
257 size_t size = snd_mxs_hardware.buffer_bytes_max;
258
259 buf->dev.type = SNDRV_DMA_TYPE_DEV;
260 buf->dev.dev = pcm->card->dev;
261 buf->private_data = NULL;
262 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
263 &buf->addr, GFP_KERNEL);
264 if (!buf->area)
265 return -ENOMEM;
266 buf->bytes = size;
267
268 return 0;
269}
270
271static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
272static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
273{
274 struct snd_card *card = rtd->card->snd_card;
275 struct snd_pcm *pcm = rtd->pcm;
276 int ret = 0;
277
278 if (!card->dev->dma_mask)
279 card->dev->dma_mask = &mxs_pcm_dmamask;
280 if (!card->dev->coherent_dma_mask)
281 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
282
283 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
284 ret = mxs_pcm_preallocate_dma_buffer(pcm,
285 SNDRV_PCM_STREAM_PLAYBACK);
286 if (ret)
287 goto out;
288 }
289
290 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
291 ret = mxs_pcm_preallocate_dma_buffer(pcm,
292 SNDRV_PCM_STREAM_CAPTURE);
293 if (ret)
294 goto out;
295 }
296
297out:
298 return ret;
299}
300
301static void mxs_pcm_free(struct snd_pcm *pcm)
302{
303 struct snd_pcm_substream *substream;
304 struct snd_dma_buffer *buf;
305 int stream;
306
307 for (stream = 0; stream < 2; stream++) {
308 substream = pcm->streams[stream].substream;
309 if (!substream)
310 continue;
311
312 buf = &substream->dma_buffer;
313 if (!buf->area)
314 continue;
315
316 dma_free_writecombine(pcm->card->dev, buf->bytes,
317 buf->area, buf->addr);
318 buf->area = NULL;
319 }
320}
321
322static struct snd_soc_platform_driver mxs_soc_platform = {
323 .ops = &mxs_pcm_ops,
324 .pcm_new = mxs_pcm_new,
325 .pcm_free = mxs_pcm_free,
326};
327
328static int __devinit mxs_soc_platform_probe(struct platform_device *pdev)
329{
330 return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform);
331}
332
333static int __devexit mxs_soc_platform_remove(struct platform_device *pdev)
334{
335 snd_soc_unregister_platform(&pdev->dev);
336
337 return 0;
338}
339
340static struct platform_driver mxs_pcm_driver = {
341 .driver = {
342 .name = "mxs-pcm-audio",
343 .owner = THIS_MODULE,
344 },
345 .probe = mxs_soc_platform_probe,
346 .remove = __devexit_p(mxs_soc_platform_remove),
347};
348
349static int __init snd_mxs_pcm_init(void)
350{
351 return platform_driver_register(&mxs_pcm_driver);
352}
353module_init(snd_mxs_pcm_init);
354
355static void __exit snd_mxs_pcm_exit(void)
356{
357 platform_driver_unregister(&mxs_pcm_driver);
358}
359module_exit(snd_mxs_pcm_exit);
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
new file mode 100644
index 00000000000..f55ac4f7a76
--- /dev/null
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H
21
22#include <mach/dma.h>
23
24struct mxs_pcm_dma_params {
25 int chan_irq;
26 int chan_num;
27};
28
29struct mxs_pcm_runtime_data {
30 int period_bytes;
31 int periods;
32 int dma;
33 unsigned long offset;
34 unsigned long size;
35 void *buf;
36 int period_time;
37 struct dma_async_tx_descriptor *desc;
38 struct dma_chan *dma_chan;
39 struct mxs_dma_data dma_data;
40 struct mxs_pcm_dma_params *dma_params;
41};
42
43#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
new file mode 100644
index 00000000000..401944cf456
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.c
@@ -0,0 +1,797 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/clk.h>
25#include <linux/delay.h>
26#include <linux/time.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/saif.h>
32#include <mach/dma.h>
33#include <asm/mach-types.h>
34#include <mach/hardware.h>
35#include <mach/mxs.h>
36
37#include "mxs-saif.h"
38
39static struct mxs_saif *mxs_saif[2];
40
41/*
42 * SAIF is a little different with other normal SOC DAIs on clock using.
43 *
44 * For MXS, two SAIF modules are instantiated on-chip.
45 * Each SAIF has a set of clock pins and can be operating in master
46 * mode simultaneously if they are connected to different off-chip codecs.
47 * Also, one of the two SAIFs can master or drive the clock pins while the
48 * other SAIF, in slave mode, receives clocking from the master SAIF.
49 * This also means that both SAIFs must operate at the same sample rate.
50 *
51 * We abstract this as each saif has a master, the master could be
52 * himself or other saifs. In the generic saif driver, saif does not need
53 * to know the different clkmux. Saif only needs to know who is his master
54 * and operating his master to generate the proper clock rate for him.
55 * The master id is provided in mach-specific layer according to different
56 * clkmux setting.
57 */
58
59static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
60 int clk_id, unsigned int freq, int dir)
61{
62 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
63
64 switch (clk_id) {
65 case MXS_SAIF_MCLK:
66 saif->mclk = freq;
67 break;
68 default:
69 return -EINVAL;
70 }
71 return 0;
72}
73
74/*
75 * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK
76 * is provided by other SAIF, we provide a interface here to get its master
77 * from its master_id.
78 * Note that the master could be himself.
79 */
80static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif)
81{
82 return mxs_saif[saif->master_id];
83}
84
85/*
86 * Set SAIF clock and MCLK
87 */
88static int mxs_saif_set_clk(struct mxs_saif *saif,
89 unsigned int mclk,
90 unsigned int rate)
91{
92 u32 scr;
93 int ret;
94 struct mxs_saif *master_saif;
95
96 dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate);
97
98 /* Set master saif to generate proper clock */
99 master_saif = mxs_saif_get_master(saif);
100 if (!master_saif)
101 return -EINVAL;
102
103 dev_dbg(saif->dev, "master saif%d\n", master_saif->id);
104
105 /* Checking if can playback and capture simutaneously */
106 if (master_saif->ongoing && rate != master_saif->cur_rate) {
107 dev_err(saif->dev,
108 "can not change clock, master saif%d(rate %d) is ongoing\n",
109 master_saif->id, master_saif->cur_rate);
110 return -EINVAL;
111 }
112
113 scr = __raw_readl(master_saif->base + SAIF_CTRL);
114 scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
115 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
116
117 /*
118 * Set SAIF clock
119 *
120 * The SAIF clock should be either 384*fs or 512*fs.
121 * If MCLK is used, the SAIF clk ratio need to match mclk ratio.
122 * For 32x mclk, set saif clk as 512*fs.
123 * For 48x mclk, set saif clk as 384*fs.
124 *
125 * If MCLK is not used, we just set saif clk to 512*fs.
126 */
127 if (master_saif->mclk_in_use) {
128 if (mclk % 32 == 0) {
129 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
130 ret = clk_set_rate(master_saif->clk, 512 * rate);
131 } else if (mclk % 48 == 0) {
132 scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
133 ret = clk_set_rate(master_saif->clk, 384 * rate);
134 } else {
135 /* SAIF MCLK should be either 32x or 48x */
136 return -EINVAL;
137 }
138 } else {
139 ret = clk_set_rate(master_saif->clk, 512 * rate);
140 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
141 }
142
143 if (ret)
144 return ret;
145
146 master_saif->cur_rate = rate;
147
148 if (!master_saif->mclk_in_use) {
149 __raw_writel(scr, master_saif->base + SAIF_CTRL);
150 return 0;
151 }
152
153 /*
154 * Program the over-sample rate for MCLK output
155 *
156 * The available MCLK range is 32x, 48x... 512x. The rate
157 * could be from 8kHz to 192kH.
158 */
159 switch (mclk / rate) {
160 case 32:
161 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
162 break;
163 case 64:
164 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
165 break;
166 case 128:
167 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
168 break;
169 case 256:
170 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
171 break;
172 case 512:
173 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
174 break;
175 case 48:
176 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
177 break;
178 case 96:
179 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
180 break;
181 case 192:
182 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
183 break;
184 case 384:
185 scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
186 break;
187 default:
188 return -EINVAL;
189 }
190
191 __raw_writel(scr, master_saif->base + SAIF_CTRL);
192
193 return 0;
194}
195
196/*
197 * Put and disable MCLK.
198 */
199int mxs_saif_put_mclk(unsigned int saif_id)
200{
201 struct mxs_saif *saif = mxs_saif[saif_id];
202 u32 stat;
203
204 if (!saif)
205 return -EINVAL;
206
207 stat = __raw_readl(saif->base + SAIF_STAT);
208 if (stat & BM_SAIF_STAT_BUSY) {
209 dev_err(saif->dev, "error: busy\n");
210 return -EBUSY;
211 }
212
213 clk_disable(saif->clk);
214
215 /* disable MCLK output */
216 __raw_writel(BM_SAIF_CTRL_CLKGATE,
217 saif->base + SAIF_CTRL + MXS_SET_ADDR);
218 __raw_writel(BM_SAIF_CTRL_RUN,
219 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
220
221 saif->mclk_in_use = 0;
222 return 0;
223}
224
225/*
226 * Get MCLK and set clock rate, then enable it
227 *
228 * This interface is used for codecs who are using MCLK provided
229 * by saif.
230 */
231int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
232 unsigned int rate)
233{
234 struct mxs_saif *saif = mxs_saif[saif_id];
235 u32 stat;
236 int ret;
237 struct mxs_saif *master_saif;
238
239 if (!saif)
240 return -EINVAL;
241
242 /* Clear Reset */
243 __raw_writel(BM_SAIF_CTRL_SFTRST,
244 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
245
246 /* FIXME: need clear clk gate for register r/w */
247 __raw_writel(BM_SAIF_CTRL_CLKGATE,
248 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
249
250 master_saif = mxs_saif_get_master(saif);
251 if (saif != master_saif) {
252 dev_err(saif->dev, "can not get mclk from a non-master saif\n");
253 return -EINVAL;
254 }
255
256 stat = __raw_readl(saif->base + SAIF_STAT);
257 if (stat & BM_SAIF_STAT_BUSY) {
258 dev_err(saif->dev, "error: busy\n");
259 return -EBUSY;
260 }
261
262 saif->mclk_in_use = 1;
263 ret = mxs_saif_set_clk(saif, mclk, rate);
264 if (ret)
265 return ret;
266
267 ret = clk_enable(saif->clk);
268 if (ret)
269 return ret;
270
271 /* enable MCLK output */
272 __raw_writel(BM_SAIF_CTRL_RUN,
273 saif->base + SAIF_CTRL + MXS_SET_ADDR);
274
275 return 0;
276}
277
278/*
279 * SAIF DAI format configuration.
280 * Should only be called when port is inactive.
281 */
282static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
283{
284 u32 scr, stat;
285 u32 scr0;
286 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
287
288 stat = __raw_readl(saif->base + SAIF_STAT);
289 if (stat & BM_SAIF_STAT_BUSY) {
290 dev_err(cpu_dai->dev, "error: busy\n");
291 return -EBUSY;
292 }
293
294 scr0 = __raw_readl(saif->base + SAIF_CTRL);
295 scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
296 & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
297 scr = 0;
298
299 /* DAI mode */
300 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301 case SND_SOC_DAIFMT_I2S:
302 /* data frame low 1clk before data */
303 scr |= BM_SAIF_CTRL_DELAY;
304 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
305 break;
306 case SND_SOC_DAIFMT_LEFT_J:
307 /* data frame high with data */
308 scr &= ~BM_SAIF_CTRL_DELAY;
309 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
310 scr &= ~BM_SAIF_CTRL_JUSTIFY;
311 break;
312 default:
313 return -EINVAL;
314 }
315
316 /* DAI clock inversion */
317 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
318 case SND_SOC_DAIFMT_IB_IF:
319 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
320 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
321 break;
322 case SND_SOC_DAIFMT_IB_NF:
323 scr |= BM_SAIF_CTRL_BITCLK_EDGE;
324 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
325 break;
326 case SND_SOC_DAIFMT_NB_IF:
327 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
328 scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
329 break;
330 case SND_SOC_DAIFMT_NB_NF:
331 scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
332 scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
333 break;
334 }
335
336 /*
337 * Note: We simply just support master mode since SAIF TX can only
338 * work as master.
339 * Here the master is relative to codec side.
340 * Saif internally could be slave when working on EXTMASTER mode.
341 * We just hide this to machine driver.
342 */
343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344 case SND_SOC_DAIFMT_CBS_CFS:
345 if (saif->id == saif->master_id)
346 scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
347 else
348 scr |= BM_SAIF_CTRL_SLAVE_MODE;
349
350 __raw_writel(scr | scr0, saif->base + SAIF_CTRL);
351 break;
352 default:
353 return -EINVAL;
354 }
355
356 return 0;
357}
358
359static int mxs_saif_startup(struct snd_pcm_substream *substream,
360 struct snd_soc_dai *cpu_dai)
361{
362 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
363 snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param);
364
365 /* clear error status to 0 for each re-open */
366 saif->fifo_underrun = 0;
367 saif->fifo_overrun = 0;
368
369 /* Clear Reset for normal operations */
370 __raw_writel(BM_SAIF_CTRL_SFTRST,
371 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
372
373 /* clear clock gate */
374 __raw_writel(BM_SAIF_CTRL_CLKGATE,
375 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
376
377 return 0;
378}
379
380/*
381 * Should only be called when port is inactive.
382 * although can be called multiple times by upper layers.
383 */
384static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
385 struct snd_pcm_hw_params *params,
386 struct snd_soc_dai *cpu_dai)
387{
388 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
389 u32 scr, stat;
390 int ret;
391
392 /* mclk should already be set */
393 if (!saif->mclk && saif->mclk_in_use) {
394 dev_err(cpu_dai->dev, "set mclk first\n");
395 return -EINVAL;
396 }
397
398 stat = __raw_readl(saif->base + SAIF_STAT);
399 if (stat & BM_SAIF_STAT_BUSY) {
400 dev_err(cpu_dai->dev, "error: busy\n");
401 return -EBUSY;
402 }
403
404 /*
405 * Set saif clk based on sample rate.
406 * If mclk is used, we also set mclk, if not, saif->mclk is
407 * default 0, means not used.
408 */
409 ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
410 if (ret) {
411 dev_err(cpu_dai->dev, "unable to get proper clk\n");
412 return ret;
413 }
414
415 scr = __raw_readl(saif->base + SAIF_CTRL);
416
417 scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
418 scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
419 switch (params_format(params)) {
420 case SNDRV_PCM_FORMAT_S16_LE:
421 scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
422 break;
423 case SNDRV_PCM_FORMAT_S20_3LE:
424 scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
425 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
426 break;
427 case SNDRV_PCM_FORMAT_S24_LE:
428 scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
429 scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
430 break;
431 default:
432 return -EINVAL;
433 }
434
435 /* Tx/Rx config */
436 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
437 /* enable TX mode */
438 scr &= ~BM_SAIF_CTRL_READ_MODE;
439 } else {
440 /* enable RX mode */
441 scr |= BM_SAIF_CTRL_READ_MODE;
442 }
443
444 __raw_writel(scr, saif->base + SAIF_CTRL);
445 return 0;
446}
447
448static int mxs_saif_prepare(struct snd_pcm_substream *substream,
449 struct snd_soc_dai *cpu_dai)
450{
451 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
452
453 /* enable FIFO error irqs */
454 __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
455 saif->base + SAIF_CTRL + MXS_SET_ADDR);
456
457 return 0;
458}
459
460static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
461 struct snd_soc_dai *cpu_dai)
462{
463 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
464 struct mxs_saif *master_saif;
465 u32 delay;
466
467 master_saif = mxs_saif_get_master(saif);
468 if (!master_saif)
469 return -EINVAL;
470
471 switch (cmd) {
472 case SNDRV_PCM_TRIGGER_START:
473 case SNDRV_PCM_TRIGGER_RESUME:
474 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
475 dev_dbg(cpu_dai->dev, "start\n");
476
477 clk_enable(master_saif->clk);
478 if (!master_saif->mclk_in_use)
479 __raw_writel(BM_SAIF_CTRL_RUN,
480 master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
481
482 /*
483 * If the saif's master is not himself, we also need to enable
484 * itself clk for its internal basic logic to work.
485 */
486 if (saif != master_saif) {
487 clk_enable(saif->clk);
488 __raw_writel(BM_SAIF_CTRL_RUN,
489 saif->base + SAIF_CTRL + MXS_SET_ADDR);
490 }
491
492 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
493 /*
494 * write a data to saif data register to trigger
495 * the transfer
496 */
497 __raw_writel(0, saif->base + SAIF_DATA);
498 } else {
499 /*
500 * read a data from saif data register to trigger
501 * the receive
502 */
503 __raw_readl(saif->base + SAIF_DATA);
504 }
505
506 master_saif->ongoing = 1;
507
508 dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
509 __raw_readl(saif->base + SAIF_CTRL),
510 __raw_readl(saif->base + SAIF_STAT));
511
512 dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n",
513 __raw_readl(master_saif->base + SAIF_CTRL),
514 __raw_readl(master_saif->base + SAIF_STAT));
515 break;
516 case SNDRV_PCM_TRIGGER_SUSPEND:
517 case SNDRV_PCM_TRIGGER_STOP:
518 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
519 dev_dbg(cpu_dai->dev, "stop\n");
520
521 /* wait a while for the current sample to complete */
522 delay = USEC_PER_SEC / master_saif->cur_rate;
523
524 if (!master_saif->mclk_in_use) {
525 __raw_writel(BM_SAIF_CTRL_RUN,
526 master_saif->base + SAIF_CTRL + MXS_CLR_ADDR);
527 udelay(delay);
528 }
529 clk_disable(master_saif->clk);
530
531 if (saif != master_saif) {
532 __raw_writel(BM_SAIF_CTRL_RUN,
533 saif->base + SAIF_CTRL + MXS_CLR_ADDR);
534 udelay(delay);
535 clk_disable(saif->clk);
536 }
537
538 master_saif->ongoing = 0;
539
540 break;
541 default:
542 return -EINVAL;
543 }
544
545 return 0;
546}
547
548#define MXS_SAIF_RATES SNDRV_PCM_RATE_8000_192000
549#define MXS_SAIF_FORMATS \
550 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
551 SNDRV_PCM_FMTBIT_S24_LE)
552
553static struct snd_soc_dai_ops mxs_saif_dai_ops = {
554 .startup = mxs_saif_startup,
555 .trigger = mxs_saif_trigger,
556 .prepare = mxs_saif_prepare,
557 .hw_params = mxs_saif_hw_params,
558 .set_sysclk = mxs_saif_set_dai_sysclk,
559 .set_fmt = mxs_saif_set_dai_fmt,
560};
561
562static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
563{
564 struct mxs_saif *saif = dev_get_drvdata(dai->dev);
565
566 snd_soc_dai_set_drvdata(dai, saif);
567
568 return 0;
569}
570
571static struct snd_soc_dai_driver mxs_saif_dai = {
572 .name = "mxs-saif",
573 .probe = mxs_saif_dai_probe,
574 .playback = {
575 .channels_min = 2,
576 .channels_max = 2,
577 .rates = MXS_SAIF_RATES,
578 .formats = MXS_SAIF_FORMATS,
579 },
580 .capture = {
581 .channels_min = 2,
582 .channels_max = 2,
583 .rates = MXS_SAIF_RATES,
584 .formats = MXS_SAIF_FORMATS,
585 },
586 .ops = &mxs_saif_dai_ops,
587};
588
589static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
590{
591 struct mxs_saif *saif = dev_id;
592 unsigned int stat;
593
594 stat = __raw_readl(saif->base + SAIF_STAT);
595 if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
596 BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
597 return IRQ_NONE;
598
599 if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
600 dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
601 __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
602 saif->base + SAIF_STAT + MXS_CLR_ADDR);
603 }
604
605 if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
606 dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
607 __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
608 saif->base + SAIF_STAT + MXS_CLR_ADDR);
609 }
610
611 dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
612 __raw_readl(saif->base + SAIF_CTRL),
613 __raw_readl(saif->base + SAIF_STAT));
614
615 return IRQ_HANDLED;
616}
617
618static int mxs_saif_probe(struct platform_device *pdev)
619{
620 struct resource *res;
621 struct mxs_saif *saif;
622 struct mxs_saif_platform_data *pdata;
623 int ret = 0;
624
625 if (pdev->id >= ARRAY_SIZE(mxs_saif))
626 return -EINVAL;
627
628 pdata = pdev->dev.platform_data;
629 if (pdata && pdata->init) {
630 ret = pdata->init();
631 if (ret)
632 return ret;
633 }
634
635 saif = kzalloc(sizeof(*saif), GFP_KERNEL);
636 if (!saif)
637 return -ENOMEM;
638
639 mxs_saif[pdev->id] = saif;
640 saif->id = pdev->id;
641
642 saif->master_id = saif->id;
643 if (pdata && pdata->get_master_id) {
644 saif->master_id = pdata->get_master_id(saif->id);
645 if (saif->master_id < 0 ||
646 saif->master_id >= ARRAY_SIZE(mxs_saif))
647 return -EINVAL;
648 }
649
650 saif->clk = clk_get(&pdev->dev, NULL);
651 if (IS_ERR(saif->clk)) {
652 ret = PTR_ERR(saif->clk);
653 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
654 ret);
655 goto failed_clk;
656 }
657
658 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
659 if (!res) {
660 ret = -ENODEV;
661 dev_err(&pdev->dev, "failed to get io resource: %d\n",
662 ret);
663 goto failed_get_resource;
664 }
665
666 if (!request_mem_region(res->start, resource_size(res), "mxs-saif")) {
667 dev_err(&pdev->dev, "request_mem_region failed\n");
668 ret = -EBUSY;
669 goto failed_get_resource;
670 }
671
672 saif->base = ioremap(res->start, resource_size(res));
673 if (!saif->base) {
674 dev_err(&pdev->dev, "ioremap failed\n");
675 ret = -ENODEV;
676 goto failed_ioremap;
677 }
678
679 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
680 if (!res) {
681 ret = -ENODEV;
682 dev_err(&pdev->dev, "failed to get dma resource: %d\n",
683 ret);
684 goto failed_ioremap;
685 }
686 saif->dma_param.chan_num = res->start;
687
688 saif->irq = platform_get_irq(pdev, 0);
689 if (saif->irq < 0) {
690 ret = saif->irq;
691 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
692 ret);
693 goto failed_get_irq1;
694 }
695
696 saif->dev = &pdev->dev;
697 ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
698 if (ret) {
699 dev_err(&pdev->dev, "failed to request irq\n");
700 goto failed_get_irq1;
701 }
702
703 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
704 if (saif->dma_param.chan_irq < 0) {
705 ret = saif->dma_param.chan_irq;
706 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
707 ret);
708 goto failed_get_irq2;
709 }
710
711 platform_set_drvdata(pdev, saif);
712
713 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
714 if (ret) {
715 dev_err(&pdev->dev, "register DAI failed\n");
716 goto failed_register;
717 }
718
719 saif->soc_platform_pdev = platform_device_alloc(
720 "mxs-pcm-audio", pdev->id);
721 if (!saif->soc_platform_pdev) {
722 ret = -ENOMEM;
723 goto failed_pdev_alloc;
724 }
725
726 platform_set_drvdata(saif->soc_platform_pdev, saif);
727 ret = platform_device_add(saif->soc_platform_pdev);
728 if (ret) {
729 dev_err(&pdev->dev, "failed to add soc platform device\n");
730 goto failed_pdev_add;
731 }
732
733 return 0;
734
735failed_pdev_add:
736 platform_device_put(saif->soc_platform_pdev);
737failed_pdev_alloc:
738 snd_soc_unregister_dai(&pdev->dev);
739failed_register:
740failed_get_irq2:
741 free_irq(saif->irq, saif);
742failed_get_irq1:
743 iounmap(saif->base);
744failed_ioremap:
745 release_mem_region(res->start, resource_size(res));
746failed_get_resource:
747 clk_put(saif->clk);
748failed_clk:
749 kfree(saif);
750
751 return ret;
752}
753
754static int __devexit mxs_saif_remove(struct platform_device *pdev)
755{
756 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
757 struct mxs_saif *saif = platform_get_drvdata(pdev);
758
759 platform_device_unregister(saif->soc_platform_pdev);
760
761 snd_soc_unregister_dai(&pdev->dev);
762
763 iounmap(saif->base);
764 release_mem_region(res->start, resource_size(res));
765 free_irq(saif->irq, saif);
766
767 clk_put(saif->clk);
768 kfree(saif);
769
770 return 0;
771}
772
773static struct platform_driver mxs_saif_driver = {
774 .probe = mxs_saif_probe,
775 .remove = __devexit_p(mxs_saif_remove),
776
777 .driver = {
778 .name = "mxs-saif",
779 .owner = THIS_MODULE,
780 },
781};
782
783static int __init mxs_saif_init(void)
784{
785 return platform_driver_register(&mxs_saif_driver);
786}
787
788static void __exit mxs_saif_exit(void)
789{
790 platform_driver_unregister(&mxs_saif_driver);
791}
792
793module_init(mxs_saif_init);
794module_exit(mxs_saif_exit);
795MODULE_AUTHOR("Freescale Semiconductor, Inc.");
796MODULE_DESCRIPTION("MXS ASoC SAIF driver");
797MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
new file mode 100644
index 00000000000..12c91e4eb94
--- /dev/null
+++ b/sound/soc/mxs/mxs-saif.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#ifndef _MXS_SAIF_H
21#define _MXS_SAIF_H
22
23#define SAIF_CTRL 0x0
24#define SAIF_STAT 0x10
25#define SAIF_DATA 0x20
26#define SAIF_VERSION 0X30
27
28/* SAIF_CTRL */
29#define BM_SAIF_CTRL_SFTRST 0x80000000
30#define BM_SAIF_CTRL_CLKGATE 0x40000000
31#define BP_SAIF_CTRL_BITCLK_MULT_RATE 27
32#define BM_SAIF_CTRL_BITCLK_MULT_RATE 0x38000000
33#define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \
34 (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE)
35#define BM_SAIF_CTRL_BITCLK_BASE_RATE 0x04000000
36#define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000
37#define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN 0x01000000
38#define BP_SAIF_CTRL_RSRVD2 21
39#define BM_SAIF_CTRL_RSRVD2 0x00E00000
40
41#define BP_SAIF_CTRL_DMAWAIT_COUNT 16
42#define BM_SAIF_CTRL_DMAWAIT_COUNT 0x001F0000
43#define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \
44 (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT)
45#define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14
46#define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000
47#define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \
48 (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT)
49#define BM_SAIF_CTRL_LRCLK_PULSE 0x00002000
50#define BM_SAIF_CTRL_BIT_ORDER 0x00001000
51#define BM_SAIF_CTRL_DELAY 0x00000800
52#define BM_SAIF_CTRL_JUSTIFY 0x00000400
53#define BM_SAIF_CTRL_LRCLK_POLARITY 0x00000200
54#define BM_SAIF_CTRL_BITCLK_EDGE 0x00000100
55#define BP_SAIF_CTRL_WORD_LENGTH 4
56#define BM_SAIF_CTRL_WORD_LENGTH 0x000000F0
57#define BF_SAIF_CTRL_WORD_LENGTH(v) \
58 (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH)
59#define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE 0x00000008
60#define BM_SAIF_CTRL_SLAVE_MODE 0x00000004
61#define BM_SAIF_CTRL_READ_MODE 0x00000002
62#define BM_SAIF_CTRL_RUN 0x00000001
63
64/* SAIF_STAT */
65#define BM_SAIF_STAT_PRESENT 0x80000000
66#define BP_SAIF_STAT_RSRVD2 17
67#define BM_SAIF_STAT_RSRVD2 0x7FFE0000
68#define BF_SAIF_STAT_RSRVD2(v) \
69 (((v) << 17) & BM_SAIF_STAT_RSRVD2)
70#define BM_SAIF_STAT_DMA_PREQ 0x00010000
71#define BP_SAIF_STAT_RSRVD1 7
72#define BM_SAIF_STAT_RSRVD1 0x0000FF80
73#define BF_SAIF_STAT_RSRVD1(v) \
74 (((v) << 7) & BM_SAIF_STAT_RSRVD1)
75
76#define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040
77#define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020
78#define BM_SAIF_STAT_FIFO_SERVICE_IRQ 0x00000010
79#define BP_SAIF_STAT_RSRVD0 1
80#define BM_SAIF_STAT_RSRVD0 0x0000000E
81#define BF_SAIF_STAT_RSRVD0(v) \
82 (((v) << 1) & BM_SAIF_STAT_RSRVD0)
83#define BM_SAIF_STAT_BUSY 0x00000001
84
85/* SAFI_DATA */
86#define BP_SAIF_DATA_PCM_RIGHT 16
87#define BM_SAIF_DATA_PCM_RIGHT 0xFFFF0000
88#define BF_SAIF_DATA_PCM_RIGHT(v) \
89 (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT)
90#define BP_SAIF_DATA_PCM_LEFT 0
91#define BM_SAIF_DATA_PCM_LEFT 0x0000FFFF
92#define BF_SAIF_DATA_PCM_LEFT(v) \
93 (((v) << 0) & BM_SAIF_DATA_PCM_LEFT)
94
95/* SAIF_VERSION */
96#define BP_SAIF_VERSION_MAJOR 24
97#define BM_SAIF_VERSION_MAJOR 0xFF000000
98#define BF_SAIF_VERSION_MAJOR(v) \
99 (((v) << 24) & BM_SAIF_VERSION_MAJOR)
100#define BP_SAIF_VERSION_MINOR 16
101#define BM_SAIF_VERSION_MINOR 0x00FF0000
102#define BF_SAIF_VERSION_MINOR(v) \
103 (((v) << 16) & BM_SAIF_VERSION_MINOR)
104#define BP_SAIF_VERSION_STEP 0
105#define BM_SAIF_VERSION_STEP 0x0000FFFF
106#define BF_SAIF_VERSION_STEP(v) \
107 (((v) << 0) & BM_SAIF_VERSION_STEP)
108
109#define MXS_SAIF_MCLK 0
110
111#include "mxs-pcm.h"
112
113struct mxs_saif {
114 struct device *dev;
115 struct clk *clk;
116 unsigned int mclk;
117 unsigned int mclk_in_use;
118 void __iomem *base;
119 int irq;
120 struct mxs_pcm_dma_params dma_param;
121 unsigned int id;
122 unsigned int master_id;
123 unsigned int cur_rate;
124 unsigned int ongoing;
125
126 struct platform_device *soc_platform_pdev;
127 u32 fifo_underrun;
128 u32 fifo_overrun;
129};
130
131extern int mxs_saif_put_mclk(unsigned int saif_id);
132extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
133 unsigned int rate);
134#endif
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
new file mode 100644
index 00000000000..7fbeaec06eb
--- /dev/null
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -0,0 +1,173 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include <sound/soc-dapm.h>
26#include <asm/mach-types.h>
27
28#include "../codecs/sgtl5000.h"
29#include "mxs-saif.h"
30
31static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params)
33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
37 unsigned int rate = params_rate(params);
38 u32 dai_format, mclk;
39 int ret;
40
41 /* sgtl5000 does not support 512*rate when in 96000 fs */
42 switch (rate) {
43 case 96000:
44 mclk = 256 * rate;
45 break;
46 default:
47 mclk = 512 * rate;
48 break;
49 }
50
51 /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
52 if (mclk < 8000000 || mclk > 27000000)
53 return -EINVAL;
54
55 /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
56 ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
57 if (ret)
58 return ret;
59
60 /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
61 ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
62 if (ret)
63 return ret;
64
65 /* set codec to slave mode */
66 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
67 SND_SOC_DAIFMT_CBS_CFS;
68
69 /* set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
71 if (ret)
72 return ret;
73
74 /* set cpu DAI configuration */
75 ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
76 if (ret)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops mxs_sgtl5000_hifi_ops = {
83 .hw_params = mxs_sgtl5000_hw_params,
84};
85
86static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
87 {
88 .name = "HiFi Tx",
89 .stream_name = "HiFi Playback",
90 .codec_dai_name = "sgtl5000",
91 .codec_name = "sgtl5000.0-000a",
92 .cpu_dai_name = "mxs-saif.0",
93 .platform_name = "mxs-pcm-audio.0",
94 .ops = &mxs_sgtl5000_hifi_ops,
95 }, {
96 .name = "HiFi Rx",
97 .stream_name = "HiFi Capture",
98 .codec_dai_name = "sgtl5000",
99 .codec_name = "sgtl5000.0-000a",
100 .cpu_dai_name = "mxs-saif.1",
101 .platform_name = "mxs-pcm-audio.1",
102 .ops = &mxs_sgtl5000_hifi_ops,
103 },
104};
105
106static struct snd_soc_card mxs_sgtl5000 = {
107 .name = "mxs_sgtl5000",
108 .dai_link = mxs_sgtl5000_dai,
109 .num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
110};
111
112static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
113{
114 struct snd_soc_card *card = &mxs_sgtl5000;
115 int ret;
116
117 /*
118 * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
119 * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
120 * should be >= 8MHz and <= 27M.
121 */
122 ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
123 if (ret)
124 return ret;
125
126 card->dev = &pdev->dev;
127 platform_set_drvdata(pdev, card);
128
129 ret = snd_soc_register_card(card);
130 if (ret) {
131 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
132 ret);
133 return ret;
134 }
135
136 return 0;
137}
138
139static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
140{
141 struct snd_soc_card *card = platform_get_drvdata(pdev);
142
143 mxs_saif_put_mclk(0);
144
145 snd_soc_unregister_card(card);
146
147 return 0;
148}
149
150static struct platform_driver mxs_sgtl5000_audio_driver = {
151 .driver = {
152 .name = "mxs-sgtl5000",
153 .owner = THIS_MODULE,
154 },
155 .probe = mxs_sgtl5000_probe,
156 .remove = __devexit_p(mxs_sgtl5000_remove),
157};
158
159static int __init mxs_sgtl5000_init(void)
160{
161 return platform_driver_register(&mxs_sgtl5000_audio_driver);
162}
163module_init(mxs_sgtl5000_init);
164
165static void __exit mxs_sgtl5000_exit(void)
166{
167 platform_driver_unregister(&mxs_sgtl5000_audio_driver);
168}
169module_exit(mxs_sgtl5000_exit);
170
171MODULE_AUTHOR("Freescale Semiconductor, Inc.");
172MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
173MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index d589ef14e91..e46d5516e00 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -318,7 +318,6 @@ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) 318static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
319{ 319{
320 struct snd_card *card = rtd->card->snd_card; 320 struct snd_card *card = rtd->card->snd_card;
321 struct snd_soc_dai *dai = rtd->cpu_dai;
322 struct snd_pcm *pcm = rtd->pcm; 321 struct snd_pcm *pcm = rtd->pcm;
323 322
324 if (!card->dev->dma_mask) 323 if (!card->dev->dma_mask)
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 1a591f1ebfb..b899a3bc8f4 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -306,8 +306,10 @@ static int __init raumfeld_audio_init(void)
306 &snd_soc_raumfeld_connector); 306 &snd_soc_raumfeld_connector);
307 307
308 ret = platform_device_add(raumfeld_audio_device); 308 ret = platform_device_add(raumfeld_audio_device);
309 if (ret < 0) 309 if (ret < 0) {
310 platform_device_put(raumfeld_audio_device);
310 return ret; 311 return ret;
312 }
311 313
312 raumfeld_enable_audio(true); 314 raumfeld_enable_audio(true);
313 return 0; 315 return 0;
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index b253d864868..ce920e3cfea 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -312,7 +312,7 @@ static struct snd_soc_dai_link spitz_dai = {
312 .cpu_dai_name = "pxa2xx-i2s", 312 .cpu_dai_name = "pxa2xx-i2s",
313 .codec_dai_name = "wm8750-hifi", 313 .codec_dai_name = "wm8750-hifi",
314 .platform_name = "pxa-pcm-audio", 314 .platform_name = "pxa-pcm-audio",
315 .codec_name = "wm8750-codec.0-001b", 315 .codec_name = "wm8750.0-001b",
316 .init = spitz_wm8750_init, 316 .init = spitz_wm8750_init,
317 .ops = &spitz_ops, 317 .ops = &spitz_ops,
318}; 318};
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index d69d9fc3223..4b81ffd8756 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -198,7 +198,7 @@ static struct snd_soc_dai_link z2_dai = {
198 .cpu_dai_name = "pxa2xx-i2s", 198 .cpu_dai_name = "pxa2xx-i2s",
199 .codec_dai_name = "wm8750-hifi", 199 .codec_dai_name = "wm8750-hifi",
200 .platform_name = "pxa-pcm-audio", 200 .platform_name = "pxa-pcm-audio",
201 .codec_name = "wm8750-codec.0-001b", 201 .codec_name = "wm8750.0-001b",
202 .init = z2_wm8750_init, 202 .init = z2_wm8750_init,
203 .ops = &z2_ops, 203 .ops = &z2_ops,
204}; 204};
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 80c85fd64e1..55efc2bdf0b 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -446,7 +446,6 @@ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) 446static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
447{ 447{
448 struct snd_card *card = runtime->card->snd_card; 448 struct snd_card *card = runtime->card->snd_card;
449 struct snd_soc_dai *dai = runtime->cpu_dai;
450 struct snd_pcm *pcm = runtime->pcm; 449 struct snd_pcm *pcm = runtime->pcm;
451 struct s6000_pcm_dma_params *params; 450 struct s6000_pcm_dma_params *params;
452 int res; 451 int res;
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 65f980ef287..dd3b3eac080 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -63,7 +63,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8994 64config SND_SOC_SAMSUNG_SMDK_WM8994
65 tristate "SoC I2S Audio support for WM8994 on SMDK" 65 tristate "SoC I2S Audio support for WM8994 on SMDK"
66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210) 66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212)
67 select SND_SOC_WM8994 67 select SND_SOC_WM8994
68 select SND_SAMSUNG_I2S 68 select SND_SAMSUNG_I2S
69 help 69 help
@@ -158,7 +158,7 @@ config SND_SOC_GONI_AQUILA_WM8994
158 158
159config SND_SOC_SAMSUNG_SMDK_SPDIF 159config SND_SOC_SAMSUNG_SMDK_SPDIF
160 tristate "SoC S/PDIF Audio support for SMDK" 160 tristate "SoC S/PDIF Audio support for SMDK"
161 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310) 161 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212)
162 select SND_SAMSUNG_SPDIF 162 select SND_SAMSUNG_SPDIF
163 help 163 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
@@ -173,7 +173,7 @@ config SND_SOC_SMDK_WM8580_PCM
173 173
174config SND_SOC_SMDK_WM8994_PCM 174config SND_SOC_SMDK_WM8994_PCM
175 tristate "SoC PCM Audio support for WM8994 on SMDK" 175 tristate "SoC PCM Audio support for WM8994 on SMDK"
176 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310) 176 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212)
177 select SND_SOC_WM8994 177 select SND_SOC_WM8994
178 select SND_SAMSUNG_PCM 178 select SND_SAMSUNG_PCM
179 help 179 help
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 14eb6ea69e7..ed8f13a29c8 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -131,7 +131,7 @@ static struct snd_soc_dai_link jive_dai = {
131 .cpu_dai_name = "s3c2412-i2s", 131 .cpu_dai_name = "s3c2412-i2s",
132 .codec_dai_name = "wm8750-hifi", 132 .codec_dai_name = "wm8750-hifi",
133 .platform_name = "samsung-audio", 133 .platform_name = "samsung-audio",
134 .codec_name = "wm8750-codec.0-001a", 134 .codec_name = "wm8750.0-001a",
135 .init = jive_wm8750_init, 135 .init = jive_wm8750_init,
136 .ops = &jive_ops, 136 .ops = &jive_ops,
137}; 137};
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 841ab14c110..7ab8e2c2921 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -69,10 +69,10 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 69 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
70 70
71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); 71 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
72 if (s3c2412_i2s.iis_cclk == NULL) { 72 if (IS_ERR(s3c2412_i2s.iis_cclk)) {
73 pr_err("failed to get i2sclk clock\n"); 73 pr_err("failed to get i2sclk clock\n");
74 iounmap(s3c2412_i2s.regs); 74 iounmap(s3c2412_i2s.regs);
75 return -ENODEV; 75 return PTR_ERR(s3c2412_i2s.iis_cclk);
76 } 76 }
77 77
78 /* Set MPLL as the source for IIS CLK */ 78 /* Set MPLL as the source for IIS CLK */
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 63d8849d80b..21c92e2e300 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -383,10 +383,10 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
383 return -ENXIO; 383 return -ENXIO;
384 384
385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); 385 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
386 if (s3c24xx_i2s.iis_clk == NULL) { 386 if (IS_ERR(s3c24xx_i2s.iis_clk)) {
387 pr_err("failed to get iis_clock\n"); 387 pr_err("failed to get iis_clock\n");
388 iounmap(s3c24xx_i2s.regs); 388 iounmap(s3c24xx_i2s.regs);
389 return -ENODEV; 389 return PTR_ERR(s3c24xx_i2s.iis_clk);
390 } 390 }
391 clk_enable(s3c24xx_i2s.iis_clk); 391 clk_enable(s3c24xx_i2s.iis_clk);
392 392
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index dc9d551f678..65c1cfd47d8 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -66,17 +66,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
66 pr_debug("%s %d\n", __func__, clk_users); 66 pr_debug("%s %d\n", __func__, clk_users);
67 if (clk_users == 0) { 67 if (clk_users == 0) {
68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); 68 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
69 if (!xtal) { 69 if (IS_ERR(xtal)) {
70 printk(KERN_ERR "%s cannot get xtal\n", __func__); 70 printk(KERN_ERR "%s cannot get xtal\n", __func__);
71 ret = -EBUSY; 71 ret = PTR_ERR(xtal);
72 } else { 72 } else {
73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, 73 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
74 "pclk"); 74 "pclk");
75 if (!pclk) { 75 if (IS_ERR(pclk)) {
76 printk(KERN_ERR "%s cannot get pclk\n", 76 printk(KERN_ERR "%s cannot get pclk\n",
77 __func__); 77 __func__);
78 clk_put(xtal); 78 clk_put(xtal);
79 ret = -EBUSY; 79 ret = PTR_ERR(pclk);
80 } 80 }
81 } 81 }
82 if (!ret) { 82 if (!ret) {
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 0a2c4f22303..bbd14768ecd 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -207,7 +207,7 @@ static struct snd_soc_dai_link smartq_dai[] = {
207 .cpu_dai_name = "samsung-i2s.0", 207 .cpu_dai_name = "samsung-i2s.0",
208 .codec_dai_name = "wm8750-hifi", 208 .codec_dai_name = "wm8750-hifi",
209 .platform_name = "samsung-audio", 209 .platform_name = "samsung-audio",
210 .codec_name = "wm8750-codec.0-0x1a", 210 .codec_name = "wm8750.0-0x1a",
211 .init = smartq_wm8987_init, 211 .init = smartq_wm8987_init,
212 .ops = &smartq_hifi_ops, 212 .ops = &smartq_hifi_ops,
213 }, 213 },
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 3d26f6607aa..20deecf3b24 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -210,7 +210,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
210 .cpu_dai_name = "samsung-i2s.0", 210 .cpu_dai_name = "samsung-i2s.0",
211 .codec_dai_name = "wm8580-hifi-playback", 211 .codec_dai_name = "wm8580-hifi-playback",
212 .platform_name = "samsung-audio", 212 .platform_name = "samsung-audio",
213 .codec_name = "wm8580-codec.0-001b", 213 .codec_name = "wm8580.0-001b",
214 .init = smdk_wm8580_init_paifrx, 214 .init = smdk_wm8580_init_paifrx,
215 .ops = &smdk_ops, 215 .ops = &smdk_ops,
216 }, 216 },
@@ -220,7 +220,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
220 .cpu_dai_name = "samsung-i2s.0", 220 .cpu_dai_name = "samsung-i2s.0",
221 .codec_dai_name = "wm8580-hifi-capture", 221 .codec_dai_name = "wm8580-hifi-capture",
222 .platform_name = "samsung-audio", 222 .platform_name = "samsung-audio",
223 .codec_name = "wm8580-codec.0-001b", 223 .codec_name = "wm8580.0-001b",
224 .init = smdk_wm8580_init_paiftx, 224 .init = smdk_wm8580_init_paiftx,
225 .ops = &smdk_ops, 225 .ops = &smdk_ops,
226 }, 226 },
@@ -230,7 +230,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
230 .cpu_dai_name = "samsung-i2s.x", 230 .cpu_dai_name = "samsung-i2s.x",
231 .codec_dai_name = "wm8580-hifi-playback", 231 .codec_dai_name = "wm8580-hifi-playback",
232 .platform_name = "samsung-audio", 232 .platform_name = "samsung-audio",
233 .codec_name = "wm8580-codec.0-001b", 233 .codec_name = "wm8580.0-001b",
234 .init = smdk_wm8580_init_paifrx, 234 .init = smdk_wm8580_init_paifrx,
235 .ops = &smdk_ops, 235 .ops = &smdk_ops,
236 }, 236 },
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index 0d12092df16..4b9c73477ce 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
127 .cpu_dai_name = "samsung-pcm.0", 127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback", 128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio", 129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b", 130 .codec_name = "wm8580.0-001b",
131 .ops = &smdk_wm8580_pcm_ops, 131 .ops = &smdk_wm8580_pcm_ops,
132 }, { 132 }, {
133 .name = "WM8580 PAIF PCM TX", 133 .name = "WM8580 PAIF PCM TX",
@@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
135 .cpu_dai_name = "samsung-pcm.0", 135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture", 136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio", 137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b", 138 .codec_name = "wm8580.0-001b",
139 .ops = &smdk_wm8580_pcm_ops, 139 .ops = &smdk_wm8580_pcm_ops,
140 }, 140 },
141}; 141};
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 590e9274b06..b9e213f6cc0 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -125,10 +125,6 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = {
125 .pin = "Headset Mic", 125 .pin = "Headset Mic",
126 .mask = SND_JACK_MICROPHONE, 126 .mask = SND_JACK_MICROPHONE,
127 }, 127 },
128 {
129 .pin = "Headphone",
130 .mask = SND_JACK_HEADPHONE,
131 },
132}; 128};
133 129
134/* Default the headphone selection to active high */ 130/* Default the headphone selection to active high */
@@ -171,7 +167,8 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
171 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); 167 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
172 168
173 ret = snd_soc_jack_new(codec, "Headset", 169 ret = snd_soc_jack_new(codec, "Headset",
174 SND_JACK_HEADSET | SND_JACK_BTN_0, 170 SND_JACK_LINEOUT | SND_JACK_HEADSET |
171 SND_JACK_BTN_0,
175 &speyside_headset); 172 &speyside_headset);
176 if (ret) 173 if (ret)
177 return ret; 174 return ret;
@@ -227,7 +224,7 @@ static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
227 snd_soc_dapm_nc_pin(dapm, "LINEOUT"); 224 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
228 225
229 /* At any time the WM9081 is active it will have this clock */ 226 /* At any time the WM9081 is active it will have this clock */
230 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 227 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
231 48000 * 256, 0); 228 48000 * 256, 0);
232} 229}
233 230
@@ -252,6 +249,7 @@ static const struct snd_kcontrol_new controls[] = {
252 SOC_DAPM_PIN_SWITCH("Main AMIC"), 249 SOC_DAPM_PIN_SWITCH("Main AMIC"),
253 SOC_DAPM_PIN_SWITCH("WM1250 Input"), 250 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
254 SOC_DAPM_PIN_SWITCH("WM1250 Output"), 251 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
252 SOC_DAPM_PIN_SWITCH("Headphone"),
255}; 253};
256 254
257static struct snd_soc_dapm_widget widgets[] = { 255static struct snd_soc_dapm_widget widgets[] = {
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/speyside_wm8962.c
index 72535f2daaf..3820a6b057d 100644
--- a/sound/soc/samsung/speyside_wm8962.c
+++ b/sound/soc/samsung/speyside_wm8962.c
@@ -31,13 +31,13 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
31 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 31 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
32 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 32 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
33 WM8962_FLL_MCLK, 32768, 33 WM8962_FLL_MCLK, 32768,
34 44100 * 256); 34 44100 * 512);
35 if (ret < 0) 35 if (ret < 0)
36 pr_err("Failed to start FLL: %d\n", ret); 36 pr_err("Failed to start FLL: %d\n", ret);
37 37
38 ret = snd_soc_dai_set_sysclk(codec_dai, 38 ret = snd_soc_dai_set_sysclk(codec_dai,
39 WM8962_SYSCLK_FLL, 39 WM8962_SYSCLK_FLL,
40 44100 * 256, 40 44100 * 512,
41 SND_SOC_CLOCK_IN); 41 SND_SOC_CLOCK_IN);
42 if (ret < 0) { 42 if (ret < 0) {
43 pr_err("Failed to set SYSCLK: %d\n", ret); 43 pr_err("Failed to set SYSCLK: %d\n", ret);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 20b7f3b003a..143c705ac27 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -548,9 +548,6 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
548 548
549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 549static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
550{ 550{
551 const struct snd_soc_codec_driver *codec_drv;
552
553 codec_drv = codec->driver;
554 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); 551 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
555} 552}
556 553
@@ -868,10 +865,6 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
868 865
869static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 866static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
870{ 867{
871 const struct snd_soc_codec_driver *codec_drv;
872
873 codec_drv = codec->driver;
874
875 if (codec->reg_def_copy) 868 if (codec->reg_def_copy)
876 codec->reg_cache = kmemdup(codec->reg_def_copy, 869 codec->reg_cache = kmemdup(codec->reg_def_copy,
877 codec->reg_size, GFP_KERNEL); 870 codec->reg_size, GFP_KERNEL);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d2ef014af21..10e5cdeeb18 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -105,7 +105,7 @@ static int format_register_str(struct snd_soc_codec *codec,
105 if (wordsize + regsize + 2 + 1 != len) 105 if (wordsize + regsize + 2 + 1 != len)
106 return -EINVAL; 106 return -EINVAL;
107 107
108 ret = snd_soc_read(codec , reg); 108 ret = snd_soc_read(codec, reg);
109 if (ret < 0) { 109 if (ret < 0) {
110 memset(regbuf, 'X', regsize); 110 memset(regbuf, 'X', regsize);
111 regbuf[regsize] = '\0'; 111 regbuf[regsize] = '\0';
@@ -143,7 +143,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
143 step = codec->driver->reg_cache_step; 143 step = codec->driver->reg_cache_step;
144 144
145 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 145 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
146 if (codec->readable_register && !codec->readable_register(codec, i)) 146 if (!snd_soc_codec_readable_register(codec, i))
147 continue; 147 continue;
148 if (codec->driver->display_register) { 148 if (codec->driver->display_register) {
149 count += codec->driver->display_register(codec, buf + count, 149 count += codec->driver->display_register(codec, buf + count,
@@ -244,7 +244,6 @@ static ssize_t codec_reg_write_file(struct file *file,
244 size_t buf_size; 244 size_t buf_size;
245 char *start = buf; 245 char *start = buf;
246 unsigned long reg, value; 246 unsigned long reg, value;
247 int step = 1;
248 struct snd_soc_codec *codec = file->private_data; 247 struct snd_soc_codec *codec = file->private_data;
249 248
250 buf_size = min(count, (sizeof(buf)-1)); 249 buf_size = min(count, (sizeof(buf)-1));
@@ -252,9 +251,6 @@ static ssize_t codec_reg_write_file(struct file *file,
252 return -EFAULT; 251 return -EFAULT;
253 buf[buf_size] = 0; 252 buf[buf_size] = 0;
254 253
255 if (codec->driver->reg_cache_step)
256 step = codec->driver->reg_cache_step;
257
258 while (*start == ' ') 254 while (*start == ' ')
259 start++; 255 start++;
260 reg = simple_strtoul(start, &start, 16); 256 reg = simple_strtoul(start, &start, 16);
@@ -956,6 +952,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
956 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 952 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
957 driver->num_dapm_widgets); 953 driver->num_dapm_widgets);
958 954
955 codec->dapm.idle_bias_off = driver->idle_bias_off;
956
959 if (driver->probe) { 957 if (driver->probe) {
960 ret = driver->probe(codec); 958 ret = driver->probe(codec);
961 if (ret < 0) { 959 if (ret < 0) {
@@ -2668,7 +2666,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2668 if (dai->driver && dai->driver->ops->set_sysclk) 2666 if (dai->driver && dai->driver->ops->set_sysclk)
2669 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 2667 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
2670 else if (dai->codec && dai->codec->driver->set_sysclk) 2668 else if (dai->codec && dai->codec->driver->set_sysclk)
2671 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 2669 return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0,
2672 freq, dir); 2670 freq, dir);
2673 else 2671 else
2674 return -EINVAL; 2672 return -EINVAL;
@@ -2679,16 +2677,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2679 * snd_soc_codec_set_sysclk - configure CODEC system or master clock. 2677 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
2680 * @codec: CODEC 2678 * @codec: CODEC
2681 * @clk_id: DAI specific clock ID 2679 * @clk_id: DAI specific clock ID
2680 * @source: Source for the clock
2682 * @freq: new clock frequency in Hz 2681 * @freq: new clock frequency in Hz
2683 * @dir: new clock direction - input/output. 2682 * @dir: new clock direction - input/output.
2684 * 2683 *
2685 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. 2684 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
2686 */ 2685 */
2687int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 2686int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
2688 unsigned int freq, int dir) 2687 int source, unsigned int freq, int dir)
2689{ 2688{
2690 if (codec->driver->set_sysclk) 2689 if (codec->driver->set_sysclk)
2691 return codec->driver->set_sysclk(codec, clk_id, freq, dir); 2690 return codec->driver->set_sysclk(codec, clk_id, source,
2691 freq, dir);
2692 else 2692 else
2693 return -EINVAL; 2693 return -EINVAL;
2694} 2694}
@@ -3141,6 +3141,7 @@ int snd_soc_register_platform(struct device *dev,
3141 platform->driver = platform_drv; 3141 platform->driver = platform_drv;
3142 platform->dapm.dev = dev; 3142 platform->dapm.dev = dev;
3143 platform->dapm.platform = platform; 3143 platform->dapm.platform = platform;
3144 platform->dapm.stream_event = platform_drv->stream_event;
3144 3145
3145 mutex_lock(&client_mutex); 3146 mutex_lock(&client_mutex);
3146 list_add(&platform->list, &platform_list); 3147 list_add(&platform->list, &platform_list);
@@ -3253,6 +3254,7 @@ int snd_soc_register_codec(struct device *dev,
3253 codec->dapm.dev = dev; 3254 codec->dapm.dev = dev;
3254 codec->dapm.codec = codec; 3255 codec->dapm.codec = codec;
3255 codec->dapm.seq_notifier = codec_drv->seq_notifier; 3256 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3257 codec->dapm.stream_event = codec_drv->stream_event;
3256 codec->dev = dev; 3258 codec->dev = dev;
3257 codec->driver = codec_drv; 3259 codec->driver = codec_drv;
3258 codec->num_dai = num_dai; 3260 codec->num_dai = num_dai;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d67c637557a..4a440b52dd7 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -443,6 +443,11 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
443 if (path->name != (char *)w->kcontrol_news[i].name) 443 if (path->name != (char *)w->kcontrol_news[i].name)
444 continue; 444 continue;
445 445
446 if (w->kcontrols[i]) {
447 path->kcontrol = w->kcontrols[i];
448 continue;
449 }
450
446 wlistsize = sizeof(struct snd_soc_dapm_widget_list) + 451 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
447 sizeof(struct snd_soc_dapm_widget *), 452 sizeof(struct snd_soc_dapm_widget *),
448 wlist = kzalloc(wlistsize, GFP_KERNEL); 453 wlist = kzalloc(wlistsize, GFP_KERNEL);
@@ -579,8 +584,8 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
579 name + prefix_len, prefix); 584 name + prefix_len, prefix);
580 ret = snd_ctl_add(card, kcontrol); 585 ret = snd_ctl_add(card, kcontrol);
581 if (ret < 0) { 586 if (ret < 0) {
582 dev_err(dapm->dev, 587 dev_err(dapm->dev, "failed to add kcontrol %s: %d\n",
583 "asoc: failed to add kcontrol %s\n", w->name); 588 w->name, ret);
584 kfree(wlist); 589 kfree(wlist);
585 return ret; 590 return ret;
586 } 591 }
@@ -1556,7 +1561,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1556 /* found, now check type */ 1561 /* found, now check type */
1557 found = 1; 1562 found = 1;
1558 path->connect = connect; 1563 path->connect = connect;
1559 break;
1560 } 1564 }
1561 1565
1562 if (found) 1566 if (found)
@@ -2584,7 +2588,7 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2584 { 2588 {
2585 if (!w->sname || w->dapm != dapm) 2589 if (!w->sname || w->dapm != dapm)
2586 continue; 2590 continue;
2587 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2591 dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2588 w->name, w->sname, stream, event); 2592 w->name, w->sname, stream, event);
2589 if (strstr(w->sname, stream)) { 2593 if (strstr(w->sname, stream)) {
2590 switch(event) { 2594 switch(event) {
@@ -2604,6 +2608,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2604 } 2608 }
2605 2609
2606 dapm_power_widgets(dapm, event); 2610 dapm_power_widgets(dapm, event);
2611
2612 /* do we need to notify any clients that DAPM stream is complete */
2613 if (dapm->stream_event)
2614 dapm->stream_event(dapm, event);
2607} 2615}
2608 2616
2609/** 2617/**
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index a62f7dd4ba9..66fcccd79ef 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -13,26 +13,14 @@
13 13
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/regmap.h>
16#include <sound/soc.h> 17#include <sound/soc.h>
17 18
18#include <trace/events/asoc.h> 19#include <trace/events/asoc.h>
19 20
20#ifdef CONFIG_SPI_MASTER 21#ifdef CONFIG_REGMAP
21static int do_spi_write(void *control, const char *data, int len) 22static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
22{ 23 unsigned int value)
23 struct spi_device *spi = control;
24 int ret;
25
26 ret = spi_write(spi, data, len);
27 if (ret < 0)
28 return ret;
29
30 return len;
31}
32#endif
33
34static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
35 unsigned int value, const void *data, int len)
36{ 24{
37 int ret; 25 int ret;
38 26
@@ -49,13 +37,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
49 return 0; 37 return 0;
50 } 38 }
51 39
52 ret = codec->hw_write(codec->control_data, data, len); 40 return regmap_write(codec->control_data, reg, value);
53 if (ret == len)
54 return 0;
55 if (ret < 0)
56 return ret;
57 else
58 return -EIO;
59} 41}
60 42
61static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) 43static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
@@ -69,8 +51,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
69 if (codec->cache_only) 51 if (codec->cache_only)
70 return -1; 52 return -1;
71 53
72 BUG_ON(!codec->hw_read); 54 ret = regmap_read(codec->control_data, reg, &val);
73 return codec->hw_read(codec, reg); 55 if (ret == 0)
56 return val;
57 else
58 return ret;
74 } 59 }
75 60
76 ret = snd_soc_cache_read(codec, reg, &val); 61 ret = snd_soc_cache_read(codec, reg, &val);
@@ -79,202 +64,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
79 return val; 64 return val;
80} 65}
81 66
82static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u16 data;
86
87 data = cpu_to_be16((reg << 12) | (value & 0xffffff));
88
89 return do_hw_write(codec, reg, value, &data, 2);
90}
91
92static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 u16 data;
96
97 data = cpu_to_be16((reg << 9) | (value & 0x1ff));
98
99 return do_hw_write(codec, reg, value, &data, 2);
100}
101
102static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
103 unsigned int value)
104{
105 u8 data[2];
106
107 reg &= 0xff;
108 data[0] = reg;
109 data[1] = value & 0xff;
110
111 return do_hw_write(codec, reg, value, data, 2);
112}
113
114static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
115 unsigned int value)
116{
117 u8 data[3];
118 u16 val = cpu_to_be16(value);
119
120 data[0] = reg;
121 memcpy(&data[1], &val, sizeof(val));
122
123 return do_hw_write(codec, reg, value, data, 3);
124}
125
126#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
127static unsigned int do_i2c_read(struct snd_soc_codec *codec,
128 void *reg, int reglen,
129 void *data, int datalen)
130{
131 struct i2c_msg xfer[2];
132 int ret;
133 struct i2c_client *client = codec->control_data;
134
135 /* Write register */
136 xfer[0].addr = client->addr;
137 xfer[0].flags = 0;
138 xfer[0].len = reglen;
139 xfer[0].buf = reg;
140
141 /* Read data */
142 xfer[1].addr = client->addr;
143 xfer[1].flags = I2C_M_RD;
144 xfer[1].len = datalen;
145 xfer[1].buf = data;
146
147 ret = i2c_transfer(client->adapter, xfer, 2);
148 if (ret == 2)
149 return 0;
150 else if (ret < 0)
151 return ret;
152 else
153 return -EIO;
154}
155#endif
156
157#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
158static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
159 unsigned int r)
160{
161 u8 reg = r;
162 u8 data;
163 int ret;
164
165 ret = do_i2c_read(codec, &reg, 1, &data, 1);
166 if (ret < 0)
167 return 0;
168 return data;
169}
170#else
171#define snd_soc_8_8_read_i2c NULL
172#endif
173
174#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
175static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
176 unsigned int r)
177{
178 u8 reg = r;
179 u16 data;
180 int ret;
181
182 ret = do_i2c_read(codec, &reg, 1, &data, 2);
183 if (ret < 0)
184 return 0;
185 return (data >> 8) | ((data & 0xff) << 8);
186}
187#else
188#define snd_soc_8_16_read_i2c NULL
189#endif
190
191#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
192static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
193 unsigned int r)
194{
195 u16 reg = r;
196 u8 data;
197 int ret;
198
199 ret = do_i2c_read(codec, &reg, 2, &data, 1);
200 if (ret < 0)
201 return 0;
202 return data;
203}
204#else
205#define snd_soc_16_8_read_i2c NULL
206#endif
207
208#if defined(CONFIG_SPI_MASTER)
209static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
210 unsigned int r)
211{
212 struct spi_device *spi = codec->control_data;
213
214 const u16 reg = cpu_to_be16(r | 0x100);
215 u8 data;
216 int ret;
217
218 ret = spi_write_then_read(spi, &reg, 2, &data, 1);
219 if (ret < 0)
220 return 0;
221 return data;
222}
223#else
224#define snd_soc_16_8_read_spi NULL
225#endif
226
227static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
228 unsigned int value)
229{
230 u8 data[3];
231 u16 rval = cpu_to_be16(reg);
232
233 memcpy(data, &rval, sizeof(rval));
234 data[2] = value;
235
236 return do_hw_write(codec, reg, value, data, 3);
237}
238
239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
240static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
241 unsigned int r)
242{
243 u16 reg = cpu_to_be16(r);
244 u16 data;
245 int ret;
246
247 ret = do_i2c_read(codec, &reg, 2, &data, 2);
248 if (ret < 0)
249 return 0;
250 return be16_to_cpu(data);
251}
252#else
253#define snd_soc_16_16_read_i2c NULL
254#endif
255
256static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
257 unsigned int value)
258{
259 u16 data[2];
260
261 data[0] = cpu_to_be16(reg);
262 data[1] = cpu_to_be16(value);
263
264 return do_hw_write(codec, reg, value, data, sizeof(data));
265}
266
267/* Primitive bulk write support for soc-cache. The data pointed to by 67/* Primitive bulk write support for soc-cache. The data pointed to by
268 * `data' needs to already be in the form the hardware expects 68 * `data' needs to already be in the form the hardware expects. Any
269 * including any leading register specific data. Any data written 69 * data written through this function will not go through the cache as
270 * through this function will not go through the cache as it only 70 * it only handles writing to volatile or out of bounds registers.
271 * handles writing to volatile or out of bounds registers. 71 *
72 * This is currently only supported for devices using the regmap API
73 * wrappers.
272 */ 74 */
273static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, 75static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
76 unsigned int reg,
274 const void *data, size_t len) 77 const void *data, size_t len)
275{ 78{
276 int ret;
277
278 /* To ensure that we don't get out of sync with the cache, check 79 /* To ensure that we don't get out of sync with the cache, check
279 * whether the base register is volatile or if we've directly asked 80 * whether the base register is volatile or if we've directly asked
280 * to bypass the cache. Out of bounds registers are considered 81 * to bypass the cache. Out of bounds registers are considered
@@ -285,68 +86,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r
285 && reg < codec->driver->reg_cache_size) 86 && reg < codec->driver->reg_cache_size)
286 return -EINVAL; 87 return -EINVAL;
287 88
288 switch (codec->control_type) { 89 return regmap_raw_write(codec->control_data, reg, data, len);
289#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
290 case SND_SOC_I2C:
291 ret = i2c_master_send(to_i2c_client(codec->dev), data, len);
292 break;
293#endif
294#if defined(CONFIG_SPI_MASTER)
295 case SND_SOC_SPI:
296 ret = spi_write(to_spi_device(codec->dev), data, len);
297 break;
298#endif
299 default:
300 BUG();
301 }
302
303 if (ret == len)
304 return 0;
305 if (ret < 0)
306 return ret;
307 else
308 return -EIO;
309} 90}
310 91
311static struct {
312 int addr_bits;
313 int data_bits;
314 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
315 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
316 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
317 unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
318} io_types[] = {
319 {
320 .addr_bits = 4, .data_bits = 12,
321 .write = snd_soc_4_12_write,
322 },
323 {
324 .addr_bits = 7, .data_bits = 9,
325 .write = snd_soc_7_9_write,
326 },
327 {
328 .addr_bits = 8, .data_bits = 8,
329 .write = snd_soc_8_8_write,
330 .i2c_read = snd_soc_8_8_read_i2c,
331 },
332 {
333 .addr_bits = 8, .data_bits = 16,
334 .write = snd_soc_8_16_write,
335 .i2c_read = snd_soc_8_16_read_i2c,
336 },
337 {
338 .addr_bits = 16, .data_bits = 8,
339 .write = snd_soc_16_8_write,
340 .i2c_read = snd_soc_16_8_read_i2c,
341 .spi_read = snd_soc_16_8_read_spi,
342 },
343 {
344 .addr_bits = 16, .data_bits = 16,
345 .write = snd_soc_16_16_write,
346 .i2c_read = snd_soc_16_16_read_i2c,
347 },
348};
349
350/** 92/**
351 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 93 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
352 * 94 *
@@ -370,50 +112,51 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
370 int addr_bits, int data_bits, 112 int addr_bits, int data_bits,
371 enum snd_soc_control_type control) 113 enum snd_soc_control_type control)
372{ 114{
373 int i; 115 struct regmap_config config;
374
375 for (i = 0; i < ARRAY_SIZE(io_types); i++)
376 if (io_types[i].addr_bits == addr_bits &&
377 io_types[i].data_bits == data_bits)
378 break;
379 if (i == ARRAY_SIZE(io_types)) {
380 printk(KERN_ERR
381 "No I/O functions for %d bit address %d bit data\n",
382 addr_bits, data_bits);
383 return -EINVAL;
384 }
385 116
386 codec->write = io_types[i].write; 117 memset(&config, 0, sizeof(config));
118 codec->write = hw_write;
387 codec->read = hw_read; 119 codec->read = hw_read;
388 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; 120 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
389 121
122 config.reg_bits = addr_bits;
123 config.val_bits = data_bits;
124
390 switch (control) { 125 switch (control) {
126#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
391 case SND_SOC_I2C: 127 case SND_SOC_I2C:
392#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 128 codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
393 codec->hw_write = (hw_write_t)i2c_master_send; 129 &config);
394#endif
395 if (io_types[i].i2c_read)
396 codec->hw_read = io_types[i].i2c_read;
397
398 codec->control_data = container_of(codec->dev,
399 struct i2c_client,
400 dev);
401 break; 130 break;
131#endif
402 132
133#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
403 case SND_SOC_SPI: 134 case SND_SOC_SPI:
404#ifdef CONFIG_SPI_MASTER 135 codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
405 codec->hw_write = do_spi_write; 136 &config);
137 break;
406#endif 138#endif
407 if (io_types[i].spi_read)
408 codec->hw_read = io_types[i].spi_read;
409 139
410 codec->control_data = container_of(codec->dev, 140 case SND_SOC_REGMAP:
411 struct spi_device, 141 /* Device has made its own regmap arrangements */
412 dev);
413 break; 142 break;
143
144 default:
145 return -EINVAL;
414 } 146 }
415 147
148 if (IS_ERR(codec->control_data))
149 return PTR_ERR(codec->control_data);
150
416 return 0; 151 return 0;
417} 152}
418EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 153EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
419 154#else
155int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
156 int addr_bits, int data_bits,
157 enum snd_soc_control_type control)
158{
159 return -ENOTSUPP;
160}
161EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
162#endif
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 2879c883eeb..1aee9fcdf65 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -27,8 +27,6 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29 29
30static DEFINE_MUTEX(pcm_mutex);
31
32static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) 30static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
33{ 31{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 32 struct snd_soc_pcm_runtime *rtd = substream->private_data;