aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c2
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ak4642.c24
-rw-r--r--sound/soc/codecs/cq93vc.c2
-rw-r--r--sound/soc/codecs/cs4271.c659
-rw-r--r--sound/soc/codecs/cx20442.c3
-rw-r--r--sound/soc/codecs/sn95031.c281
-rw-r--r--sound/soc/codecs/wm8903.c127
-rw-r--r--sound/soc/codecs/wm8962.c2
-rw-r--r--sound/soc/codecs/wm8994.c2
-rw-r--r--sound/soc/codecs/wm8995.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c15
-rw-r--r--sound/soc/davinci/davinci-evm.c2
-rw-r--r--sound/soc/ep93xx/Kconfig9
-rw-r--r--sound/soc/ep93xx/Makefile2
-rw-r--r--sound/soc/ep93xx/edb93xx.c142
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/fsl/p1022_ds.c6
-rw-r--r--sound/soc/mid-x86/mfld_machine.c3
-rw-r--r--sound/soc/mid-x86/sst_platform.c6
-rw-r--r--sound/soc/omap/ams-delta.c2
-rw-r--r--sound/soc/pxa/corgi.c4
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/raumfeld.c4
-rw-r--r--sound/soc/pxa/spitz.c4
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/zylonite.c9
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c6
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c7
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c4
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c4
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/sh/fsi-ak4642.c13
-rw-r--r--sound/soc/sh/fsi-da7210.c13
-rw-r--r--sound/soc/sh/fsi-hdmi.c77
-rw-r--r--sound/soc/sh/fsi.c203
-rw-r--r--sound/soc/soc-cache.c50
-rw-r--r--sound/soc/soc-core.c114
-rw-r--r--sound/soc/soc-dapm.c71
-rw-r--r--sound/soc/soc-utils.c23
-rw-r--r--sound/soc/tegra/harmony.c170
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c91
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h20
-rw-r--r--sound/soc/tegra/tegra_i2s.c2
46 files changed, 1870 insertions, 332 deletions
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index da2208e06b0d..5e4d499d8434 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -129,7 +129,7 @@ static struct snd_soc_dai_link afeb9260_dai = {
129 .cpu_dai_name = "atmel-ssc-dai.0", 129 .cpu_dai_name = "atmel-ssc-dai.0",
130 .codec_dai_name = "tlv320aic23-hifi", 130 .codec_dai_name = "tlv320aic23-hifi",
131 .platform_name = "atmel_pcm-audio", 131 .platform_name = "atmel_pcm-audio",
132 .codec_name = "tlv320aic23-codec.0-0x1a", 132 .codec_name = "tlv320aic23-codec.0-001a",
133 .init = afeb9260_tlv320aic23_init, 133 .init = afeb9260_tlv320aic23_init,
134 .ops = &afeb9260_ops, 134 .ops = &afeb9260_ops,
135}; 135};
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index e902b24c1856..ad28663f5bbd 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -119,7 +119,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
119 .cpu_dai_name = "bf5xx-i2s", 119 .cpu_dai_name = "bf5xx-i2s",
120 .codec_dai_name = "ssm2602-hifi", 120 .codec_dai_name = "ssm2602-hifi",
121 .platform_name = "bf5xx-pcm-audio", 121 .platform_name = "bf5xx-pcm-audio",
122 .codec_name = "ssm2602-codec.0-0x1b", 122 .codec_name = "ssm2602-codec.0-001b",
123 .ops = &bf5xx_ssm2602_ops, 123 .ops = &bf5xx_ssm2602_ops,
124}; 124};
125 125
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index a9cb2a04ad56..e239345a4d5d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS
26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
27 select SND_SOC_CS42L51 if I2C 27 select SND_SOC_CS42L51 if I2C
28 select SND_SOC_CS4270 if I2C 28 select SND_SOC_CS4270 if I2C
29 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
29 select SND_SOC_CX20442 30 select SND_SOC_CX20442
30 select SND_SOC_DA7210 if I2C 31 select SND_SOC_DA7210 if I2C
31 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 32 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
@@ -157,6 +158,9 @@ config SND_SOC_CS4270_VD33_ERRATA
157 bool 158 bool
158 depends on SND_SOC_CS4270 159 depends on SND_SOC_CS4270
159 160
161config SND_SOC_CS4271
162 tristate
163
160config SND_SOC_CX20442 164config SND_SOC_CX20442
161 tristate 165 tristate
162 166
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 68e76af894b9..83b7accd7037 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -12,6 +12,7 @@ snd-soc-ak4671-objs := ak4671.o
12snd-soc-cq93vc-objs := cq93vc.o 12snd-soc-cq93vc-objs := cq93vc.o
13snd-soc-cs42l51-objs := cs42l51.o 13snd-soc-cs42l51-objs := cs42l51.o
14snd-soc-cs4270-objs := cs4270.o 14snd-soc-cs4270-objs := cs4270.o
15snd-soc-cs4271-objs := cs4271.o
15snd-soc-cx20442-objs := cx20442.o 16snd-soc-cx20442-objs := cx20442.o
16snd-soc-da7210-objs := da7210.o 17snd-soc-da7210-objs := da7210.o
17snd-soc-dmic-objs := dmic.o 18snd-soc-dmic-objs := dmic.o
@@ -93,6 +94,7 @@ obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
93obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 94obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
94obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 95obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
95obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 96obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
97obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
96obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 98obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
97obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 99obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
98obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 100obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index f00eba313dfd..4be0570e3f1f 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -116,6 +116,12 @@
116#define BCKO_MASK (1 << 3) 116#define BCKO_MASK (1 << 3)
117#define BCKO_64 BCKO_MASK 117#define BCKO_64 BCKO_MASK
118 118
119#define DIF_MASK (3 << 0)
120#define DSP (0 << 0)
121#define RIGHT_J (1 << 0)
122#define LEFT_J (2 << 0)
123#define I2S (3 << 0)
124
119/* MD_CTL2 */ 125/* MD_CTL2 */
120#define FS0 (1 << 0) 126#define FS0 (1 << 0)
121#define FS1 (1 << 1) 127#define FS1 (1 << 1)
@@ -354,6 +360,24 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
354 snd_soc_update_bits(codec, PW_MGMT2, MS, data); 360 snd_soc_update_bits(codec, PW_MGMT2, MS, data);
355 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); 361 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
356 362
363 /* format type */
364 data = 0;
365 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
366 case SND_SOC_DAIFMT_LEFT_J:
367 data = LEFT_J;
368 break;
369 case SND_SOC_DAIFMT_I2S:
370 data = I2S;
371 break;
372 /* FIXME
373 * Please add RIGHT_J / DSP support here
374 */
375 default:
376 return -EINVAL;
377 break;
378 }
379 snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
380
357 return 0; 381 return 0;
358} 382}
359 383
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 46dbfd067f79..347a567b01e1 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -153,7 +153,7 @@ static int cq93vc_resume(struct snd_soc_codec *codec)
153 153
154static int cq93vc_probe(struct snd_soc_codec *codec) 154static int cq93vc_probe(struct snd_soc_codec *codec)
155{ 155{
156 struct davinci_vc *davinci_vc = codec->dev->platform_data; 156 struct davinci_vc *davinci_vc = snd_soc_codec_get_drvdata(codec);
157 157
158 davinci_vc->cq93vc.codec = codec; 158 davinci_vc->cq93vc.codec = codec;
159 codec->control_data = davinci_vc; 159 codec->control_data = davinci_vc;
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
new file mode 100644
index 000000000000..9c5b7db0ce6a
--- /dev/null
+++ b/sound/soc/codecs/cs4271.c
@@ -0,0 +1,659 @@
1/*
2 * CS4271 ASoC codec driver
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/delay.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/tlv.h>
28#include <linux/gpio.h>
29#include <linux/i2c.h>
30#include <linux/spi/spi.h>
31#include <sound/cs4271.h>
32
33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \
35 SNDRV_PCM_FMTBIT_S32_LE)
36
37/*
38 * CS4271 registers
39 * High byte represents SPI chip address (0x10) + write command (0)
40 * Low byte - codec register address
41 */
42#define CS4271_MODE1 0x2001 /* Mode Control 1 */
43#define CS4271_DACCTL 0x2002 /* DAC Control */
44#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */
45#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */
46#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */
47#define CS4271_ADCCTL 0x2006 /* ADC Control */
48#define CS4271_MODE2 0x2007 /* Mode Control 2 */
49#define CS4271_CHIPID 0x2008 /* Chip ID */
50
51#define CS4271_FIRSTREG CS4271_MODE1
52#define CS4271_LASTREG CS4271_MODE2
53#define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
54
55/* Bit masks for the CS4271 registers */
56#define CS4271_MODE1_MODE_MASK 0xC0
57#define CS4271_MODE1_MODE_1X 0x00
58#define CS4271_MODE1_MODE_2X 0x80
59#define CS4271_MODE1_MODE_4X 0xC0
60
61#define CS4271_MODE1_DIV_MASK 0x30
62#define CS4271_MODE1_DIV_1 0x00
63#define CS4271_MODE1_DIV_15 0x10
64#define CS4271_MODE1_DIV_2 0x20
65#define CS4271_MODE1_DIV_3 0x30
66
67#define CS4271_MODE1_MASTER 0x08
68
69#define CS4271_MODE1_DAC_DIF_MASK 0x07
70#define CS4271_MODE1_DAC_DIF_LJ 0x00
71#define CS4271_MODE1_DAC_DIF_I2S 0x01
72#define CS4271_MODE1_DAC_DIF_RJ16 0x02
73#define CS4271_MODE1_DAC_DIF_RJ24 0x03
74#define CS4271_MODE1_DAC_DIF_RJ20 0x04
75#define CS4271_MODE1_DAC_DIF_RJ18 0x05
76
77#define CS4271_DACCTL_AMUTE 0x80
78#define CS4271_DACCTL_IF_SLOW 0x40
79
80#define CS4271_DACCTL_DEM_MASK 0x30
81#define CS4271_DACCTL_DEM_DIS 0x00
82#define CS4271_DACCTL_DEM_441 0x10
83#define CS4271_DACCTL_DEM_48 0x20
84#define CS4271_DACCTL_DEM_32 0x30
85
86#define CS4271_DACCTL_SVRU 0x08
87#define CS4271_DACCTL_SRD 0x04
88#define CS4271_DACCTL_INVA 0x02
89#define CS4271_DACCTL_INVB 0x01
90
91#define CS4271_DACVOL_BEQUA 0x40
92#define CS4271_DACVOL_SOFT 0x20
93#define CS4271_DACVOL_ZEROC 0x10
94
95#define CS4271_DACVOL_ATAPI_MASK 0x0F
96#define CS4271_DACVOL_ATAPI_M_M 0x00
97#define CS4271_DACVOL_ATAPI_M_BR 0x01
98#define CS4271_DACVOL_ATAPI_M_BL 0x02
99#define CS4271_DACVOL_ATAPI_M_BLR2 0x03
100#define CS4271_DACVOL_ATAPI_AR_M 0x04
101#define CS4271_DACVOL_ATAPI_AR_BR 0x05
102#define CS4271_DACVOL_ATAPI_AR_BL 0x06
103#define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
104#define CS4271_DACVOL_ATAPI_AL_M 0x08
105#define CS4271_DACVOL_ATAPI_AL_BR 0x09
106#define CS4271_DACVOL_ATAPI_AL_BL 0x0A
107#define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
108#define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
109#define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
110#define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
111#define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
112
113#define CS4271_VOLA_MUTE 0x80
114#define CS4271_VOLA_VOL_MASK 0x7F
115#define CS4271_VOLB_MUTE 0x80
116#define CS4271_VOLB_VOL_MASK 0x7F
117
118#define CS4271_ADCCTL_DITHER16 0x20
119
120#define CS4271_ADCCTL_ADC_DIF_MASK 0x10
121#define CS4271_ADCCTL_ADC_DIF_LJ 0x00
122#define CS4271_ADCCTL_ADC_DIF_I2S 0x10
123
124#define CS4271_ADCCTL_MUTEA 0x08
125#define CS4271_ADCCTL_MUTEB 0x04
126#define CS4271_ADCCTL_HPFDA 0x02
127#define CS4271_ADCCTL_HPFDB 0x01
128
129#define CS4271_MODE2_LOOP 0x10
130#define CS4271_MODE2_MUTECAEQUB 0x08
131#define CS4271_MODE2_FREEZE 0x04
132#define CS4271_MODE2_CPEN 0x02
133#define CS4271_MODE2_PDN 0x01
134
135#define CS4271_CHIPID_PART_MASK 0xF0
136#define CS4271_CHIPID_REV_MASK 0x0F
137
138/*
139 * Default CS4271 power-up configuration
140 * Array contains non-existing in hw register at address 0
141 * Array do not include Chip ID, as codec driver does not use
142 * registers read operations at all
143 */
144static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
145 0,
146 0,
147 CS4271_DACCTL_AMUTE,
148 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR,
149 0,
150 0,
151 0,
152 0,
153};
154
155struct cs4271_private {
156 /* SND_SOC_I2C or SND_SOC_SPI */
157 enum snd_soc_control_type bus_type;
158 void *control_data;
159 unsigned int mclk;
160 bool master;
161 bool deemph;
162 /* Current sample rate for de-emphasis control */
163 int rate;
164 /* GPIO driving Reset pin, if any */
165 int gpio_nreset;
166 /* GPIO that disable serial bus, if any */
167 int gpio_disable;
168};
169
170struct cs4271_clk_cfg {
171 unsigned int ratio; /* MCLK / sample rate */
172 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
173 u8 mclk_master; /* ratio bit mask for Master mode */
174 u8 mclk_slave; /* ratio bit mask for Slave mode */
175};
176
177static struct cs4271_clk_cfg cs4271_clk_tab[] = {
178 {64, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
179 {96, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
180 {128, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
181 {192, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
182 {256, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
183 {384, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
184 {512, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_2, CS4271_MODE1_DIV_1},
185 {768, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3},
186 {1024, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3}
187};
188
189#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
190
191/*
192 * @freq is the desired MCLK rate
193 * MCLK rate should (c) be the sample rate, multiplied by one of the
194 * ratios listed in cs4271_mclk_fs_ratios table
195 */
196static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir)
198{
199 struct snd_soc_codec *codec = codec_dai->codec;
200 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
201
202 cs4271->mclk = freq;
203 return 0;
204}
205
206static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
207 unsigned int format)
208{
209 struct snd_soc_codec *codec = codec_dai->codec;
210 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
211 unsigned int val = 0;
212 int ret;
213
214 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
215 case SND_SOC_DAIFMT_CBS_CFS:
216 cs4271->master = 0;
217 break;
218 case SND_SOC_DAIFMT_CBM_CFM:
219 cs4271->master = 1;
220 val |= CS4271_MODE1_MASTER;
221 break;
222 default:
223 dev_err(codec->dev, "Invalid DAI format\n");
224 return -EINVAL;
225 }
226
227 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
228 case SND_SOC_DAIFMT_LEFT_J:
229 val |= CS4271_MODE1_DAC_DIF_LJ;
230 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
231 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
232 if (ret < 0)
233 return ret;
234 break;
235 case SND_SOC_DAIFMT_I2S:
236 val |= CS4271_MODE1_DAC_DIF_I2S;
237 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
238 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
239 if (ret < 0)
240 return ret;
241 break;
242 default:
243 dev_err(codec->dev, "Invalid DAI format\n");
244 return -EINVAL;
245 }
246
247 ret = snd_soc_update_bits(codec, CS4271_MODE1,
248 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
249 if (ret < 0)
250 return ret;
251 return 0;
252}
253
254static int cs4271_deemph[] = {0, 44100, 48000, 32000};
255
256static int cs4271_set_deemph(struct snd_soc_codec *codec)
257{
258 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
259 int i, ret;
260 int val = CS4271_DACCTL_DEM_DIS;
261
262 if (cs4271->deemph) {
263 /* Find closest de-emphasis freq */
264 val = 1;
265 for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
266 if (abs(cs4271_deemph[i] - cs4271->rate) <
267 abs(cs4271_deemph[val] - cs4271->rate))
268 val = i;
269 val <<= 4;
270 }
271
272 ret = snd_soc_update_bits(codec, CS4271_DACCTL,
273 CS4271_DACCTL_DEM_MASK, val);
274 if (ret < 0)
275 return ret;
276 return 0;
277}
278
279static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
283 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
284
285 ucontrol->value.enumerated.item[0] = cs4271->deemph;
286 return 0;
287}
288
289static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
290 struct snd_ctl_elem_value *ucontrol)
291{
292 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
293 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
294
295 cs4271->deemph = ucontrol->value.enumerated.item[0];
296 return cs4271_set_deemph(codec);
297}
298
299static int cs4271_hw_params(struct snd_pcm_substream *substream,
300 struct snd_pcm_hw_params *params,
301 struct snd_soc_dai *dai)
302{
303 struct snd_soc_pcm_runtime *rtd = substream->private_data;
304 struct snd_soc_codec *codec = rtd->codec;
305 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
306 int i, ret;
307 unsigned int ratio, val;
308
309 cs4271->rate = params_rate(params);
310 ratio = cs4271->mclk / cs4271->rate;
311 for (i = 0; i < CS4171_NR_RATIOS; i++)
312 if (cs4271_clk_tab[i].ratio == ratio)
313 break;
314
315 if ((i == CS4171_NR_RATIOS) || ((ratio == 1024) && cs4271->master)) {
316 dev_err(codec->dev, "Invalid sample rate\n");
317 return -EINVAL;
318 }
319
320 /* Configure DAC */
321 val = cs4271_clk_tab[i].speed_mode;
322
323 if (cs4271->master)
324 val |= cs4271_clk_tab[i].mclk_master;
325 else
326 val |= cs4271_clk_tab[i].mclk_slave;
327
328 ret = snd_soc_update_bits(codec, CS4271_MODE1,
329 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
330 if (ret < 0)
331 return ret;
332
333 return cs4271_set_deemph(codec);
334}
335
336static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
337{
338 struct snd_soc_codec *codec = dai->codec;
339 int ret;
340 int val_a = 0;
341 int val_b = 0;
342
343 if (mute) {
344 val_a = CS4271_VOLA_MUTE;
345 val_b = CS4271_VOLB_MUTE;
346 }
347
348 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a);
349 if (ret < 0)
350 return ret;
351 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b);
352 if (ret < 0)
353 return ret;
354
355 return 0;
356}
357
358/* CS4271 controls */
359static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
360
361static const struct snd_kcontrol_new cs4271_snd_controls[] = {
362 SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
363 0, 0x7F, 1, cs4271_dac_tlv),
364 SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
365 SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
366 SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
367 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
368 cs4271_get_deemph, cs4271_put_deemph),
369 SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
370 SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
371 SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
372 SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
373 SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
374 SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
375 SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
376 SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
377 SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
378 SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
379 7, 1, 1),
380};
381
382static struct snd_soc_dai_ops cs4271_dai_ops = {
383 .hw_params = cs4271_hw_params,
384 .set_sysclk = cs4271_set_dai_sysclk,
385 .set_fmt = cs4271_set_dai_fmt,
386 .digital_mute = cs4271_digital_mute,
387};
388
389static struct snd_soc_dai_driver cs4271_dai = {
390 .name = "cs4271-hifi",
391 .playback = {
392 .stream_name = "Playback",
393 .channels_min = 2,
394 .channels_max = 2,
395 .rates = SNDRV_PCM_RATE_8000_96000,
396 .formats = CS4271_PCM_FORMATS,
397 },
398 .capture = {
399 .stream_name = "Capture",
400 .channels_min = 2,
401 .channels_max = 2,
402 .rates = SNDRV_PCM_RATE_8000_96000,
403 .formats = CS4271_PCM_FORMATS,
404 },
405 .ops = &cs4271_dai_ops,
406 .symmetric_rates = 1,
407};
408
409#ifdef CONFIG_PM
410static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
411{
412 int ret;
413 /* Set power-down bit */
414 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
415 if (ret < 0)
416 return ret;
417 return 0;
418}
419
420static int cs4271_soc_resume(struct snd_soc_codec *codec)
421{
422 int ret;
423 /* Restore codec state */
424 ret = snd_soc_cache_sync(codec);
425 if (ret < 0)
426 return ret;
427 /* then disable the power-down bit */
428 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
429 if (ret < 0)
430 return ret;
431 return 0;
432}
433#else
434#define cs4271_soc_suspend NULL
435#define cs4271_soc_resume NULL
436#endif /* CONFIG_PM */
437
438static int cs4271_probe(struct snd_soc_codec *codec)
439{
440 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
441 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
442 int ret;
443 int gpio_nreset = -EINVAL;
444 int gpio_disable = -EINVAL;
445
446 codec->control_data = cs4271->control_data;
447
448 if (cs4271plat) {
449 if (gpio_is_valid(cs4271plat->gpio_nreset))
450 gpio_nreset = cs4271plat->gpio_nreset;
451 if (gpio_is_valid(cs4271plat->gpio_disable))
452 gpio_disable = cs4271plat->gpio_disable;
453 }
454
455 if (gpio_disable >= 0)
456 if (gpio_request(gpio_disable, "CS4271 Disable"))
457 gpio_disable = -EINVAL;
458 if (gpio_disable >= 0)
459 gpio_direction_output(gpio_disable, 0);
460
461 if (gpio_nreset >= 0)
462 if (gpio_request(gpio_nreset, "CS4271 Reset"))
463 gpio_nreset = -EINVAL;
464 if (gpio_nreset >= 0) {
465 /* Reset codec */
466 gpio_direction_output(gpio_nreset, 0);
467 udelay(1);
468 gpio_set_value(gpio_nreset, 1);
469 /* Give the codec time to wake up */
470 udelay(1);
471 }
472
473 cs4271->gpio_nreset = gpio_nreset;
474 cs4271->gpio_disable = gpio_disable;
475
476 /*
477 * In case of I2C, chip address specified in board data.
478 * So cache IO operations use 8 bit codec register address.
479 * In case of SPI, chip address and register address
480 * passed together as 16 bit value.
481 * Anyway, register address is masked with 0xFF inside
482 * soc-cache code.
483 */
484 if (cs4271->bus_type == SND_SOC_SPI)
485 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
486 cs4271->bus_type);
487 else
488 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
489 cs4271->bus_type);
490 if (ret) {
491 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
492 return ret;
493 }
494
495 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
496 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
497 if (ret < 0)
498 return ret;
499 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
500 if (ret < 0)
501 return ret;
502 /* Power-up sequence requires 85 uS */
503 udelay(85);
504
505 return snd_soc_add_controls(codec, cs4271_snd_controls,
506 ARRAY_SIZE(cs4271_snd_controls));
507}
508
509static int cs4271_remove(struct snd_soc_codec *codec)
510{
511 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
512 int gpio_nreset, gpio_disable;
513
514 gpio_nreset = cs4271->gpio_nreset;
515 gpio_disable = cs4271->gpio_disable;
516
517 if (gpio_is_valid(gpio_nreset)) {
518 /* Set codec to the reset state */
519 gpio_set_value(gpio_nreset, 0);
520 gpio_free(gpio_nreset);
521 }
522
523 if (gpio_is_valid(gpio_disable))
524 gpio_free(gpio_disable);
525
526 return 0;
527};
528
529static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
530 .probe = cs4271_probe,
531 .remove = cs4271_remove,
532 .suspend = cs4271_soc_suspend,
533 .resume = cs4271_soc_resume,
534 .reg_cache_default = cs4271_dflt_reg,
535 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
536 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
537 .compress_type = SND_SOC_FLAT_COMPRESSION,
538};
539
540#if defined(CONFIG_SPI_MASTER)
541static int __devinit cs4271_spi_probe(struct spi_device *spi)
542{
543 struct cs4271_private *cs4271;
544
545 cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
546 if (!cs4271)
547 return -ENOMEM;
548
549 spi_set_drvdata(spi, cs4271);
550 cs4271->control_data = spi;
551 cs4271->bus_type = SND_SOC_SPI;
552
553 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
554 &cs4271_dai, 1);
555}
556
557static int __devexit cs4271_spi_remove(struct spi_device *spi)
558{
559 snd_soc_unregister_codec(&spi->dev);
560 return 0;
561}
562
563static struct spi_driver cs4271_spi_driver = {
564 .driver = {
565 .name = "cs4271",
566 .owner = THIS_MODULE,
567 },
568 .probe = cs4271_spi_probe,
569 .remove = __devexit_p(cs4271_spi_remove),
570};
571#endif /* defined(CONFIG_SPI_MASTER) */
572
573#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
574static struct i2c_device_id cs4271_i2c_id[] = {
575 {"cs4271", 0},
576 {}
577};
578MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
579
580static int __devinit cs4271_i2c_probe(struct i2c_client *client,
581 const struct i2c_device_id *id)
582{
583 struct cs4271_private *cs4271;
584
585 cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
586 if (!cs4271)
587 return -ENOMEM;
588
589 i2c_set_clientdata(client, cs4271);
590 cs4271->control_data = client;
591 cs4271->bus_type = SND_SOC_I2C;
592
593 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
594 &cs4271_dai, 1);
595}
596
597static int __devexit cs4271_i2c_remove(struct i2c_client *client)
598{
599 snd_soc_unregister_codec(&client->dev);
600 return 0;
601}
602
603static struct i2c_driver cs4271_i2c_driver = {
604 .driver = {
605 .name = "cs4271",
606 .owner = THIS_MODULE,
607 },
608 .id_table = cs4271_i2c_id,
609 .probe = cs4271_i2c_probe,
610 .remove = __devexit_p(cs4271_i2c_remove),
611};
612#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
613
614/*
615 * We only register our serial bus driver here without
616 * assignment to particular chip. So if any of the below
617 * fails, there is some problem with I2C or SPI subsystem.
618 * In most cases this module will be compiled with support
619 * of only one serial bus.
620 */
621static int __init cs4271_modinit(void)
622{
623 int ret;
624
625#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
626 ret = i2c_add_driver(&cs4271_i2c_driver);
627 if (ret) {
628 pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
629 return ret;
630 }
631#endif
632
633#if defined(CONFIG_SPI_MASTER)
634 ret = spi_register_driver(&cs4271_spi_driver);
635 if (ret) {
636 pr_err("Failed to register CS4271 SPI driver: %d\n", ret);
637 return ret;
638 }
639#endif
640
641 return 0;
642}
643module_init(cs4271_modinit);
644
645static void __exit cs4271_modexit(void)
646{
647#if defined(CONFIG_SPI_MASTER)
648 spi_unregister_driver(&cs4271_spi_driver);
649#endif
650
651#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
652 i2c_del_driver(&cs4271_i2c_driver);
653#endif
654}
655module_exit(cs4271_modexit);
656
657MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
658MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
659MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 03d1e860d229..bb4bf65b9e7e 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -367,9 +367,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
367 return 0; 367 return 0;
368} 368}
369 369
370static const u8 cx20442_reg = CX20442_TELOUT | CX20442_MIC;
371
370static struct snd_soc_codec_driver cx20442_codec_dev = { 372static struct snd_soc_codec_driver cx20442_codec_dev = {
371 .probe = cx20442_codec_probe, 373 .probe = cx20442_codec_probe,
372 .remove = cx20442_codec_remove, 374 .remove = cx20442_codec_remove,
375 .reg_cache_default = &cx20442_reg,
373 .reg_cache_size = 1, 376 .reg_cache_size = 1,
374 .reg_word_size = sizeof(u8), 377 .reg_word_size = sizeof(u8),
375 .read = cx20442_read_reg_cache, 378 .read = cx20442_read_reg_cache,
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 593632cf791d..40e285df9ae5 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -33,6 +33,7 @@
33#include <sound/soc.h> 33#include <sound/soc.h>
34#include <sound/soc-dapm.h> 34#include <sound/soc-dapm.h>
35#include <sound/initval.h> 35#include <sound/initval.h>
36#include <sound/tlv.h>
36#include "sn95031.h" 37#include "sn95031.h"
37 38
38#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) 39#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
@@ -145,6 +146,129 @@ static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
145 return 0; 146 return 0;
146} 147}
147 148
149static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
150 struct snd_kcontrol *k, int event)
151{
152 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
153
154 if (SND_SOC_DAPM_EVENT_ON(event)) {
155 ldo = BIT(5)|BIT(4);
156 clk_dir = BIT(0);
157 data_dir = BIT(7);
158 }
159 /* program DMIC LDO, clock and set clock */
160 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
161 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
162 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
163 return 0;
164}
165
166static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
167 struct snd_kcontrol *k, int event)
168{
169 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
170
171 if (SND_SOC_DAPM_EVENT_ON(event)) {
172 ldo = BIT(5)|BIT(4);
173 clk_dir = BIT(2);
174 data_dir = BIT(1);
175 }
176 /* program DMIC LDO, clock and set clock */
177 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
178 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
179 snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
180 return 0;
181}
182
183static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
184 struct snd_kcontrol *k, int event)
185{
186 unsigned int ldo = 0;
187
188 if (SND_SOC_DAPM_EVENT_ON(event))
189 ldo = BIT(7)|BIT(6);
190
191 /* program DMIC LDO */
192 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
193 return 0;
194}
195
196/* mux controls */
197static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
198
199static const struct soc_enum sn95031_micl_enum =
200 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts);
201
202static const struct snd_kcontrol_new sn95031_micl_mux_control =
203 SOC_DAPM_ENUM("Route", sn95031_micl_enum);
204
205static const struct soc_enum sn95031_micr_enum =
206 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts);
207
208static const struct snd_kcontrol_new sn95031_micr_mux_control =
209 SOC_DAPM_ENUM("Route", sn95031_micr_enum);
210
211static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
212 "DMIC4", "DMIC5", "DMIC6",
213 "ADC Left", "ADC Right" };
214
215static const struct soc_enum sn95031_input1_enum =
216 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts);
217
218static const struct snd_kcontrol_new sn95031_input1_mux_control =
219 SOC_DAPM_ENUM("Route", sn95031_input1_enum);
220
221static const struct soc_enum sn95031_input2_enum =
222 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts);
223
224static const struct snd_kcontrol_new sn95031_input2_mux_control =
225 SOC_DAPM_ENUM("Route", sn95031_input2_enum);
226
227static const struct soc_enum sn95031_input3_enum =
228 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts);
229
230static const struct snd_kcontrol_new sn95031_input3_mux_control =
231 SOC_DAPM_ENUM("Route", sn95031_input3_enum);
232
233static const struct soc_enum sn95031_input4_enum =
234 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts);
235
236static const struct snd_kcontrol_new sn95031_input4_mux_control =
237 SOC_DAPM_ENUM("Route", sn95031_input4_enum);
238
239/* capture path controls */
240
241static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
242
243/* 0dB to 30dB in 10dB steps */
244static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 30);
245
246static const struct soc_enum sn95031_micmode1_enum =
247 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
248static const struct soc_enum sn95031_micmode2_enum =
249 SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text);
250
251static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
252
253static const struct soc_enum sn95031_dmic12_cfg_enum =
254 SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text);
255static const struct soc_enum sn95031_dmic34_cfg_enum =
256 SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text);
257static const struct soc_enum sn95031_dmic56_cfg_enum =
258 SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text);
259
260static const struct snd_kcontrol_new sn95031_snd_controls[] = {
261 SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
262 SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
263 SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
264 SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
265 SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
266 SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
267 2, 4, 0, mic_tlv),
268 SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
269 2, 4, 0, mic_tlv),
270};
271
148/* DAPM widgets */ 272/* DAPM widgets */
149static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { 273static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
150 274
@@ -159,6 +283,36 @@ static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
159 SND_SOC_DAPM_OUTPUT("VIB1OUT"), 283 SND_SOC_DAPM_OUTPUT("VIB1OUT"),
160 SND_SOC_DAPM_OUTPUT("VIB2OUT"), 284 SND_SOC_DAPM_OUTPUT("VIB2OUT"),
161 285
286 SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
287 SND_SOC_DAPM_INPUT("AMIC2"),
288 SND_SOC_DAPM_INPUT("DMIC1"),
289 SND_SOC_DAPM_INPUT("DMIC2"),
290 SND_SOC_DAPM_INPUT("DMIC3"),
291 SND_SOC_DAPM_INPUT("DMIC4"),
292 SND_SOC_DAPM_INPUT("DMIC5"),
293 SND_SOC_DAPM_INPUT("DMIC6"),
294 SND_SOC_DAPM_INPUT("LINEINL"),
295 SND_SOC_DAPM_INPUT("LINEINR"),
296
297 SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
298 SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
299 SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
300 SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
301 SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
302
303 SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
304 sn95031_dmic12_event,
305 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
306 SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
307 sn95031_dmic34_event,
308 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
309 SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
310 sn95031_dmic56_event,
311 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
312
313 SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
314 SND_SOC_NOPM, 0, 0),
315
162 SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0, 316 SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
163 sn95031_vhs_event, 317 sn95031_vhs_event,
164 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 318 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -209,6 +363,40 @@ static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
209 SN95031_VIB1C5, 1, 0), 363 SN95031_VIB1C5, 1, 0),
210 SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2", 364 SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
211 SN95031_VIB2C5, 1, 0), 365 SN95031_VIB2C5, 1, 0),
366
367 /* capture widgets */
368 SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
369 7, 0, NULL, 0),
370 SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
371 7, 0, NULL, 0),
372
373 SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
374 SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
375 SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
376 SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
377 SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
378 SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
379
380 /* ADC have null stream as they will be turned ON by TX path */
381 SND_SOC_DAPM_ADC("ADC Left", NULL,
382 SN95031_ADCCONFIG, 0, 0),
383 SND_SOC_DAPM_ADC("ADC Right", NULL,
384 SN95031_ADCCONFIG, 2, 0),
385
386 SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
387 SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
388 SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
389 SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
390
391 SND_SOC_DAPM_MUX("Txpath1 Capture Route",
392 SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
393 SND_SOC_DAPM_MUX("Txpath2 Capture Route",
394 SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
395 SND_SOC_DAPM_MUX("Txpath3 Capture Route",
396 SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
397 SND_SOC_DAPM_MUX("Txpath4 Capture Route",
398 SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
399
212}; 400};
213 401
214static const struct snd_soc_dapm_route sn95031_audio_map[] = { 402static const struct snd_soc_dapm_route sn95031_audio_map[] = {
@@ -250,6 +438,87 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = {
250 { "Lineout Right Playback", NULL, "Headset Right Filter"}, 438 { "Lineout Right Playback", NULL, "Headset Right Filter"},
251 { "Lineout Right Playback", NULL, "Speaker Right Filter"}, 439 { "Lineout Right Playback", NULL, "Speaker Right Filter"},
252 { "Lineout Right Playback", NULL, "Vibra2 DAC"}, 440 { "Lineout Right Playback", NULL, "Vibra2 DAC"},
441
442 /* Headset (AMIC1) mic */
443 { "AMIC1Bias", NULL, "AMIC1"},
444 { "MIC1 Enable", NULL, "AMIC1Bias"},
445 { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
446
447 /* AMIC2 */
448 { "AMIC2Bias", NULL, "AMIC2"},
449 { "MIC2 Enable", NULL, "AMIC2Bias"},
450 { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
451
452
453 /* Linein */
454 { "LineIn Enable Left", NULL, "LINEINL"},
455 { "LineIn Enable Right", NULL, "LINEINR"},
456 { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
457 { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
458
459 /* ADC connection */
460 { "ADC Left", NULL, "Mic_InputL Capture Route"},
461 { "ADC Right", NULL, "Mic_InputR Capture Route"},
462
463 /*DMIC connections */
464 { "DMIC1", NULL, "DMIC12supply"},
465 { "DMIC2", NULL, "DMIC12supply"},
466 { "DMIC3", NULL, "DMIC34supply"},
467 { "DMIC4", NULL, "DMIC34supply"},
468 { "DMIC5", NULL, "DMIC56supply"},
469 { "DMIC6", NULL, "DMIC56supply"},
470
471 { "DMIC12Bias", NULL, "DMIC1"},
472 { "DMIC12Bias", NULL, "DMIC2"},
473 { "DMIC34Bias", NULL, "DMIC3"},
474 { "DMIC34Bias", NULL, "DMIC4"},
475 { "DMIC56Bias", NULL, "DMIC5"},
476 { "DMIC56Bias", NULL, "DMIC6"},
477
478 /*TX path inputs*/
479 { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
480 { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
481 { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
482 { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
483 { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
484 { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
485 { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
486 { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
487 { "Txpath1 Capture Route", NULL, "DMIC1"},
488 { "Txpath2 Capture Route", NULL, "DMIC1"},
489 { "Txpath3 Capture Route", NULL, "DMIC1"},
490 { "Txpath4 Capture Route", NULL, "DMIC1"},
491 { "Txpath1 Capture Route", NULL, "DMIC2"},
492 { "Txpath2 Capture Route", NULL, "DMIC2"},
493 { "Txpath3 Capture Route", NULL, "DMIC2"},
494 { "Txpath4 Capture Route", NULL, "DMIC2"},
495 { "Txpath1 Capture Route", NULL, "DMIC3"},
496 { "Txpath2 Capture Route", NULL, "DMIC3"},
497 { "Txpath3 Capture Route", NULL, "DMIC3"},
498 { "Txpath4 Capture Route", NULL, "DMIC3"},
499 { "Txpath1 Capture Route", NULL, "DMIC4"},
500 { "Txpath2 Capture Route", NULL, "DMIC4"},
501 { "Txpath3 Capture Route", NULL, "DMIC4"},
502 { "Txpath4 Capture Route", NULL, "DMIC4"},
503 { "Txpath1 Capture Route", NULL, "DMIC5"},
504 { "Txpath2 Capture Route", NULL, "DMIC5"},
505 { "Txpath3 Capture Route", NULL, "DMIC5"},
506 { "Txpath4 Capture Route", NULL, "DMIC5"},
507 { "Txpath1 Capture Route", NULL, "DMIC6"},
508 { "Txpath2 Capture Route", NULL, "DMIC6"},
509 { "Txpath3 Capture Route", NULL, "DMIC6"},
510 { "Txpath4 Capture Route", NULL, "DMIC6"},
511
512 /* tx path */
513 { "TX1 Enable", NULL, "Txpath1 Capture Route"},
514 { "TX2 Enable", NULL, "Txpath2 Capture Route"},
515 { "TX3 Enable", NULL, "Txpath3 Capture Route"},
516 { "TX4 Enable", NULL, "Txpath4 Capture Route"},
517 { "PCM_Out", NULL, "TX1 Enable"},
518 { "PCM_Out", NULL, "TX2 Enable"},
519 { "PCM_Out", NULL, "TX3 Enable"},
520 { "PCM_Out", NULL, "TX4 Enable"},
521
253}; 522};
254 523
255/* speaker and headset mutes, for audio pops and clicks */ 524/* speaker and headset mutes, for audio pops and clicks */
@@ -339,6 +608,13 @@ struct snd_soc_dai_driver sn95031_dais[] = {
339 .rates = SN95031_RATES, 608 .rates = SN95031_RATES,
340 .formats = SN95031_FORMATS, 609 .formats = SN95031_FORMATS,
341 }, 610 },
611 .capture = {
612 .stream_name = "Capture",
613 .channels_min = 1,
614 .channels_max = 5,
615 .rates = SN95031_RATES,
616 .formats = SN95031_FORMATS,
617 },
342 .ops = &sn95031_headset_dai_ops, 618 .ops = &sn95031_headset_dai_ops,
343}, 619},
344{ .name = "SN95031 Speaker", 620{ .name = "SN95031 Speaker",
@@ -390,6 +666,8 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
390 snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10); 666 snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
391 snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32); 667 snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
392 snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54); 668 snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
669 snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
670 snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
393 /* pcm port setting 671 /* pcm port setting
394 * This sets the pcm port to slave and clock at 19.2Mhz which 672 * This sets the pcm port to slave and clock at 19.2Mhz which
395 * can support 6slots, sampling rate set per stream in hw-params 673 * can support 6slots, sampling rate set per stream in hw-params
@@ -423,6 +701,9 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
423 snd_soc_write(codec, SN95031_SSR2, 0x10); 701 snd_soc_write(codec, SN95031_SSR2, 0x10);
424 snd_soc_write(codec, SN95031_SSR3, 0x40); 702 snd_soc_write(codec, SN95031_SSR3, 0x40);
425 703
704 snd_soc_add_controls(codec, sn95031_snd_controls,
705 ARRAY_SIZE(sn95031_snd_controls));
706
426 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, 707 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets,
427 ARRAY_SIZE(sn95031_dapm_widgets)); 708 ARRAY_SIZE(sn95031_dapm_widgets));
428 if (ret) 709 if (ret)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index a2a446cb1807..3d4c55f3c7b5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2,6 +2,7 @@
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc.
5 * 6 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 8 *
@@ -19,6 +20,7 @@
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/completion.h> 21#include <linux/completion.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/gpio.h>
22#include <linux/pm.h> 24#include <linux/pm.h>
23#include <linux/i2c.h> 25#include <linux/i2c.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -213,6 +215,7 @@ static u16 wm8903_reg_defaults[] = {
213}; 215};
214 216
215struct wm8903_priv { 217struct wm8903_priv {
218 struct snd_soc_codec *codec;
216 219
217 int sysclk; 220 int sysclk;
218 int irq; 221 int irq;
@@ -230,6 +233,10 @@ struct wm8903_priv {
230 int mic_short; 233 int mic_short;
231 int mic_last_report; 234 int mic_last_report;
232 int mic_delay; 235 int mic_delay;
236
237#ifdef CONFIG_GPIOLIB
238 struct gpio_chip gpio_chip;
239#endif
233}; 240};
234 241
235static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg) 242static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
@@ -1635,6 +1642,120 @@ static int wm8903_resume(struct snd_soc_codec *codec)
1635 return 0; 1642 return 0;
1636} 1643}
1637 1644
1645#ifdef CONFIG_GPIOLIB
1646static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip)
1647{
1648 return container_of(chip, struct wm8903_priv, gpio_chip);
1649}
1650
1651static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1652{
1653 if (offset >= WM8903_NUM_GPIO)
1654 return -EINVAL;
1655
1656 return 0;
1657}
1658
1659static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1660{
1661 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1662 struct snd_soc_codec *codec = wm8903->codec;
1663 unsigned int mask, val;
1664
1665 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
1666 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1667 WM8903_GP1_DIR;
1668
1669 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1670 mask, val);
1671}
1672
1673static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1674{
1675 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1676 struct snd_soc_codec *codec = wm8903->codec;
1677 int reg;
1678
1679 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
1680
1681 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1682}
1683
1684static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1685 unsigned offset, int value)
1686{
1687 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1688 struct snd_soc_codec *codec = wm8903->codec;
1689 unsigned int mask, val;
1690
1691 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
1692 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1693 (value << WM8903_GP2_LVL_SHIFT);
1694
1695 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1696 mask, val);
1697}
1698
1699static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1700{
1701 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1702 struct snd_soc_codec *codec = wm8903->codec;
1703
1704 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1705 WM8903_GP1_LVL_MASK,
1706 !!value << WM8903_GP1_LVL_SHIFT);
1707}
1708
1709static struct gpio_chip wm8903_template_chip = {
1710 .label = "wm8903",
1711 .owner = THIS_MODULE,
1712 .request = wm8903_gpio_request,
1713 .direction_input = wm8903_gpio_direction_in,
1714 .get = wm8903_gpio_get,
1715 .direction_output = wm8903_gpio_direction_out,
1716 .set = wm8903_gpio_set,
1717 .can_sleep = 1,
1718};
1719
1720static void wm8903_init_gpio(struct snd_soc_codec *codec)
1721{
1722 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1723 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1724 int ret;
1725
1726 wm8903->gpio_chip = wm8903_template_chip;
1727 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1728 wm8903->gpio_chip.dev = codec->dev;
1729
1730 if (pdata && pdata->gpio_base)
1731 wm8903->gpio_chip.base = pdata->gpio_base;
1732 else
1733 wm8903->gpio_chip.base = -1;
1734
1735 ret = gpiochip_add(&wm8903->gpio_chip);
1736 if (ret != 0)
1737 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
1738}
1739
1740static void wm8903_free_gpio(struct snd_soc_codec *codec)
1741{
1742 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1743 int ret;
1744
1745 ret = gpiochip_remove(&wm8903->gpio_chip);
1746 if (ret != 0)
1747 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
1748}
1749#else
1750static void wm8903_init_gpio(struct snd_soc_codec *codec)
1751{
1752}
1753
1754static void wm8903_free_gpio(struct snd_soc_codec *codec)
1755{
1756}
1757#endif
1758
1638static int wm8903_probe(struct snd_soc_codec *codec) 1759static int wm8903_probe(struct snd_soc_codec *codec)
1639{ 1760{
1640 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); 1761 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
@@ -1643,6 +1764,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1643 int trigger, irq_pol; 1764 int trigger, irq_pol;
1644 u16 val; 1765 u16 val;
1645 1766
1767 wm8903->codec = codec;
1646 init_completion(&wm8903->wseq); 1768 init_completion(&wm8903->wseq);
1647 1769
1648 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1770 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
@@ -1667,7 +1789,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1667 /* Set up GPIOs and microphone detection */ 1789 /* Set up GPIOs and microphone detection */
1668 if (pdata) { 1790 if (pdata) {
1669 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { 1791 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1670 if (!pdata->gpio_cfg[i]) 1792 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
1671 continue; 1793 continue;
1672 1794
1673 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, 1795 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
@@ -1749,12 +1871,15 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1749 ARRAY_SIZE(wm8903_snd_controls)); 1871 ARRAY_SIZE(wm8903_snd_controls));
1750 wm8903_add_widgets(codec); 1872 wm8903_add_widgets(codec);
1751 1873
1874 wm8903_init_gpio(codec);
1875
1752 return ret; 1876 return ret;
1753} 1877}
1754 1878
1755/* power down chip */ 1879/* power down chip */
1756static int wm8903_remove(struct snd_soc_codec *codec) 1880static int wm8903_remove(struct snd_soc_codec *codec)
1757{ 1881{
1882 wm8903_free_gpio(codec);
1758 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1883 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1759 return 0; 1884 return 0;
1760} 1885}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 5c7b730a864f..3b71dd65c966 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3635,7 +3635,7 @@ static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
3635 struct snd_soc_codec *codec = wm8962->codec; 3635 struct snd_soc_codec *codec = wm8962->codec;
3636 3636
3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, 3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
3638 WM8962_GP2_LVL, value << WM8962_GP2_LVL_SHIFT); 3638 WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
3639} 3639}
3640 3640
3641static int wm8962_gpio_direction_out(struct gpio_chip *chip, 3641static int wm8962_gpio_direction_out(struct gpio_chip *chip,
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 0bb0bb40b842..0ca81d3c64e8 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2386,7 +2386,7 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
2386 else 2386 else
2387 val = 0; 2387 val = 0;
2388 2388
2389 return snd_soc_update_bits(codec, reg, mask, reg); 2389 return snd_soc_update_bits(codec, reg, mask, val);
2390} 2390}
2391 2391
2392#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 2392#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 7d563413df3e..67eaaecbb42e 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -1265,7 +1265,7 @@ static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
1265 else 1265 else
1266 val = 0; 1266 val = 0;
1267 1267
1268 return snd_soc_update_bits(codec, reg, mask, reg); 1268 return snd_soc_update_bits(codec, reg, mask, val);
1269} 1269}
1270 1270
1271/* The size in bits of the FLL divide multiplied by 10 1271/* The size in bits of the FLL divide multiplied by 10
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index c466982eed23..613df5db0b32 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -91,6 +91,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
91static void calibrate_dc_servo(struct snd_soc_codec *codec) 91static void calibrate_dc_servo(struct snd_soc_codec *codec)
92{ 92{
93 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 93 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
94 s8 offset;
94 u16 reg, reg_l, reg_r, dcs_cfg; 95 u16 reg, reg_l, reg_r, dcs_cfg;
95 96
96 /* If we're using a digital only path and have a previously 97 /* If we're using a digital only path and have a previously
@@ -149,16 +150,14 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
149 hubs->dcs_codes); 150 hubs->dcs_codes);
150 151
151 /* HPOUT1L */ 152 /* HPOUT1L */
152 if (reg_l + hubs->dcs_codes > 0 && 153 offset = reg_l;
153 reg_l + hubs->dcs_codes < 0xff) 154 offset += hubs->dcs_codes;
154 reg_l += hubs->dcs_codes; 155 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
155 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
156 156
157 /* HPOUT1R */ 157 /* HPOUT1R */
158 if (reg_r + hubs->dcs_codes > 0 && 158 offset = reg_r;
159 reg_r + hubs->dcs_codes < 0xff) 159 offset += hubs->dcs_codes;
160 reg_r += hubs->dcs_codes; 160 dcs_cfg |= (u8)offset;
161 dcs_cfg |= reg_r;
162 161
163 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); 162 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
164 163
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 0c2d6bacc681..b36f0b39b090 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -223,7 +223,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
223 .stream_name = "AIC3X", 223 .stream_name = "AIC3X",
224 .cpu_dai_name= "davinci-mcasp.0", 224 .cpu_dai_name= "davinci-mcasp.0",
225 .codec_dai_name = "tlv320aic3x-hifi", 225 .codec_dai_name = "tlv320aic3x-hifi",
226 .codec_name = "tlv320aic3x-codec.0-001a", 226 .codec_name = "tlv320aic3x-codec.1-0018",
227 .platform_name = "davinci-pcm-audio", 227 .platform_name = "davinci-pcm-audio",
228 .init = evm_aic3x_init, 228 .init = evm_aic3x_init,
229 .ops = &evm_ops, 229 .ops = &evm_ops,
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
index 57429041189c..91a28de94109 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/ep93xx/Kconfig
@@ -30,3 +30,12 @@ config SND_EP93XX_SOC_SIMONE
30 help 30 help
31 Say Y or M here if you want to add support for AC97 audio on the 31 Say Y or M here if you want to add support for AC97 audio on the
32 Simplemachines Sim.One board. 32 Simplemachines Sim.One board.
33
34config SND_EP93XX_SOC_EDB93XX
35 tristate "SoC Audio support for Cirrus Logic EDB93xx boards"
36 depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A)
37 select SND_EP93XX_SOC_I2S
38 select SND_SOC_CS4271
39 help
40 Say Y or M here if you want to add support for I2S audio on the
41 Cirrus Logic EDB93xx boards.
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/ep93xx/Makefile
index 8e7977fb6b7d..5514146cbdf0 100644
--- a/sound/soc/ep93xx/Makefile
+++ b/sound/soc/ep93xx/Makefile
@@ -10,6 +10,8 @@ obj-$(CONFIG_SND_EP93XX_SOC_AC97) += snd-soc-ep93xx-ac97.o
10# EP93XX Machine Support 10# EP93XX Machine Support
11snd-soc-snappercl15-objs := snappercl15.o 11snd-soc-snappercl15-objs := snappercl15.o
12snd-soc-simone-objs := simone.o 12snd-soc-simone-objs := simone.o
13snd-soc-edb93xx-objs := edb93xx.o
13 14
14obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o 15obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
15obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o 16obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o
17obj-$(CONFIG_SND_EP93XX_SOC_EDB93XX) += snd-soc-edb93xx.o
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
new file mode 100644
index 000000000000..b270085227f3
--- /dev/null
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -0,0 +1,142 @@
1/*
2 * SoC audio for EDB93xx
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include "ep93xx-pcm.h"
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,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 int err;
44 unsigned int rate = params_rate(params);
45 /*
46 * We set LRCLK equal to `rate' and SCLK = LRCLK * 64,
47 * because our sample size is 32 bit * 2 channels.
48 * I2S standard permits us to transmit more bits than
49 * the codec uses.
50 * MCLK = SCLK * 4 is the best recommended value,
51 * but we have to fall back to ratio 2 for higher
52 * sample rates.
53 */
54 unsigned int mclk_rate = rate * 64 * ((rate <= 48000) ? 4 : 2);
55
56 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_IF |
58 SND_SOC_DAIFMT_CBS_CFS);
59 if (err)
60 return err;
61
62 err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_IF |
64 SND_SOC_DAIFMT_CBS_CFS);
65 if (err)
66 return err;
67
68 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
69 SND_SOC_CLOCK_IN);
70 if (err)
71 return err;
72
73 return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate,
74 SND_SOC_CLOCK_OUT);
75}
76
77static struct snd_soc_ops edb93xx_ops = {
78 .hw_params = edb93xx_hw_params,
79};
80
81static struct snd_soc_dai_link edb93xx_dai = {
82 .name = "CS4271",
83 .stream_name = "CS4271 HiFi",
84 .platform_name = "ep93xx-pcm-audio",
85 .cpu_dai_name = "ep93xx-i2s",
86 .codec_name = "spi0.0",
87 .codec_dai_name = "cs4271-hifi",
88 .ops = &edb93xx_ops,
89};
90
91static struct snd_soc_card snd_soc_edb93xx = {
92 .name = "EDB93XX",
93 .dai_link = &edb93xx_dai,
94 .num_links = 1,
95};
96
97static struct platform_device *edb93xx_snd_device;
98
99static int __init edb93xx_init(void)
100{
101 int ret;
102
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret)
110 return ret;
111
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1);
113 if (!edb93xx_snd_device) {
114 ret = -ENOMEM;
115 goto free_i2s;
116 }
117
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx);
119 ret = platform_device_add(edb93xx_snd_device);
120 if (ret)
121 goto device_put;
122
123 return 0;
124
125device_put:
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release();
129 return ret;
130}
131module_init(edb93xx_init);
132
133static void __exit edb93xx_exit(void)
134{
135 platform_device_unregister(edb93xx_snd_device);
136 ep93xx_i2s_release();
137}
138module_exit(edb93xx_exit);
139
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 7d7847a1e66b..c16c6b2eff95 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -53,9 +53,8 @@ struct mpc8610_hpcd_data {
53 * 53 *
54 * Here we program the DMACR and PMUXCR registers. 54 * Here we program the DMACR and PMUXCR registers.
55 */ 55 */
56static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device) 56static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
57{ 57{
58 struct snd_soc_card *card = platform_get_drvdata(sound_device);
59 struct mpc8610_hpcd_data *machine_data = 58 struct mpc8610_hpcd_data *machine_data =
60 container_of(card, struct mpc8610_hpcd_data, card); 59 container_of(card, struct mpc8610_hpcd_data, card);
61 struct ccsr_guts_86xx __iomem *guts; 60 struct ccsr_guts_86xx __iomem *guts;
@@ -138,9 +137,8 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
138 * This function is called to remove the sound device for one SSI. We 137 * This function is called to remove the sound device for one SSI. We
139 * de-program the DMACR and PMUXCR register. 138 * de-program the DMACR and PMUXCR register.
140 */ 139 */
141static int mpc8610_hpcd_machine_remove(struct platform_device *sound_device) 140static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
142{ 141{
143 struct snd_soc_card *card = platform_get_drvdata(sound_device);
144 struct mpc8610_hpcd_data *machine_data = 142 struct mpc8610_hpcd_data *machine_data =
145 container_of(card, struct mpc8610_hpcd_data, card); 143 container_of(card, struct mpc8610_hpcd_data, card);
146 struct ccsr_guts_86xx __iomem *guts; 144 struct ccsr_guts_86xx __iomem *guts;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 026b756961e0..66e0b68af147 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -85,9 +85,8 @@ struct machine_data {
85 * 85 *
86 * Here we program the DMACR and PMUXCR registers. 86 * Here we program the DMACR and PMUXCR registers.
87 */ 87 */
88static int p1022_ds_machine_probe(struct platform_device *sound_device) 88static int p1022_ds_machine_probe(struct snd_soc_card *card)
89{ 89{
90 struct snd_soc_card *card = platform_get_drvdata(sound_device);
91 struct machine_data *mdata = 90 struct machine_data *mdata =
92 container_of(card, struct machine_data, card); 91 container_of(card, struct machine_data, card);
93 struct ccsr_guts_85xx __iomem *guts; 92 struct ccsr_guts_85xx __iomem *guts;
@@ -160,9 +159,8 @@ static int p1022_ds_startup(struct snd_pcm_substream *substream)
160 * This function is called to remove the sound device for one SSI. We 159 * This function is called to remove the sound device for one SSI. We
161 * de-program the DMACR and PMUXCR register. 160 * de-program the DMACR and PMUXCR register.
162 */ 161 */
163static int p1022_ds_machine_remove(struct platform_device *sound_device) 162static int p1022_ds_machine_remove(struct snd_soc_card *card)
164{ 163{
165 struct snd_soc_card *card = platform_get_drvdata(sound_device);
166 struct machine_data *mdata = 164 struct machine_data *mdata =
167 container_of(card, struct machine_data, card); 165 container_of(card, struct machine_data, card);
168 struct ccsr_guts_85xx __iomem *guts; 166 struct ccsr_guts_85xx __iomem *guts;
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 1a330be1a01e..7925851a5de1 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -182,6 +182,9 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
182 snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); 182 snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
183 lo_dac = 3; 183 lo_dac = 3;
184 hs_switch = 0; 184 hs_switch = 0;
185 /* we dont use linein in this so set to NC */
186 snd_soc_dapm_disable_pin(dapm, "LINEINL");
187 snd_soc_dapm_disable_pin(dapm, "LINEINR");
185 return snd_soc_dapm_sync(dapm); 188 return snd_soc_dapm_sync(dapm);
186} 189}
187 190
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 1d1f5447b338..96e6e9c9c5f4 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -73,6 +73,12 @@ struct snd_soc_dai_driver sst_platform_dai[] = {
73 .rates = SNDRV_PCM_RATE_48000, 73 .rates = SNDRV_PCM_RATE_48000,
74 .formats = SNDRV_PCM_FMTBIT_S24_LE, 74 .formats = SNDRV_PCM_FMTBIT_S24_LE,
75 }, 75 },
76 .capture = {
77 .channels_min = 1,
78 .channels_max = 5,
79 .rates = SNDRV_PCM_RATE_48000,
80 .formats = SNDRV_PCM_FMTBIT_S24_LE,
81 },
76}, 82},
77{ 83{
78 .name = "Speaker-cpu-dai", 84 .name = "Speaker-cpu-dai",
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 2101bdcee21f..3167be689621 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -507,8 +507,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
507 /* Set up digital mute if not provided by the codec */ 507 /* Set up digital mute if not provided by the codec */
508 if (!codec_dai->driver->ops) { 508 if (!codec_dai->driver->ops) {
509 codec_dai->driver->ops = &ams_delta_dai_ops; 509 codec_dai->driver->ops = &ams_delta_dai_ops;
510 } else if (!codec_dai->driver->ops->digital_mute) {
511 codec_dai->driver->ops->digital_mute = ams_delta_digital_mute;
512 } else { 510 } else {
513 ams_delta_ops.startup = ams_delta_startup; 511 ams_delta_ops.startup = ams_delta_startup;
514 ams_delta_ops.shutdown = ams_delta_shutdown; 512 ams_delta_ops.shutdown = ams_delta_shutdown;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index fc592f0d5fc7..784cff5f67e8 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -307,10 +307,10 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
307static struct snd_soc_dai_link corgi_dai = { 307static struct snd_soc_dai_link corgi_dai = {
308 .name = "WM8731", 308 .name = "WM8731",
309 .stream_name = "WM8731", 309 .stream_name = "WM8731",
310 .cpu_dai_name = "pxa-is2-dai", 310 .cpu_dai_name = "pxa2xx-i2s",
311 .codec_dai_name = "wm8731-hifi", 311 .codec_dai_name = "wm8731-hifi",
312 .platform_name = "pxa-pcm-audio", 312 .platform_name = "pxa-pcm-audio",
313 .codec_name = "wm8731-codec-0.001a", 313 .codec_name = "wm8731-codec-0.001b",
314 .init = corgi_wm8731_init, 314 .init = corgi_wm8731_init,
315 .ops = &corgi_ops, 315 .ops = &corgi_ops,
316}; 316};
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 6298ee115e27..a7d4999f9b24 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = {
276 .cpu_dai_name = "pxa2xx-i2s", 276 .cpu_dai_name = "pxa2xx-i2s",
277 .codec_dai_name = "wm8731-hifi", 277 .codec_dai_name = "wm8731-hifi",
278 .platform_name = "pxa-pcm-audio", 278 .platform_name = "pxa-pcm-audio",
279 .codec_name = "wm8731-codec.0-001a", 279 .codec_name = "wm8731-codec.0-001b",
280 .init = poodle_wm8731_init, 280 .init = poodle_wm8731_init,
281 .ops = &poodle_ops, 281 .ops = &poodle_ops,
282}; 282};
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 0fd60f423036..db1dd560a585 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = {
151 .hw_params = raumfeld_cs4270_hw_params, 151 .hw_params = raumfeld_cs4270_hw_params,
152}; 152};
153 153
154static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state) 154static int raumfeld_line_suspend(struct snd_soc_card *card)
155{ 155{
156 raumfeld_enable_audio(false); 156 raumfeld_enable_audio(false);
157 return 0; 157 return 0;
158} 158}
159 159
160static int raumfeld_line_resume(struct platform_device *pdev) 160static int raumfeld_line_resume(struct snd_soc_card *card)
161{ 161{
162 raumfeld_enable_audio(true); 162 raumfeld_enable_audio(true);
163 return 0; 163 return 0;
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index c2acb69b957a..8e1571350630 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -315,10 +315,10 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
315static struct snd_soc_dai_link spitz_dai = { 315static struct snd_soc_dai_link spitz_dai = {
316 .name = "wm8750", 316 .name = "wm8750",
317 .stream_name = "WM8750", 317 .stream_name = "WM8750",
318 .cpu_dai_name = "pxa-is2", 318 .cpu_dai_name = "pxa2xx-i2s",
319 .codec_dai_name = "wm8750-hifi", 319 .codec_dai_name = "wm8750-hifi",
320 .platform_name = "pxa-pcm-audio", 320 .platform_name = "pxa-pcm-audio",
321 .codec_name = "wm8750-codec.0-001a", 321 .codec_name = "wm8750-codec.0-001b",
322 .init = spitz_wm8750_init, 322 .init = spitz_wm8750_init,
323 .ops = &spitz_ops, 323 .ops = &spitz_ops,
324}; 324};
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index f75804ef0897..489139a31cf9 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -237,7 +237,7 @@ static struct snd_soc_dai_link tosa_dai[] = {
237}, 237},
238}; 238};
239 239
240static int tosa_probe(struct platform_device *dev) 240static int tosa_probe(struct snd_soc_card *card)
241{ 241{
242 int ret; 242 int ret;
243 243
@@ -251,7 +251,7 @@ static int tosa_probe(struct platform_device *dev)
251 return ret; 251 return ret;
252} 252}
253 253
254static int tosa_remove(struct platform_device *dev) 254static int tosa_remove(struct snd_soc_card *card)
255{ 255{
256 gpio_free(TOSA_GPIO_L_MUTE); 256 gpio_free(TOSA_GPIO_L_MUTE);
257 return 0; 257 return 0;
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index b222a7d72027..c5858296b48a 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -189,7 +189,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
189}, 189},
190}; 190};
191 191
192static int zylonite_probe(struct platform_device *pdev) 192static int zylonite_probe(struct snd_soc_card *card)
193{ 193{
194 int ret; 194 int ret;
195 195
@@ -216,7 +216,7 @@ static int zylonite_probe(struct platform_device *pdev)
216 return 0; 216 return 0;
217} 217}
218 218
219static int zylonite_remove(struct platform_device *pdev) 219static int zylonite_remove(struct snd_soc_card *card)
220{ 220{
221 if (clk_pout) { 221 if (clk_pout) {
222 clk_disable(pout); 222 clk_disable(pout);
@@ -226,8 +226,7 @@ static int zylonite_remove(struct platform_device *pdev)
226 return 0; 226 return 0;
227} 227}
228 228
229static int zylonite_suspend_post(struct platform_device *pdev, 229static int zylonite_suspend_post(struct snd_soc_card *card)
230 pm_message_t state)
231{ 230{
232 if (clk_pout) 231 if (clk_pout)
233 clk_disable(pout); 232 clk_disable(pout);
@@ -235,7 +234,7 @@ static int zylonite_suspend_post(struct platform_device *pdev,
235 return 0; 234 return 0;
236} 235}
237 236
238static int zylonite_resume_pre(struct platform_device *pdev) 237static int zylonite_resume_pre(struct snd_soc_card *card)
239{ 238{
240 int ret = 0; 239 int ret = 0;
241 240
diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
index 69e08fd1ff00..95ebf812b146 100644
--- a/sound/soc/samsung/neo1973_gta02_wm8753.c
+++ b/sound/soc/samsung/neo1973_gta02_wm8753.c
@@ -387,11 +387,11 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
387{ /* Hifi Playback - for similatious use with voice below */ 387{ /* Hifi Playback - for similatious use with voice below */
388 .name = "WM8753", 388 .name = "WM8753",
389 .stream_name = "WM8753 HiFi", 389 .stream_name = "WM8753 HiFi",
390 .cpu_dai_name = "s3c24xx-i2s", 390 .cpu_dai_name = "s3c24xx-iis",
391 .codec_dai_name = "wm8753-hifi", 391 .codec_dai_name = "wm8753-hifi",
392 .init = neo1973_gta02_wm8753_init, 392 .init = neo1973_gta02_wm8753_init,
393 .platform_name = "samsung-audio", 393 .platform_name = "samsung-audio",
394 .codec_name = "wm8753-codec.0-0x1a", 394 .codec_name = "wm8753-codec.0-001a",
395 .ops = &neo1973_gta02_hifi_ops, 395 .ops = &neo1973_gta02_hifi_ops,
396}, 396},
397{ /* Voice via BT */ 397{ /* Voice via BT */
@@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
400 .cpu_dai_name = "bluetooth-dai", 400 .cpu_dai_name = "bluetooth-dai",
401 .codec_dai_name = "wm8753-voice", 401 .codec_dai_name = "wm8753-voice",
402 .ops = &neo1973_gta02_voice_ops, 402 .ops = &neo1973_gta02_voice_ops,
403 .codec_name = "wm8753-codec.0-0x1a", 403 .codec_name = "wm8753-codec.0-001a",
404 .platform_name = "samsung-audio", 404 .platform_name = "samsung-audio",
405}, 405},
406}; 406};
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index c7a24514beb5..d3cd6888a810 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -24,7 +24,6 @@
24#include <sound/tlv.h> 24#include <sound/tlv.h>
25 25
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/regs-clock.h> 27#include <mach/regs-clock.h>
29#include <mach/regs-gpio.h> 28#include <mach/regs-gpio.h>
30#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -559,9 +558,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
559 .name = "WM8753", 558 .name = "WM8753",
560 .stream_name = "WM8753 HiFi", 559 .stream_name = "WM8753 HiFi",
561 .platform_name = "samsung-audio", 560 .platform_name = "samsung-audio",
562 .cpu_dai_name = "s3c24xx-i2s", 561 .cpu_dai_name = "s3c24xx-iis",
563 .codec_dai_name = "wm8753-hifi", 562 .codec_dai_name = "wm8753-hifi",
564 .codec_name = "wm8753-codec.0-0x1a", 563 .codec_name = "wm8753-codec.0-001a",
565 .init = neo1973_wm8753_init, 564 .init = neo1973_wm8753_init,
566 .ops = &neo1973_hifi_ops, 565 .ops = &neo1973_hifi_ops,
567}, 566},
@@ -571,7 +570,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
571 .platform_name = "samsung-audio", 570 .platform_name = "samsung-audio",
572 .cpu_dai_name = "bluetooth-dai", 571 .cpu_dai_name = "bluetooth-dai",
573 .codec_dai_name = "wm8753-voice", 572 .codec_dai_name = "wm8753-voice",
574 .codec_name = "wm8753-codec.0-0x1a", 573 .codec_name = "wm8753-codec.0-001a",
575 .ops = &neo1973_voice_ops, 574 .ops = &neo1973_voice_ops,
576}, 575},
577}; 576};
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index d7b3e6e9d783..ce6aef604179 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -84,8 +84,8 @@ static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
84static struct snd_soc_dai_link simtec_dai_aic33 = { 84static struct snd_soc_dai_link simtec_dai_aic33 = {
85 .name = "tlv320aic33", 85 .name = "tlv320aic33",
86 .stream_name = "TLV320AIC33", 86 .stream_name = "TLV320AIC33",
87 .codec_name = "tlv320aic3x-codec.0-0x1a", 87 .codec_name = "tlv320aic3x-codec.0-001a",
88 .cpu_dai_name = "s3c24xx-i2s", 88 .cpu_dai_name = "s3c24xx-iis",
89 .codec_dai_name = "tlv320aic3x-hifi", 89 .codec_dai_name = "tlv320aic3x-hifi",
90 .platform_name = "samsung-audio", 90 .platform_name = "samsung-audio",
91 .init = simtec_hermes_init, 91 .init = simtec_hermes_init,
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index ff6168f5f2e0..a7ef7db54687 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -73,8 +73,8 @@ static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
73static struct snd_soc_dai_link simtec_dai_aic23 = { 73static struct snd_soc_dai_link simtec_dai_aic23 = {
74 .name = "tlv320aic23", 74 .name = "tlv320aic23",
75 .stream_name = "TLV320AIC23", 75 .stream_name = "TLV320AIC23",
76 .codec_name = "tlv320aic3x-codec.0-0x1a", 76 .codec_name = "tlv320aic3x-codec.0-001a",
77 .cpu_dai_name = "s3c24xx-i2s", 77 .cpu_dai_name = "s3c24xx-iis",
78 .codec_dai_name = "tlv320aic3x-hifi", 78 .codec_dai_name = "tlv320aic3x-hifi",
79 .platform_name = "samsung-audio", 79 .platform_name = "samsung-audio",
80 .init = simtec_tlv320aic23_init, 80 .init = simtec_tlv320aic23_init,
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index ce749a10ec07..3cb700751078 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -221,7 +221,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
221 .stream_name = "UDA134X", 221 .stream_name = "UDA134X",
222 .codec_name = "uda134x-hifi", 222 .codec_name = "uda134x-hifi",
223 .codec_dai_name = "uda134x-hifi", 223 .codec_dai_name = "uda134x-hifi",
224 .cpu_dai_name = "s3c24xx-i2s", 224 .cpu_dai_name = "s3c24xx-iis",
225 .ops = &s3c24xx_uda134x_ops, 225 .ops = &s3c24xx_uda134x_ops,
226 .platform_name = "samsung-audio", 226 .platform_name = "samsung-audio",
227}; 227};
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index 56cd34223100..d6f4703b3c07 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -23,14 +23,21 @@ struct fsi_ak4642_data {
23 23
24static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) 24static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
25{ 25{
26 struct snd_soc_dai *dai = rtd->codec_dai; 26 struct snd_soc_dai *codec = rtd->codec_dai;
27 struct snd_soc_dai *cpu = rtd->cpu_dai;
27 int ret; 28 int ret;
28 29
29 ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM); 30 ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
31 SND_SOC_DAIFMT_CBM_CFM);
30 if (ret < 0) 32 if (ret < 0)
31 return ret; 33 return ret;
32 34
33 ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0); 35 ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
36 if (ret < 0)
37 return ret;
38
39 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
40 SND_SOC_DAIFMT_CBS_CFS);
34 41
35 return ret; 42 return ret;
36} 43}
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index e8df9da92f71..dbafd7ac5590 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -15,11 +15,20 @@
15 15
16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) 16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
17{ 17{
18 struct snd_soc_dai *dai = rtd->codec_dai; 18 struct snd_soc_dai *codec = rtd->codec_dai;
19 struct snd_soc_dai *cpu = rtd->cpu_dai;
20 int ret;
19 21
20 return snd_soc_dai_set_fmt(dai, 22 ret = snd_soc_dai_set_fmt(codec,
21 SND_SOC_DAIFMT_I2S | 23 SND_SOC_DAIFMT_I2S |
22 SND_SOC_DAIFMT_CBM_CFM); 24 SND_SOC_DAIFMT_CBM_CFM);
25 if (ret < 0)
26 return ret;
27
28 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
29 SND_SOC_DAIFMT_CBS_CFS);
30
31 return ret;
23} 32}
24 33
25static struct snd_soc_dai_link fsi_da7210_dai = { 34static struct snd_soc_dai_link fsi_da7210_dai = {
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
index a52dd8ec71d3..9719985eb82d 100644
--- a/sound/soc/sh/fsi-hdmi.c
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -12,31 +12,59 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14 14
15struct fsi_hdmi_data {
16 const char *cpu_dai;
17 const char *card;
18 int id;
19};
20
21static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
22{
23 struct snd_soc_dai *cpu = rtd->cpu_dai;
24 int ret;
25
26 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
27
28 return ret;
29}
30
15static struct snd_soc_dai_link fsi_dai_link = { 31static struct snd_soc_dai_link fsi_dai_link = {
16 .name = "HDMI", 32 .name = "HDMI",
17 .stream_name = "HDMI", 33 .stream_name = "HDMI",
18 .cpu_dai_name = "fsib-dai", /* fsi B */
19 .codec_dai_name = "sh_mobile_hdmi-hifi", 34 .codec_dai_name = "sh_mobile_hdmi-hifi",
20 .platform_name = "sh_fsi2", 35 .platform_name = "sh_fsi2",
21 .codec_name = "sh-mobile-hdmi", 36 .codec_name = "sh-mobile-hdmi",
37 .init = fsi_hdmi_dai_init,
22}; 38};
23 39
24static struct snd_soc_card fsi_soc_card = { 40static struct snd_soc_card fsi_soc_card = {
25 .name = "FSI (SH MOBILE HDMI)",
26 .dai_link = &fsi_dai_link, 41 .dai_link = &fsi_dai_link,
27 .num_links = 1, 42 .num_links = 1,
28}; 43};
29 44
30static struct platform_device *fsi_snd_device; 45static struct platform_device *fsi_snd_device;
31 46
32static int __init fsi_hdmi_init(void) 47static int fsi_hdmi_probe(struct platform_device *pdev)
33{ 48{
34 int ret = -ENOMEM; 49 int ret = -ENOMEM;
50 const struct platform_device_id *id_entry;
51 struct fsi_hdmi_data *pdata;
52
53 id_entry = pdev->id_entry;
54 if (!id_entry) {
55 dev_err(&pdev->dev, "unknown fsi hdmi\n");
56 return -ENODEV;
57 }
35 58
36 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); 59 pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
60
61 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
37 if (!fsi_snd_device) 62 if (!fsi_snd_device)
38 goto out; 63 goto out;
39 64
65 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
66 fsi_soc_card.name = pdata->card;
67
40 platform_set_drvdata(fsi_snd_device, &fsi_soc_card); 68 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
41 ret = platform_device_add(fsi_snd_device); 69 ret = platform_device_add(fsi_snd_device);
42 70
@@ -47,9 +75,48 @@ out:
47 return ret; 75 return ret;
48} 76}
49 77
50static void __exit fsi_hdmi_exit(void) 78static int fsi_hdmi_remove(struct platform_device *pdev)
51{ 79{
52 platform_device_unregister(fsi_snd_device); 80 platform_device_unregister(fsi_snd_device);
81 return 0;
82}
83
84static struct fsi_hdmi_data fsi2_a_hdmi = {
85 .cpu_dai = "fsia-dai",
86 .card = "FSI2A (SH MOBILE HDMI)",
87 .id = FSI_PORT_A,
88};
89
90static struct fsi_hdmi_data fsi2_b_hdmi = {
91 .cpu_dai = "fsib-dai",
92 .card = "FSI2B (SH MOBILE HDMI)",
93 .id = FSI_PORT_B,
94};
95
96static struct platform_device_id fsi_id_table[] = {
97 /* FSI 2 */
98 { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
99 { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
100 {},
101};
102
103static struct platform_driver fsi_hdmi = {
104 .driver = {
105 .name = "fsi-hdmi-audio",
106 },
107 .probe = fsi_hdmi_probe,
108 .remove = fsi_hdmi_remove,
109 .id_table = fsi_id_table,
110};
111
112static int __init fsi_hdmi_init(void)
113{
114 return platform_driver_register(&fsi_hdmi);
115}
116
117static void __exit fsi_hdmi_exit(void)
118{
119 platform_driver_unregister(&fsi_hdmi);
53} 120}
54 121
55module_init(fsi_hdmi_init); 122module_init(fsi_hdmi_init);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2b06402801ef..0c9997e2d8c0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -78,6 +78,8 @@
78/* CKG1 */ 78/* CKG1 */
79#define ACKMD_MASK 0x00007000 79#define ACKMD_MASK 0x00007000
80#define BPFMD_MASK 0x00000700 80#define BPFMD_MASK 0x00000700
81#define DIMD (1 << 4)
82#define DOMD (1 << 0)
81 83
82/* A/B MST_CTLR */ 84/* A/B MST_CTLR */
83#define BP (1 << 4) /* Fix the signal of Biphase output */ 85#define BP (1 << 4) /* Fix the signal of Biphase output */
@@ -111,6 +113,8 @@
111 113
112#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 114#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
113 115
116typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
117
114/* 118/*
115 * FSI driver use below type name for variable 119 * FSI driver use below type name for variable
116 * 120 *
@@ -128,7 +132,6 @@ struct fsi_stream {
128 struct snd_pcm_substream *substream; 132 struct snd_pcm_substream *substream;
129 133
130 int fifo_max_num; 134 int fifo_max_num;
131 int chan_num;
132 135
133 int buff_offset; 136 int buff_offset;
134 int buff_len; 137 int buff_len;
@@ -143,6 +146,7 @@ struct fsi_priv {
143 void __iomem *base; 146 void __iomem *base;
144 struct fsi_master *master; 147 struct fsi_master *master;
145 148
149 int chan_num;
146 struct fsi_stream playback; 150 struct fsi_stream playback;
147 struct fsi_stream capture; 151 struct fsi_stream capture;
148 152
@@ -252,9 +256,8 @@ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
252 return rtd->cpu_dai; 256 return rtd->cpu_dai;
253} 257}
254 258
255static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) 259static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai)
256{ 260{
257 struct snd_soc_dai *dai = fsi_get_dai(substream);
258 struct fsi_master *master = snd_soc_dai_get_drvdata(dai); 261 struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
259 262
260 if (dai->id == 0) 263 if (dai->id == 0)
@@ -263,11 +266,27 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
263 return &master->fsib; 266 return &master->fsib;
264} 267}
265 268
269static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
270{
271 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
272}
273
274static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
275{
276 if (!master->info)
277 return NULL;
278
279 return master->info->set_rate;
280}
281
266static u32 fsi_get_info_flags(struct fsi_priv *fsi) 282static u32 fsi_get_info_flags(struct fsi_priv *fsi)
267{ 283{
268 int is_porta = fsi_is_port_a(fsi); 284 int is_porta = fsi_is_port_a(fsi);
269 struct fsi_master *master = fsi_get_master(fsi); 285 struct fsi_master *master = fsi_get_master(fsi);
270 286
287 if (!master->info)
288 return 0;
289
271 return is_porta ? master->info->porta_flags : 290 return is_porta ? master->info->porta_flags :
272 master->info->portb_flags; 291 master->info->portb_flags;
273} 292}
@@ -288,21 +307,6 @@ static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
288 return is_play ? &fsi->playback : &fsi->capture; 307 return is_play ? &fsi->playback : &fsi->capture;
289} 308}
290 309
291static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
292{
293 u32 mode;
294 u32 flags = fsi_get_info_flags(fsi);
295
296 mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
297
298 /* return
299 * 1 : master mode
300 * 0 : slave mode
301 */
302
303 return (mode & flags) != mode;
304}
305
306static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) 310static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
307{ 311{
308 int is_porta = fsi_is_port_a(fsi); 312 int is_porta = fsi_is_port_a(fsi);
@@ -357,7 +361,6 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 361static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
358{ 362{
359 u32 status; 363 u32 status;
360 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
361 int data_num; 364 int data_num;
362 365
363 status = is_play ? 366 status = is_play ?
@@ -365,7 +368,7 @@ static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
365 fsi_reg_read(fsi, DIFF_ST); 368 fsi_reg_read(fsi, DIFF_ST);
366 369
367 data_num = 0x1ff & (status >> 8); 370 data_num = 0x1ff & (status >> 8);
368 data_num *= io->chan_num; 371 data_num *= fsi->chan_num;
369 372
370 return data_num; 373 return data_num;
371} 374}
@@ -387,7 +390,7 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
387 struct snd_pcm_substream *substream = io->substream; 390 struct snd_pcm_substream *substream = io->substream;
388 struct snd_pcm_runtime *runtime = substream->runtime; 391 struct snd_pcm_runtime *runtime = substream->runtime;
389 392
390 return frames_to_bytes(runtime, 1) / io->chan_num; 393 return frames_to_bytes(runtime, 1) / fsi->chan_num;
391} 394}
392 395
393static void fsi_count_fifo_err(struct fsi_priv *fsi) 396static void fsi_count_fifo_err(struct fsi_priv *fsi)
@@ -580,10 +583,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
580 * 7 channels: 32 ( 32 x 7 = 224) 583 * 7 channels: 32 ( 32 x 7 = 224)
581 * 8 channels: 32 ( 32 x 8 = 256) 584 * 8 channels: 32 ( 32 x 8 = 256)
582 */ 585 */
583 for (i = 1; i < io->chan_num; i <<= 1) 586 for (i = 1; i < fsi->chan_num; i <<= 1)
584 io->fifo_max_num >>= 1; 587 io->fifo_max_num >>= 1;
585 dev_dbg(dai->dev, "%d channel %d store\n", 588 dev_dbg(dai->dev, "%d channel %d store\n",
586 io->chan_num, io->fifo_max_num); 589 fsi->chan_num, io->fifo_max_num);
587 590
588 /* 591 /*
589 * set interrupt generation factor 592 * set interrupt generation factor
@@ -659,7 +662,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
659 * data_num_max : number of FSI fifo free space 662 * data_num_max : number of FSI fifo free space
660 * data_num : number of ALSA residue data 663 * data_num : number of ALSA residue data
661 */ 664 */
662 data_num_max = io->fifo_max_num * io->chan_num; 665 data_num_max = io->fifo_max_num * fsi->chan_num;
663 data_num_max -= fsi_get_fifo_data_num(fsi, is_play); 666 data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
664 667
665 data_num = data_residue_num; 668 data_num = data_residue_num;
@@ -754,25 +757,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
754 struct snd_soc_dai *dai) 757 struct snd_soc_dai *dai)
755{ 758{
756 struct fsi_priv *fsi = fsi_get_priv(substream); 759 struct fsi_priv *fsi = fsi_get_priv(substream);
757 struct fsi_master *master = fsi_get_master(fsi);
758 struct fsi_stream *io;
759 u32 flags = fsi_get_info_flags(fsi); 760 u32 flags = fsi_get_info_flags(fsi);
760 u32 fmt;
761 u32 data; 761 u32 data;
762 int is_play = fsi_is_play(substream); 762 int is_play = fsi_is_play(substream);
763 int is_master;
764
765 io = fsi_get_stream(fsi, is_play);
766 763
767 pm_runtime_get_sync(dai->dev); 764 pm_runtime_get_sync(dai->dev);
768 765
769 /* CKG1 */
770 data = is_play ? (1 << 0) : (1 << 4);
771 is_master = fsi_is_master_mode(fsi, is_play);
772 if (is_master)
773 fsi_reg_mask_set(fsi, CKG1, data, data);
774 else
775 fsi_reg_mask_set(fsi, CKG1, data, 0);
776 766
777 /* clock inversion (CKG2) */ 767 /* clock inversion (CKG2) */
778 data = 0; 768 data = 0;
@@ -787,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
787 777
788 fsi_reg_write(fsi, CKG2, data); 778 fsi_reg_write(fsi, CKG2, data);
789 779
790 /* do fmt, di fmt */
791 data = 0;
792 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
793 switch (fmt) {
794 case SH_FSI_FMT_MONO:
795 data = CR_MONO;
796 io->chan_num = 1;
797 break;
798 case SH_FSI_FMT_MONO_DELAY:
799 data = CR_MONO_D;
800 io->chan_num = 1;
801 break;
802 case SH_FSI_FMT_PCM:
803 data = CR_PCM;
804 io->chan_num = 2;
805 break;
806 case SH_FSI_FMT_I2S:
807 data = CR_I2S;
808 io->chan_num = 2;
809 break;
810 case SH_FSI_FMT_TDM:
811 io->chan_num = is_play ?
812 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
813 data = CR_TDM | (io->chan_num - 1);
814 break;
815 case SH_FSI_FMT_TDM_DELAY:
816 io->chan_num = is_play ?
817 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
818 data = CR_TDM_D | (io->chan_num - 1);
819 break;
820 case SH_FSI_FMT_SPDIF:
821 if (master->core->ver < 2) {
822 dev_err(dai->dev, "This FSI can not use SPDIF\n");
823 return -EINVAL;
824 }
825 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
826 io->chan_num = 2;
827 fsi_spdif_clk_ctrl(fsi, 1);
828 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
829 break;
830 default:
831 dev_err(dai->dev, "unknown format.\n");
832 return -EINVAL;
833 }
834 is_play ?
835 fsi_reg_write(fsi, DO_FMT, data) :
836 fsi_reg_write(fsi, DI_FMT, data);
837
838 /* irq clear */ 780 /* irq clear */
839 fsi_irq_disable(fsi, is_play); 781 fsi_irq_disable(fsi, is_play);
840 fsi_irq_clear_status(fsi); 782 fsi_irq_clear_status(fsi);
@@ -851,12 +793,12 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
851 struct fsi_priv *fsi = fsi_get_priv(substream); 793 struct fsi_priv *fsi = fsi_get_priv(substream);
852 int is_play = fsi_is_play(substream); 794 int is_play = fsi_is_play(substream);
853 struct fsi_master *master = fsi_get_master(fsi); 795 struct fsi_master *master = fsi_get_master(fsi);
854 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 796 set_rate_func set_rate;
855 797
856 fsi_irq_disable(fsi, is_play); 798 fsi_irq_disable(fsi, is_play);
857 fsi_clk_ctrl(fsi, 0); 799 fsi_clk_ctrl(fsi, 0);
858 800
859 set_rate = master->info->set_rate; 801 set_rate = fsi_get_info_set_rate(master);
860 if (set_rate && fsi->rate) 802 if (set_rate && fsi->rate)
861 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
862 fsi->rate = 0; 804 fsi->rate = 0;
@@ -889,18 +831,100 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
889 return ret; 831 return ret;
890} 832}
891 833
834static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
835{
836 u32 data = 0;
837
838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
839 case SND_SOC_DAIFMT_I2S:
840 data = CR_I2S;
841 fsi->chan_num = 2;
842 break;
843 case SND_SOC_DAIFMT_LEFT_J:
844 data = CR_PCM;
845 fsi->chan_num = 2;
846 break;
847 default:
848 return -EINVAL;
849 }
850
851 fsi_reg_write(fsi, DO_FMT, data);
852 fsi_reg_write(fsi, DI_FMT, data);
853
854 return 0;
855}
856
857static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
858{
859 struct fsi_master *master = fsi_get_master(fsi);
860 u32 data = 0;
861
862 if (master->core->ver < 2)
863 return -EINVAL;
864
865 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
866 fsi->chan_num = 2;
867 fsi_spdif_clk_ctrl(fsi, 1);
868 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
869
870 fsi_reg_write(fsi, DO_FMT, data);
871 fsi_reg_write(fsi, DI_FMT, data);
872
873 return 0;
874}
875
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
879 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0;
881 int ret;
882
883 pm_runtime_get_sync(dai->dev);
884
885 /* set master/slave audio interface */
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD;
889 break;
890 case SND_SOC_DAIFMT_CBS_CFS:
891 break;
892 default:
893 ret = -EINVAL;
894 goto set_fmt_exit;
895 }
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897
898 /* set format */
899 switch (flags & SH_FSI_FMT_MASK) {
900 case SH_FSI_FMT_DAI:
901 ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
902 break;
903 case SH_FSI_FMT_SPDIF:
904 ret = fsi_set_fmt_spdif(fsi);
905 break;
906 default:
907 ret = -EINVAL;
908 }
909
910set_fmt_exit:
911 pm_runtime_put_sync(dai->dev);
912
913 return ret;
914}
915
892static int fsi_dai_hw_params(struct snd_pcm_substream *substream, 916static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
893 struct snd_pcm_hw_params *params, 917 struct snd_pcm_hw_params *params,
894 struct snd_soc_dai *dai) 918 struct snd_soc_dai *dai)
895{ 919{
896 struct fsi_priv *fsi = fsi_get_priv(substream); 920 struct fsi_priv *fsi = fsi_get_priv(substream);
897 struct fsi_master *master = fsi_get_master(fsi); 921 struct fsi_master *master = fsi_get_master(fsi);
898 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 922 set_rate_func set_rate;
899 int fsi_ver = master->core->ver; 923 int fsi_ver = master->core->ver;
900 long rate = params_rate(params); 924 long rate = params_rate(params);
901 int ret; 925 int ret;
902 926
903 set_rate = master->info->set_rate; 927 set_rate = fsi_get_info_set_rate(master);
904 if (!set_rate) 928 if (!set_rate)
905 return 0; 929 return 0;
906 930
@@ -975,6 +999,7 @@ static struct snd_soc_dai_ops fsi_dai_ops = {
975 .startup = fsi_dai_startup, 999 .startup = fsi_dai_startup,
976 .shutdown = fsi_dai_shutdown, 1000 .shutdown = fsi_dai_shutdown,
977 .trigger = fsi_dai_trigger, 1001 .trigger = fsi_dai_trigger,
1002 .set_fmt = fsi_dai_set_fmt,
978 .hw_params = fsi_dai_hw_params, 1003 .hw_params = fsi_dai_hw_params,
979}; 1004};
980 1005
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d97a59f6a249..db66dc44add2 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -18,6 +18,8 @@
18#include <linux/bitmap.h> 18#include <linux/bitmap.h>
19#include <linux/rbtree.h> 19#include <linux/rbtree.h>
20 20
21#include <trace/events/asoc.h>
22
21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
22 unsigned int reg) 24 unsigned int reg)
23{ 25{
@@ -25,7 +27,8 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
25 unsigned int val; 27 unsigned int val;
26 28
27 if (reg >= codec->driver->reg_cache_size || 29 if (reg >= codec->driver->reg_cache_size ||
28 snd_soc_codec_volatile_register(codec, reg)) { 30 snd_soc_codec_volatile_register(codec, reg) ||
31 codec->cache_bypass) {
29 if (codec->cache_only) 32 if (codec->cache_only)
30 return -1; 33 return -1;
31 34
@@ -49,7 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
49 data[1] = value & 0x00ff; 52 data[1] = value & 0x00ff;
50 53
51 if (!snd_soc_codec_volatile_register(codec, reg) && 54 if (!snd_soc_codec_volatile_register(codec, reg) &&
52 reg < codec->driver->reg_cache_size) { 55 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) {
53 ret = snd_soc_cache_write(codec, reg, value); 57 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0) 58 if (ret < 0)
55 return -1; 59 return -1;
@@ -106,7 +110,8 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
106 unsigned int val; 110 unsigned int val;
107 111
108 if (reg >= codec->driver->reg_cache_size || 112 if (reg >= codec->driver->reg_cache_size ||
109 snd_soc_codec_volatile_register(codec, reg)) { 113 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) {
110 if (codec->cache_only) 115 if (codec->cache_only)
111 return -1; 116 return -1;
112 117
@@ -130,7 +135,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
130 data[1] = value & 0x00ff; 135 data[1] = value & 0x00ff;
131 136
132 if (!snd_soc_codec_volatile_register(codec, reg) && 137 if (!snd_soc_codec_volatile_register(codec, reg) &&
133 reg < codec->driver->reg_cache_size) { 138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
134 ret = snd_soc_cache_write(codec, reg, value); 140 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0) 141 if (ret < 0)
136 return -1; 142 return -1;
@@ -191,7 +197,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
191 data[1] = value & 0xff; 197 data[1] = value & 0xff;
192 198
193 if (!snd_soc_codec_volatile_register(codec, reg) && 199 if (!snd_soc_codec_volatile_register(codec, reg) &&
194 reg < codec->driver->reg_cache_size) { 200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
195 ret = snd_soc_cache_write(codec, reg, value); 202 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0) 203 if (ret < 0)
197 return -1; 204 return -1;
@@ -216,7 +223,8 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
216 223
217 reg &= 0xff; 224 reg &= 0xff;
218 if (reg >= codec->driver->reg_cache_size || 225 if (reg >= codec->driver->reg_cache_size ||
219 snd_soc_codec_volatile_register(codec, reg)) { 226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
220 if (codec->cache_only) 228 if (codec->cache_only)
221 return -1; 229 return -1;
222 230
@@ -271,7 +279,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
271 data[2] = value & 0xff; 279 data[2] = value & 0xff;
272 280
273 if (!snd_soc_codec_volatile_register(codec, reg) && 281 if (!snd_soc_codec_volatile_register(codec, reg) &&
274 reg < codec->driver->reg_cache_size) { 282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
275 ret = snd_soc_cache_write(codec, reg, value); 284 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0) 285 if (ret < 0)
277 return -1; 286 return -1;
@@ -295,7 +304,8 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
295 unsigned int val; 304 unsigned int val;
296 305
297 if (reg >= codec->driver->reg_cache_size || 306 if (reg >= codec->driver->reg_cache_size ||
298 snd_soc_codec_volatile_register(codec, reg)) { 307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
299 if (codec->cache_only) 309 if (codec->cache_only)
300 return -1; 310 return -1;
301 311
@@ -450,7 +460,8 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
450 460
451 reg &= 0xff; 461 reg &= 0xff;
452 if (reg >= codec->driver->reg_cache_size || 462 if (reg >= codec->driver->reg_cache_size ||
453 snd_soc_codec_volatile_register(codec, reg)) { 463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
454 if (codec->cache_only) 465 if (codec->cache_only)
455 return -1; 466 return -1;
456 467
@@ -476,7 +487,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
476 487
477 reg &= 0xff; 488 reg &= 0xff;
478 if (!snd_soc_codec_volatile_register(codec, reg) && 489 if (!snd_soc_codec_volatile_register(codec, reg) &&
479 reg < codec->driver->reg_cache_size) { 490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
480 ret = snd_soc_cache_write(codec, reg, value); 492 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0) 493 if (ret < 0)
482 return -1; 494 return -1;
@@ -568,7 +580,8 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
568 unsigned int val; 580 unsigned int val;
569 581
570 if (reg >= codec->driver->reg_cache_size || 582 if (reg >= codec->driver->reg_cache_size ||
571 snd_soc_codec_volatile_register(codec, reg)) { 583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
572 if (codec->cache_only) 585 if (codec->cache_only)
573 return -1; 586 return -1;
574 587
@@ -595,7 +608,8 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
595 data[3] = value & 0xff; 608 data[3] = value & 0xff;
596 609
597 if (!snd_soc_codec_volatile_register(codec, reg) && 610 if (!snd_soc_codec_volatile_register(codec, reg) &&
598 reg < codec->driver->reg_cache_size) { 611 reg < codec->driver->reg_cache_size &&
612 !codec->cache_bypass) {
599 ret = snd_soc_cache_write(codec, reg, value); 613 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0) 614 if (ret < 0)
601 return -1; 615 return -1;
@@ -878,7 +892,9 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
878 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 892 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
879 if (ret) 893 if (ret)
880 return ret; 894 return ret;
895 codec->cache_bypass = 1;
881 ret = snd_soc_write(codec, rbnode->reg, val); 896 ret = snd_soc_write(codec, rbnode->reg, val);
897 codec->cache_bypass = 0;
882 if (ret) 898 if (ret)
883 return ret; 899 return ret;
884 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 900 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -1136,7 +1152,9 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1136 ret = snd_soc_cache_read(codec, i, &val); 1152 ret = snd_soc_cache_read(codec, i, &val);
1137 if (ret) 1153 if (ret)
1138 return ret; 1154 return ret;
1155 codec->cache_bypass = 1;
1139 ret = snd_soc_write(codec, i, val); 1156 ret = snd_soc_write(codec, i, val);
1157 codec->cache_bypass = 0;
1140 if (ret) 1158 if (ret)
1141 return ret; 1159 return ret;
1142 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 1160 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -1585,18 +1603,26 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1585int snd_soc_cache_sync(struct snd_soc_codec *codec) 1603int snd_soc_cache_sync(struct snd_soc_codec *codec)
1586{ 1604{
1587 int ret; 1605 int ret;
1606 const char *name;
1588 1607
1589 if (!codec->cache_sync) { 1608 if (!codec->cache_sync) {
1590 return 0; 1609 return 0;
1591 } 1610 }
1592 1611
1612 if (codec->cache_ops->name)
1613 name = codec->cache_ops->name;
1614 else
1615 name = "unknown";
1616
1593 if (codec->cache_ops && codec->cache_ops->sync) { 1617 if (codec->cache_ops && codec->cache_ops->sync) {
1594 if (codec->cache_ops->name) 1618 if (codec->cache_ops->name)
1595 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", 1619 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1596 codec->cache_ops->name, codec->name); 1620 codec->cache_ops->name, codec->name);
1621 trace_snd_soc_cache_sync(codec, name, "start");
1597 ret = codec->cache_ops->sync(codec); 1622 ret = codec->cache_ops->sync(codec);
1598 if (!ret) 1623 if (!ret)
1599 codec->cache_sync = 0; 1624 codec->cache_sync = 0;
1625 trace_snd_soc_cache_sync(codec, name, "end");
1600 return ret; 1626 return ret;
1601 } 1627 }
1602 1628
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9e68984423b2..205cbd7b149f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -69,10 +69,32 @@ static int pmdown_time = 5000;
69module_param(pmdown_time, int, 0); 69module_param(pmdown_time, int, 0);
70MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 70MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
71 71
72/* returns the minimum number of bytes needed to represent
73 * a particular given value */
74static int min_bytes_needed(unsigned long val)
75{
76 int c = 0;
77 int i;
78
79 for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
80 if (val & (1UL << i))
81 break;
82 c = (sizeof val * 8) - c;
83 if (!c || (c % 8))
84 c = (c + 8) / 8;
85 else
86 c /= 8;
87 return c;
88}
89
72/* codec register dump */ 90/* codec register dump */
73static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 91static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
74{ 92{
75 int ret, i, step = 1, count = 0; 93 int ret, i, step = 1, count = 0;
94 int wordsize, regsize;
95
96 wordsize = codec->driver->reg_word_size * 2;
97 regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
76 98
77 if (!codec->driver->reg_cache_size) 99 if (!codec->driver->reg_cache_size)
78 return 0; 100 return 0;
@@ -80,12 +102,11 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
80 if (codec->driver->reg_cache_step) 102 if (codec->driver->reg_cache_step)
81 step = codec->driver->reg_cache_step; 103 step = codec->driver->reg_cache_step;
82 104
83 count += sprintf(buf, "%s registers\n", codec->name);
84 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 105 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
85 if (codec->readable_register && !codec->readable_register(codec, i)) 106 if (codec->readable_register && !codec->readable_register(codec, i))
86 continue; 107 continue;
87 108
88 count += sprintf(buf + count, "%2x: ", i); 109 count += sprintf(buf + count, "%.*x: ", regsize, i);
89 if (count >= PAGE_SIZE - 1) 110 if (count >= PAGE_SIZE - 1)
90 break; 111 break;
91 112
@@ -101,7 +122,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
101 if (ret >= 0) 122 if (ret >= 0)
102 count += snprintf(buf + count, 123 count += snprintf(buf + count,
103 PAGE_SIZE - count, 124 PAGE_SIZE - count,
104 "%4x", ret); 125 "%.*x", wordsize, ret);
105 else 126 else
106 count += snprintf(buf + count, 127 count += snprintf(buf + count,
107 PAGE_SIZE - count, 128 PAGE_SIZE - count,
@@ -235,6 +256,11 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
235 return; 256 return;
236 } 257 }
237 258
259 debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root,
260 &codec->cache_sync);
261 debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
262 &codec->cache_only);
263
238 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 264 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
239 codec->debugfs_codec_root, 265 codec->debugfs_codec_root,
240 codec, &codec_reg_fops); 266 codec, &codec_reg_fops);
@@ -965,12 +991,11 @@ static struct snd_pcm_ops soc_pcm_ops = {
965 .pointer = soc_pcm_pointer, 991 .pointer = soc_pcm_pointer,
966}; 992};
967 993
968#ifdef CONFIG_PM 994#ifdef CONFIG_PM_SLEEP
969/* powers down audio subsystem for suspend */ 995/* powers down audio subsystem for suspend */
970static int soc_suspend(struct device *dev) 996int snd_soc_suspend(struct device *dev)
971{ 997{
972 struct platform_device *pdev = to_platform_device(dev); 998 struct snd_soc_card *card = dev_get_drvdata(dev);
973 struct snd_soc_card *card = platform_get_drvdata(pdev);
974 struct snd_soc_codec *codec; 999 struct snd_soc_codec *codec;
975 int i; 1000 int i;
976 1001
@@ -1011,7 +1036,7 @@ static int soc_suspend(struct device *dev)
1011 } 1036 }
1012 1037
1013 if (card->suspend_pre) 1038 if (card->suspend_pre)
1014 card->suspend_pre(pdev, PMSG_SUSPEND); 1039 card->suspend_pre(card);
1015 1040
1016 for (i = 0; i < card->num_rtd; i++) { 1041 for (i = 0; i < card->num_rtd; i++) {
1017 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 1042 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
@@ -1078,10 +1103,11 @@ static int soc_suspend(struct device *dev)
1078 } 1103 }
1079 1104
1080 if (card->suspend_post) 1105 if (card->suspend_post)
1081 card->suspend_post(pdev, PMSG_SUSPEND); 1106 card->suspend_post(card);
1082 1107
1083 return 0; 1108 return 0;
1084} 1109}
1110EXPORT_SYMBOL_GPL(snd_soc_suspend);
1085 1111
1086/* deferred resume work, so resume can complete before we finished 1112/* deferred resume work, so resume can complete before we finished
1087 * setting our codec back up, which can be very slow on I2C 1113 * setting our codec back up, which can be very slow on I2C
@@ -1090,7 +1116,6 @@ static void soc_resume_deferred(struct work_struct *work)
1090{ 1116{
1091 struct snd_soc_card *card = 1117 struct snd_soc_card *card =
1092 container_of(work, struct snd_soc_card, deferred_resume_work); 1118 container_of(work, struct snd_soc_card, deferred_resume_work);
1093 struct platform_device *pdev = to_platform_device(card->dev);
1094 struct snd_soc_codec *codec; 1119 struct snd_soc_codec *codec;
1095 int i; 1120 int i;
1096 1121
@@ -1104,7 +1129,7 @@ static void soc_resume_deferred(struct work_struct *work)
1104 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); 1129 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
1105 1130
1106 if (card->resume_pre) 1131 if (card->resume_pre)
1107 card->resume_pre(pdev); 1132 card->resume_pre(card);
1108 1133
1109 /* resume AC97 DAIs */ 1134 /* resume AC97 DAIs */
1110 for (i = 0; i < card->num_rtd; i++) { 1135 for (i = 0; i < card->num_rtd; i++) {
@@ -1179,7 +1204,7 @@ static void soc_resume_deferred(struct work_struct *work)
1179 } 1204 }
1180 1205
1181 if (card->resume_post) 1206 if (card->resume_post)
1182 card->resume_post(pdev); 1207 card->resume_post(card);
1183 1208
1184 dev_dbg(card->dev, "resume work completed\n"); 1209 dev_dbg(card->dev, "resume work completed\n");
1185 1210
@@ -1188,10 +1213,9 @@ static void soc_resume_deferred(struct work_struct *work)
1188} 1213}
1189 1214
1190/* powers up audio subsystem after a suspend */ 1215/* powers up audio subsystem after a suspend */
1191static int soc_resume(struct device *dev) 1216int snd_soc_resume(struct device *dev)
1192{ 1217{
1193 struct platform_device *pdev = to_platform_device(dev); 1218 struct snd_soc_card *card = dev_get_drvdata(dev);
1194 struct snd_soc_card *card = platform_get_drvdata(pdev);
1195 int i; 1219 int i;
1196 1220
1197 /* AC97 devices might have other drivers hanging off them so 1221 /* AC97 devices might have other drivers hanging off them so
@@ -1213,9 +1237,10 @@ static int soc_resume(struct device *dev)
1213 1237
1214 return 0; 1238 return 0;
1215} 1239}
1240EXPORT_SYMBOL_GPL(snd_soc_resume);
1216#else 1241#else
1217#define soc_suspend NULL 1242#define snd_soc_suspend NULL
1218#define soc_resume NULL 1243#define snd_soc_resume NULL
1219#endif 1244#endif
1220 1245
1221static struct snd_soc_dai_ops null_dai_ops = { 1246static struct snd_soc_dai_ops null_dai_ops = {
@@ -1408,26 +1433,31 @@ static int soc_probe_codec(struct snd_soc_card *card,
1408 codec->dapm.card = card; 1433 codec->dapm.card = card;
1409 soc_set_name_prefix(card, codec); 1434 soc_set_name_prefix(card, codec);
1410 1435
1436 if (!try_module_get(codec->dev->driver->owner))
1437 return -ENODEV;
1438
1411 if (codec->driver->probe) { 1439 if (codec->driver->probe) {
1412 ret = codec->driver->probe(codec); 1440 ret = codec->driver->probe(codec);
1413 if (ret < 0) { 1441 if (ret < 0) {
1414 dev_err(codec->dev, 1442 dev_err(codec->dev,
1415 "asoc: failed to probe CODEC %s: %d\n", 1443 "asoc: failed to probe CODEC %s: %d\n",
1416 codec->name, ret); 1444 codec->name, ret);
1417 return ret; 1445 goto err_probe;
1418 } 1446 }
1419 } 1447 }
1420 1448
1421 soc_init_codec_debugfs(codec); 1449 soc_init_codec_debugfs(codec);
1422 1450
1423 /* mark codec as probed and add to card codec list */ 1451 /* mark codec as probed and add to card codec list */
1424 if (!try_module_get(codec->dev->driver->owner))
1425 return -ENODEV;
1426
1427 codec->probed = 1; 1452 codec->probed = 1;
1428 list_add(&codec->card_list, &card->codec_dev_list); 1453 list_add(&codec->card_list, &card->codec_dev_list);
1429 list_add(&codec->dapm.list, &card->dapm_list); 1454 list_add(&codec->dapm.list, &card->dapm_list);
1430 1455
1456 return 0;
1457
1458err_probe:
1459 module_put(codec->dev->driver->owner);
1460
1431 return ret; 1461 return ret;
1432} 1462}
1433 1463
@@ -1545,19 +1575,19 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1545 1575
1546 /* probe the platform */ 1576 /* probe the platform */
1547 if (!platform->probed) { 1577 if (!platform->probed) {
1578 if (!try_module_get(platform->dev->driver->owner))
1579 return -ENODEV;
1580
1548 if (platform->driver->probe) { 1581 if (platform->driver->probe) {
1549 ret = platform->driver->probe(platform); 1582 ret = platform->driver->probe(platform);
1550 if (ret < 0) { 1583 if (ret < 0) {
1551 printk(KERN_ERR "asoc: failed to probe platform %s\n", 1584 printk(KERN_ERR "asoc: failed to probe platform %s\n",
1552 platform->name); 1585 platform->name);
1586 module_put(platform->dev->driver->owner);
1553 return ret; 1587 return ret;
1554 } 1588 }
1555 } 1589 }
1556 /* mark platform as probed and add to card platform list */ 1590 /* mark platform as probed and add to card platform list */
1557
1558 if (!try_module_get(platform->dev->driver->owner))
1559 return -ENODEV;
1560
1561 platform->probed = 1; 1591 platform->probed = 1;
1562 list_add(&platform->card_list, &card->platform_dev_list); 1592 list_add(&platform->card_list, &card->platform_dev_list);
1563 } 1593 }
@@ -1666,9 +1696,6 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1666 goto out; 1696 goto out;
1667 1697
1668found: 1698found:
1669 if (!try_module_get(codec->dev->driver->owner))
1670 return -ENODEV;
1671
1672 ret = soc_probe_codec(card, codec); 1699 ret = soc_probe_codec(card, codec);
1673 if (ret < 0) 1700 if (ret < 0)
1674 return ret; 1701 return ret;
@@ -1718,7 +1745,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1718 1745
1719static void snd_soc_instantiate_card(struct snd_soc_card *card) 1746static void snd_soc_instantiate_card(struct snd_soc_card *card)
1720{ 1747{
1721 struct platform_device *pdev = to_platform_device(card->dev);
1722 struct snd_soc_codec *codec; 1748 struct snd_soc_codec *codec;
1723 struct snd_soc_codec_conf *codec_conf; 1749 struct snd_soc_codec_conf *codec_conf;
1724 enum snd_soc_compress_type compress_type; 1750 enum snd_soc_compress_type compress_type;
@@ -1782,7 +1808,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1782 1808
1783 /* initialise the sound card only once */ 1809 /* initialise the sound card only once */
1784 if (card->probe) { 1810 if (card->probe) {
1785 ret = card->probe(pdev); 1811 ret = card->probe(card);
1786 if (ret < 0) 1812 if (ret < 0)
1787 goto card_probe_error; 1813 goto card_probe_error;
1788 } 1814 }
@@ -1843,7 +1869,7 @@ probe_dai_err:
1843 1869
1844card_probe_error: 1870card_probe_error:
1845 if (card->remove) 1871 if (card->remove)
1846 card->remove(pdev); 1872 card->remove(card);
1847 1873
1848 snd_card_free(card->snd_card); 1874 snd_card_free(card->snd_card);
1849 1875
@@ -1876,7 +1902,6 @@ static int soc_probe(struct platform_device *pdev)
1876 1902
1877 /* Bodge while we unpick instantiation */ 1903 /* Bodge while we unpick instantiation */
1878 card->dev = &pdev->dev; 1904 card->dev = &pdev->dev;
1879 snd_soc_initialize_card_lists(card);
1880 1905
1881 ret = snd_soc_register_card(card); 1906 ret = snd_soc_register_card(card);
1882 if (ret != 0) { 1907 if (ret != 0) {
@@ -1889,7 +1914,6 @@ static int soc_probe(struct platform_device *pdev)
1889 1914
1890static int soc_cleanup_card_resources(struct snd_soc_card *card) 1915static int soc_cleanup_card_resources(struct snd_soc_card *card)
1891{ 1916{
1892 struct platform_device *pdev = to_platform_device(card->dev);
1893 int i; 1917 int i;
1894 1918
1895 /* make sure any delayed work runs */ 1919 /* make sure any delayed work runs */
@@ -1910,7 +1934,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1910 1934
1911 /* remove the card */ 1935 /* remove the card */
1912 if (card->remove) 1936 if (card->remove)
1913 card->remove(pdev); 1937 card->remove(card);
1914 1938
1915 kfree(card->rtd); 1939 kfree(card->rtd);
1916 snd_card_free(card->snd_card); 1940 snd_card_free(card->snd_card);
@@ -1927,10 +1951,9 @@ static int soc_remove(struct platform_device *pdev)
1927 return 0; 1951 return 0;
1928} 1952}
1929 1953
1930static int soc_poweroff(struct device *dev) 1954int snd_soc_poweroff(struct device *dev)
1931{ 1955{
1932 struct platform_device *pdev = to_platform_device(dev); 1956 struct snd_soc_card *card = dev_get_drvdata(dev);
1933 struct snd_soc_card *card = platform_get_drvdata(pdev);
1934 int i; 1957 int i;
1935 1958
1936 if (!card->instantiated) 1959 if (!card->instantiated)
@@ -1947,11 +1970,12 @@ static int soc_poweroff(struct device *dev)
1947 1970
1948 return 0; 1971 return 0;
1949} 1972}
1973EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1950 1974
1951static const struct dev_pm_ops soc_pm_ops = { 1975const struct dev_pm_ops snd_soc_pm_ops = {
1952 .suspend = soc_suspend, 1976 .suspend = snd_soc_suspend,
1953 .resume = soc_resume, 1977 .resume = snd_soc_resume,
1954 .poweroff = soc_poweroff, 1978 .poweroff = snd_soc_poweroff,
1955}; 1979};
1956 1980
1957/* ASoC platform driver */ 1981/* ASoC platform driver */
@@ -1959,7 +1983,7 @@ static struct platform_driver soc_driver = {
1959 .driver = { 1983 .driver = {
1960 .name = "soc-audio", 1984 .name = "soc-audio",
1961 .owner = THIS_MODULE, 1985 .owner = THIS_MODULE,
1962 .pm = &soc_pm_ops, 1986 .pm = &snd_soc_pm_ops,
1963 }, 1987 },
1964 .probe = soc_probe, 1988 .probe = soc_probe,
1965 .remove = soc_remove, 1989 .remove = soc_remove,
@@ -2029,7 +2053,8 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2029 * 2053 *
2030 * Boolean function indiciating if a CODEC register is volatile. 2054 * Boolean function indiciating if a CODEC register is volatile.
2031 */ 2055 */
2032int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg) 2056int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2057 unsigned int reg)
2033{ 2058{
2034 if (codec->volatile_register) 2059 if (codec->volatile_register)
2035 return codec->volatile_register(codec, reg); 2060 return codec->volatile_register(codec, reg);
@@ -3117,6 +3142,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
3117 if (!card->name || !card->dev) 3142 if (!card->name || !card->dev)
3118 return -EINVAL; 3143 return -EINVAL;
3119 3144
3145 snd_soc_initialize_card_lists(card);
3146
3120 soc_init_card_debugfs(card); 3147 soc_init_card_debugfs(card);
3121 3148
3122 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * 3149 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
@@ -3496,6 +3523,7 @@ int snd_soc_register_codec(struct device *dev,
3496 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3523 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3497 codec->dapm.dev = dev; 3524 codec->dapm.dev = dev;
3498 codec->dapm.codec = codec; 3525 codec->dapm.codec = codec;
3526 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3499 codec->dev = dev; 3527 codec->dev = dev;
3500 codec->driver = codec_drv; 3528 codec->driver = codec_drv;
3501 codec->num_dai = num_dai; 3529 codec->num_dai = num_dai;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 499730ab5638..d0342aab2c15 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -726,10 +726,23 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
726 726
727static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 727static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
728 struct snd_soc_dapm_widget *b, 728 struct snd_soc_dapm_widget *b,
729 int sort[]) 729 bool power_up)
730{ 730{
731 int *sort;
732
733 if (power_up)
734 sort = dapm_up_seq;
735 else
736 sort = dapm_down_seq;
737
731 if (sort[a->id] != sort[b->id]) 738 if (sort[a->id] != sort[b->id])
732 return sort[a->id] - sort[b->id]; 739 return sort[a->id] - sort[b->id];
740 if (a->subseq != b->subseq) {
741 if (power_up)
742 return a->subseq - b->subseq;
743 else
744 return b->subseq - a->subseq;
745 }
733 if (a->reg != b->reg) 746 if (a->reg != b->reg)
734 return a->reg - b->reg; 747 return a->reg - b->reg;
735 if (a->dapm != b->dapm) 748 if (a->dapm != b->dapm)
@@ -741,12 +754,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
741/* Insert a widget in order into a DAPM power sequence. */ 754/* Insert a widget in order into a DAPM power sequence. */
742static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 755static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
743 struct list_head *list, 756 struct list_head *list,
744 int sort[]) 757 bool power_up)
745{ 758{
746 struct snd_soc_dapm_widget *w; 759 struct snd_soc_dapm_widget *w;
747 760
748 list_for_each_entry(w, list, power_list) 761 list_for_each_entry(w, list, power_list)
749 if (dapm_seq_compare(new_widget, w, sort) < 0) { 762 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
750 list_add_tail(&new_widget->power_list, &w->power_list); 763 list_add_tail(&new_widget->power_list, &w->power_list);
751 return; 764 return;
752 } 765 }
@@ -857,26 +870,42 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
857 * handled. 870 * handled.
858 */ 871 */
859static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 872static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
860 struct list_head *list, int event, int sort[]) 873 struct list_head *list, int event, bool power_up)
861{ 874{
862 struct snd_soc_dapm_widget *w, *n; 875 struct snd_soc_dapm_widget *w, *n;
863 LIST_HEAD(pending); 876 LIST_HEAD(pending);
864 int cur_sort = -1; 877 int cur_sort = -1;
878 int cur_subseq = -1;
865 int cur_reg = SND_SOC_NOPM; 879 int cur_reg = SND_SOC_NOPM;
866 struct snd_soc_dapm_context *cur_dapm = NULL; 880 struct snd_soc_dapm_context *cur_dapm = NULL;
867 int ret; 881 int ret, i;
882 int *sort;
883
884 if (power_up)
885 sort = dapm_up_seq;
886 else
887 sort = dapm_down_seq;
868 888
869 list_for_each_entry_safe(w, n, list, power_list) { 889 list_for_each_entry_safe(w, n, list, power_list) {
870 ret = 0; 890 ret = 0;
871 891
872 /* Do we need to apply any queued changes? */ 892 /* Do we need to apply any queued changes? */
873 if (sort[w->id] != cur_sort || w->reg != cur_reg || 893 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
874 w->dapm != cur_dapm) { 894 w->dapm != cur_dapm || w->subseq != cur_subseq) {
875 if (!list_empty(&pending)) 895 if (!list_empty(&pending))
876 dapm_seq_run_coalesced(cur_dapm, &pending); 896 dapm_seq_run_coalesced(cur_dapm, &pending);
877 897
898 if (cur_dapm && cur_dapm->seq_notifier) {
899 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
900 if (sort[i] == cur_sort)
901 cur_dapm->seq_notifier(cur_dapm,
902 i,
903 cur_subseq);
904 }
905
878 INIT_LIST_HEAD(&pending); 906 INIT_LIST_HEAD(&pending);
879 cur_sort = -1; 907 cur_sort = -1;
908 cur_subseq = -1;
880 cur_reg = SND_SOC_NOPM; 909 cur_reg = SND_SOC_NOPM;
881 cur_dapm = NULL; 910 cur_dapm = NULL;
882 } 911 }
@@ -921,6 +950,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
921 default: 950 default:
922 /* Queue it up for application */ 951 /* Queue it up for application */
923 cur_sort = sort[w->id]; 952 cur_sort = sort[w->id];
953 cur_subseq = w->subseq;
924 cur_reg = w->reg; 954 cur_reg = w->reg;
925 cur_dapm = w->dapm; 955 cur_dapm = w->dapm;
926 list_move(&w->power_list, &pending); 956 list_move(&w->power_list, &pending);
@@ -934,6 +964,13 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
934 964
935 if (!list_empty(&pending)) 965 if (!list_empty(&pending))
936 dapm_seq_run_coalesced(dapm, &pending); 966 dapm_seq_run_coalesced(dapm, &pending);
967
968 if (cur_dapm && cur_dapm->seq_notifier) {
969 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
970 if (sort[i] == cur_sort)
971 cur_dapm->seq_notifier(cur_dapm,
972 i, cur_subseq);
973 }
937} 974}
938 975
939static void dapm_widget_update(struct snd_soc_dapm_context *dapm) 976static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
@@ -1002,10 +1039,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1002 list_for_each_entry(w, &card->widgets, list) { 1039 list_for_each_entry(w, &card->widgets, list) {
1003 switch (w->id) { 1040 switch (w->id) {
1004 case snd_soc_dapm_pre: 1041 case snd_soc_dapm_pre:
1005 dapm_seq_insert(w, &down_list, dapm_down_seq); 1042 dapm_seq_insert(w, &down_list, false);
1006 break; 1043 break;
1007 case snd_soc_dapm_post: 1044 case snd_soc_dapm_post:
1008 dapm_seq_insert(w, &up_list, dapm_up_seq); 1045 dapm_seq_insert(w, &up_list, true);
1009 break; 1046 break;
1010 1047
1011 default: 1048 default:
@@ -1025,9 +1062,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1025 trace_snd_soc_dapm_widget_power(w, power); 1062 trace_snd_soc_dapm_widget_power(w, power);
1026 1063
1027 if (power) 1064 if (power)
1028 dapm_seq_insert(w, &up_list, dapm_up_seq); 1065 dapm_seq_insert(w, &up_list, true);
1029 else 1066 else
1030 dapm_seq_insert(w, &down_list, dapm_down_seq); 1067 dapm_seq_insert(w, &down_list, false);
1031 1068
1032 w->power = power; 1069 w->power = power;
1033 break; 1070 break;
@@ -1086,12 +1123,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1086 } 1123 }
1087 1124
1088 /* Power down widgets first; try to avoid amplifying pops. */ 1125 /* Power down widgets first; try to avoid amplifying pops. */
1089 dapm_seq_run(dapm, &down_list, event, dapm_down_seq); 1126 dapm_seq_run(dapm, &down_list, event, false);
1090 1127
1091 dapm_widget_update(dapm); 1128 dapm_widget_update(dapm);
1092 1129
1093 /* Now power up. */ 1130 /* Now power up. */
1094 dapm_seq_run(dapm, &up_list, event, dapm_up_seq); 1131 dapm_seq_run(dapm, &up_list, event, true);
1095 1132
1096 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1133 list_for_each_entry(d, &dapm->card->dapm_list, list) {
1097 /* If we just powered the last thing off drop to standby bias */ 1134 /* If we just powered the last thing off drop to standby bias */
@@ -1742,7 +1779,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1742 int max = mc->max; 1779 int max = mc->max;
1743 unsigned int mask = (1 << fls(max)) - 1; 1780 unsigned int mask = (1 << fls(max)) - 1;
1744 unsigned int invert = mc->invert; 1781 unsigned int invert = mc->invert;
1745 unsigned int val, val_mask; 1782 unsigned int val;
1746 int connect, change; 1783 int connect, change;
1747 struct snd_soc_dapm_update update; 1784 struct snd_soc_dapm_update update;
1748 1785
@@ -1750,13 +1787,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1750 1787
1751 if (invert) 1788 if (invert)
1752 val = max - val; 1789 val = max - val;
1753 val_mask = mask << shift; 1790 mask = mask << shift;
1754 val = val << shift; 1791 val = val << shift;
1755 1792
1756 mutex_lock(&widget->codec->mutex); 1793 mutex_lock(&widget->codec->mutex);
1757 widget->value = val; 1794 widget->value = val;
1758 1795
1759 change = snd_soc_test_bits(widget->codec, reg, val_mask, val); 1796 change = snd_soc_test_bits(widget->codec, reg, mask, val);
1760 if (change) { 1797 if (change) {
1761 if (val) 1798 if (val)
1762 /* new connection */ 1799 /* new connection */
@@ -2372,7 +2409,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2372 if (w->dapm != dapm) 2409 if (w->dapm != dapm)
2373 continue; 2410 continue;
2374 if (w->power) { 2411 if (w->power) {
2375 dapm_seq_insert(w, &down_list, dapm_down_seq); 2412 dapm_seq_insert(w, &down_list, false);
2376 w->power = 0; 2413 w->power = 0;
2377 powerdown = 1; 2414 powerdown = 1;
2378 } 2415 }
@@ -2383,7 +2420,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2383 */ 2420 */
2384 if (powerdown) { 2421 if (powerdown) {
2385 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2422 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
2386 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); 2423 dapm_seq_run(dapm, &down_list, 0, false);
2387 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); 2424 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
2388 } 2425 }
2389} 2426}
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 1d07b931f3d8..3f45e6a439bf 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -28,26 +28,9 @@ int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
28{ 28{
29 int sample_size; 29 int sample_size;
30 30
31 switch (params_format(params)) { 31 sample_size = snd_pcm_format_width(params_format(params));
32 case SNDRV_PCM_FORMAT_S16_LE: 32 if (sample_size < 0)
33 case SNDRV_PCM_FORMAT_S16_BE: 33 return sample_size;
34 sample_size = 16;
35 break;
36 case SNDRV_PCM_FORMAT_S20_3LE:
37 case SNDRV_PCM_FORMAT_S20_3BE:
38 sample_size = 20;
39 break;
40 case SNDRV_PCM_FORMAT_S24_LE:
41 case SNDRV_PCM_FORMAT_S24_BE:
42 sample_size = 24;
43 break;
44 case SNDRV_PCM_FORMAT_S32_LE:
45 case SNDRV_PCM_FORMAT_S32_BE:
46 sample_size = 32;
47 break;
48 default:
49 return -ENOTSUPP;
50 }
51 34
52 return snd_soc_calc_frame_size(sample_size, params_channels(params), 35 return snd_soc_calc_frame_size(sample_size, params_channels(params),
53 1); 36 1);
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
index b160b7113f45..11e2cb825664 100644
--- a/sound/soc/tegra/harmony.c
+++ b/sound/soc/tegra/harmony.c
@@ -2,7 +2,7 @@
2 * harmony.c - Harmony machine ASoC driver 2 * harmony.c - Harmony machine ASoC driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,7 +29,14 @@
29 */ 29 */
30 30
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32
32#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/harmony_audio.h>
39
33#include <sound/core.h> 40#include <sound/core.h>
34#include <sound/pcm.h> 41#include <sound/pcm.h>
35#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
@@ -40,9 +47,13 @@
40#include "tegra_pcm.h" 47#include "tegra_pcm.h"
41#include "tegra_asoc_utils.h" 48#include "tegra_asoc_utils.h"
42 49
43#define PREFIX "ASoC Harmony: " 50#define DRV_NAME "tegra-snd-harmony"
44 51
45static struct platform_device *harmony_snd_device; 52struct tegra_harmony {
53 struct tegra_asoc_utils_data util_data;
54 struct harmony_audio_platform_data *pdata;
55 int gpio_spkr_en_requested;
56};
46 57
47static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, 58static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
48 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
@@ -50,6 +61,9 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *codec_dai = rtd->codec_dai; 62 struct snd_soc_dai *codec_dai = rtd->codec_dai;
52 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 63 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
64 struct snd_soc_codec *codec = rtd->codec;
65 struct snd_soc_card *card = codec->card;
66 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
53 int srate, mclk, mclk_change; 67 int srate, mclk, mclk_change;
54 int err; 68 int err;
55 69
@@ -68,9 +82,10 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
68 while (mclk < 6000000) 82 while (mclk < 6000000)
69 mclk *= 2; 83 mclk *= 2;
70 84
71 err = tegra_asoc_utils_set_rate(srate, mclk, &mclk_change); 85 err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk,
86 &mclk_change);
72 if (err < 0) { 87 if (err < 0) {
73 pr_err(PREFIX "Can't configure clocks\n"); 88 dev_err(card->dev, "Can't configure clocks\n");
74 return err; 89 return err;
75 } 90 }
76 91
@@ -79,7 +94,7 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
79 SND_SOC_DAIFMT_NB_NF | 94 SND_SOC_DAIFMT_NB_NF |
80 SND_SOC_DAIFMT_CBS_CFS); 95 SND_SOC_DAIFMT_CBS_CFS);
81 if (err < 0) { 96 if (err < 0) {
82 pr_err(PREFIX "codec_dai fmt not set\n"); 97 dev_err(card->dev, "codec_dai fmt not set\n");
83 return err; 98 return err;
84 } 99 }
85 100
@@ -88,16 +103,17 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
88 SND_SOC_DAIFMT_NB_NF | 103 SND_SOC_DAIFMT_NB_NF |
89 SND_SOC_DAIFMT_CBS_CFS); 104 SND_SOC_DAIFMT_CBS_CFS);
90 if (err < 0) { 105 if (err < 0) {
91 pr_err(PREFIX "cpu_dai fmt not set\n"); 106 dev_err(card->dev, "cpu_dai fmt not set\n");
92 return err; 107 return err;
93 } 108 }
94 109
95 if (mclk_change) { 110 if (mclk_change) {
96 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); 111 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
97 if (err < 0) { 112 SND_SOC_CLOCK_IN);
98 pr_err(PREFIX "codec_dai clock not set\n"); 113 if (err < 0) {
99 return err; 114 dev_err(card->dev, "codec_dai clock not set\n");
100 } 115 return err;
116 }
101 } 117 }
102 118
103 return 0; 119 return 0;
@@ -107,7 +123,22 @@ static struct snd_soc_ops harmony_asoc_ops = {
107 .hw_params = harmony_asoc_hw_params, 123 .hw_params = harmony_asoc_hw_params,
108}; 124};
109 125
126static int harmony_event_int_spk(struct snd_soc_dapm_widget *w,
127 struct snd_kcontrol *k, int event)
128{
129 struct snd_soc_codec *codec = w->codec;
130 struct snd_soc_card *card = codec->card;
131 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
132 struct harmony_audio_platform_data *pdata = harmony->pdata;
133
134 gpio_set_value_cansleep(pdata->gpio_spkr_en,
135 SND_SOC_DAPM_EVENT_ON(event));
136
137 return 0;
138}
139
110static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = { 140static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
141 SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk),
111 SND_SOC_DAPM_HP("Headphone Jack", NULL), 142 SND_SOC_DAPM_HP("Headphone Jack", NULL),
112 SND_SOC_DAPM_MIC("Mic Jack", NULL), 143 SND_SOC_DAPM_MIC("Mic Jack", NULL),
113}; 144};
@@ -115,6 +146,10 @@ static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
115static const struct snd_soc_dapm_route harmony_audio_map[] = { 146static const struct snd_soc_dapm_route harmony_audio_map[] = {
116 {"Headphone Jack", NULL, "HPOUTR"}, 147 {"Headphone Jack", NULL, "HPOUTR"},
117 {"Headphone Jack", NULL, "HPOUTL"}, 148 {"Headphone Jack", NULL, "HPOUTL"},
149 {"Int Spk", NULL, "ROP"},
150 {"Int Spk", NULL, "RON"},
151 {"Int Spk", NULL, "LOP"},
152 {"Int Spk", NULL, "LON"},
118 {"Mic Bias", NULL, "Mic Jack"}, 153 {"Mic Bias", NULL, "Mic Jack"},
119 {"IN1L", NULL, "Mic Bias"}, 154 {"IN1L", NULL, "Mic Bias"},
120}; 155};
@@ -123,6 +158,19 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
123{ 158{
124 struct snd_soc_codec *codec = rtd->codec; 159 struct snd_soc_codec *codec = rtd->codec;
125 struct snd_soc_dapm_context *dapm = &codec->dapm; 160 struct snd_soc_dapm_context *dapm = &codec->dapm;
161 struct snd_soc_card *card = codec->card;
162 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
163 struct harmony_audio_platform_data *pdata = harmony->pdata;
164 int ret;
165
166 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
167 if (ret) {
168 dev_err(card->dev, "cannot get spkr_en gpio\n");
169 return ret;
170 }
171 harmony->gpio_spkr_en_requested = 1;
172
173 gpio_direction_output(pdata->gpio_spkr_en, 0);
126 174
127 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets, 175 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
128 ARRAY_SIZE(harmony_dapm_widgets)); 176 ARRAY_SIZE(harmony_dapm_widgets));
@@ -131,6 +179,7 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
131 ARRAY_SIZE(harmony_audio_map)); 179 ARRAY_SIZE(harmony_audio_map));
132 180
133 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 181 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
182 snd_soc_dapm_enable_pin(dapm, "Int Spk");
134 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 183 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
135 snd_soc_dapm_sync(dapm); 184 snd_soc_dapm_sync(dapm);
136 185
@@ -154,56 +203,101 @@ static struct snd_soc_card snd_soc_harmony = {
154 .num_links = 1, 203 .num_links = 1,
155}; 204};
156 205
157static int __init harmony_soc_modinit(void) 206static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev)
158{ 207{
208 struct snd_soc_card *card = &snd_soc_harmony;
209 struct tegra_harmony *harmony;
210 struct harmony_audio_platform_data *pdata;
159 int ret; 211 int ret;
160 212
161 if (!machine_is_harmony()) { 213 if (!machine_is_harmony()) {
162 pr_err(PREFIX "Not running on Tegra Harmony!\n"); 214 dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
163 return -ENODEV; 215 return -ENODEV;
164 } 216 }
165 217
166 ret = tegra_asoc_utils_init(); 218 pdata = pdev->dev.platform_data;
167 if (ret) { 219 if (!pdata) {
168 return ret; 220 dev_err(&pdev->dev, "no platform data supplied\n");
221 return -EINVAL;
169 } 222 }
170 223
171 /* 224 harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL);
172 * Create and register platform device 225 if (!harmony) {
173 */ 226 dev_err(&pdev->dev, "Can't allocate tegra_harmony\n");
174 harmony_snd_device = platform_device_alloc("soc-audio", -1); 227 return -ENOMEM;
175 if (harmony_snd_device == NULL) {
176 pr_err(PREFIX "platform_device_alloc failed\n");
177 ret = -ENOMEM;
178 goto err_clock_utils;
179 } 228 }
180 229
181 platform_set_drvdata(harmony_snd_device, &snd_soc_harmony); 230 harmony->pdata = pdata;
231
232 ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev);
233 if (ret)
234 goto err_free_harmony;
235
236 card->dev = &pdev->dev;
237 platform_set_drvdata(pdev, card);
238 snd_soc_card_set_drvdata(card, harmony);
182 239
183 ret = platform_device_add(harmony_snd_device); 240 ret = snd_soc_register_card(card);
184 if (ret) { 241 if (ret) {
185 pr_err(PREFIX "platform_device_add failed (%d)\n", 242 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
186 ret); 243 ret);
187 goto err_device_put; 244 goto err_clear_drvdata;
188 } 245 }
189 246
190 return 0; 247 return 0;
191 248
192err_device_put: 249err_clear_drvdata:
193 platform_device_put(harmony_snd_device); 250 snd_soc_card_set_drvdata(card, NULL);
194err_clock_utils: 251 platform_set_drvdata(pdev, NULL);
195 tegra_asoc_utils_fini(); 252 card->dev = NULL;
253 tegra_asoc_utils_fini(&harmony->util_data);
254err_free_harmony:
255 kfree(harmony);
196 return ret; 256 return ret;
197} 257}
198module_init(harmony_soc_modinit);
199 258
200static void __exit harmony_soc_modexit(void) 259static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev)
201{ 260{
202 platform_device_unregister(harmony_snd_device); 261 struct snd_soc_card *card = platform_get_drvdata(pdev);
262 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
263 struct harmony_audio_platform_data *pdata = harmony->pdata;
264
265 snd_soc_unregister_card(card);
266
267 snd_soc_card_set_drvdata(card, NULL);
268 platform_set_drvdata(pdev, NULL);
269 card->dev = NULL;
203 270
204 tegra_asoc_utils_fini(); 271 tegra_asoc_utils_fini(&harmony->util_data);
272
273 if (harmony->gpio_spkr_en_requested)
274 gpio_free(pdata->gpio_spkr_en);
275
276 kfree(harmony);
277
278 return 0;
279}
280
281static struct platform_driver tegra_snd_harmony_driver = {
282 .driver = {
283 .name = DRV_NAME,
284 .owner = THIS_MODULE,
285 },
286 .probe = tegra_snd_harmony_probe,
287 .remove = __devexit_p(tegra_snd_harmony_remove),
288};
289
290static int __init snd_tegra_harmony_init(void)
291{
292 return platform_driver_register(&tegra_snd_harmony_driver);
293}
294module_init(snd_tegra_harmony_init);
295
296static void __exit snd_tegra_harmony_exit(void)
297{
298 platform_driver_unregister(&tegra_snd_harmony_driver);
205} 299}
206module_exit(harmony_soc_modexit); 300module_exit(snd_tegra_harmony_exit);
207 301
208MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 302MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
209MODULE_DESCRIPTION("Harmony machine ASoC driver"); 303MODULE_DESCRIPTION("Harmony machine ASoC driver");
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index cfe2ea890dc0..cb4fc13c7d22 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -21,20 +21,14 @@
21 */ 21 */
22 22
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/device.h>
24#include <linux/err.h> 25#include <linux/err.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26 27
27#include "tegra_asoc_utils.h" 28#include "tegra_asoc_utils.h"
28 29
29#define PREFIX "ASoC Tegra: " 30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
30 31 int mclk, int *mclk_change)
31static struct clk *clk_pll_a;
32static struct clk *clk_pll_a_out0;
33static struct clk *clk_cdev1;
34
35static int set_baseclock, set_mclk;
36
37int tegra_asoc_utils_set_rate(int srate, int mclk, int *mclk_change)
38{ 32{
39 int new_baseclock; 33 int new_baseclock;
40 int err; 34 int err;
@@ -58,95 +52,98 @@ int tegra_asoc_utils_set_rate(int srate, int mclk, int *mclk_change)
58 return -EINVAL; 52 return -EINVAL;
59 } 53 }
60 54
61 *mclk_change = ((new_baseclock != set_baseclock) || 55 *mclk_change = ((new_baseclock != data->set_baseclock) ||
62 (mclk != set_mclk)); 56 (mclk != data->set_mclk));
63 if (!*mclk_change) 57 if (!*mclk_change)
64 return 0; 58 return 0;
65 59
66 set_baseclock = 0; 60 data->set_baseclock = 0;
67 set_mclk = 0; 61 data->set_mclk = 0;
68 62
69 clk_disable(clk_cdev1); 63 clk_disable(data->clk_cdev1);
70 clk_disable(clk_pll_a_out0); 64 clk_disable(data->clk_pll_a_out0);
71 clk_disable(clk_pll_a); 65 clk_disable(data->clk_pll_a);
72 66
73 err = clk_set_rate(clk_pll_a, new_baseclock); 67 err = clk_set_rate(data->clk_pll_a, new_baseclock);
74 if (err) { 68 if (err) {
75 pr_err(PREFIX "Can't set pll_a rate: %d\n", err); 69 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
76 return err; 70 return err;
77 } 71 }
78 72
79 err = clk_set_rate(clk_pll_a_out0, mclk); 73 err = clk_set_rate(data->clk_pll_a_out0, mclk);
80 if (err) { 74 if (err) {
81 pr_err(PREFIX "Can't set pll_a_out0 rate: %d\n", err); 75 dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
82 return err; 76 return err;
83 } 77 }
84 78
85 /* Don't set cdev1 rate; its locked to pll_a_out0 */ 79 /* Don't set cdev1 rate; its locked to pll_a_out0 */
86 80
87 err = clk_enable(clk_pll_a); 81 err = clk_enable(data->clk_pll_a);
88 if (err) { 82 if (err) {
89 pr_err(PREFIX "Can't enable pll_a: %d\n", err); 83 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
90 return err; 84 return err;
91 } 85 }
92 86
93 err = clk_enable(clk_pll_a_out0); 87 err = clk_enable(data->clk_pll_a_out0);
94 if (err) { 88 if (err) {
95 pr_err(PREFIX "Can't enable pll_a_out0: %d\n", err); 89 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
96 return err; 90 return err;
97 } 91 }
98 92
99 err = clk_enable(clk_cdev1); 93 err = clk_enable(data->clk_cdev1);
100 if (err) { 94 if (err) {
101 pr_err(PREFIX "Can't enable cdev1: %d\n", err); 95 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
102 return err; 96 return err;
103 } 97 }
104 98
105 set_baseclock = new_baseclock; 99 data->set_baseclock = new_baseclock;
106 set_mclk = mclk; 100 data->set_mclk = mclk;
107 101
108 return 0; 102 return 0;
109} 103}
110 104
111int tegra_asoc_utils_init(void) 105int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
106 struct device *dev)
112{ 107{
113 int ret; 108 int ret;
114 109
115 clk_pll_a = clk_get_sys(NULL, "pll_a"); 110 data->dev = dev;
116 if (IS_ERR(clk_pll_a)) { 111
117 pr_err(PREFIX "Can't retrieve clk pll_a\n"); 112 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
118 ret = PTR_ERR(clk_pll_a); 113 if (IS_ERR(data->clk_pll_a)) {
114 dev_err(data->dev, "Can't retrieve clk pll_a\n");
115 ret = PTR_ERR(data->clk_pll_a);
119 goto err; 116 goto err;
120 } 117 }
121 118
122 clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); 119 data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
123 if (IS_ERR(clk_pll_a_out0)) { 120 if (IS_ERR(data->clk_pll_a_out0)) {
124 pr_err(PREFIX "Can't retrieve clk pll_a_out0\n"); 121 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
125 ret = PTR_ERR(clk_pll_a_out0); 122 ret = PTR_ERR(data->clk_pll_a_out0);
126 goto err_put_pll_a; 123 goto err_put_pll_a;
127 } 124 }
128 125
129 clk_cdev1 = clk_get_sys(NULL, "cdev1"); 126 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
130 if (IS_ERR(clk_cdev1)) { 127 if (IS_ERR(data->clk_cdev1)) {
131 pr_err(PREFIX "Can't retrieve clk cdev1\n"); 128 dev_err(data->dev, "Can't retrieve clk cdev1\n");
132 ret = PTR_ERR(clk_cdev1); 129 ret = PTR_ERR(data->clk_cdev1);
133 goto err_put_pll_a_out0; 130 goto err_put_pll_a_out0;
134 } 131 }
135 132
136 return 0; 133 return 0;
137 134
138err_put_pll_a_out0: 135err_put_pll_a_out0:
139 clk_put(clk_pll_a_out0); 136 clk_put(data->clk_pll_a_out0);
140err_put_pll_a: 137err_put_pll_a:
141 clk_put(clk_pll_a); 138 clk_put(data->clk_pll_a);
142err: 139err:
143 return ret; 140 return ret;
144} 141}
145 142
146void tegra_asoc_utils_fini(void) 143void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
147{ 144{
148 clk_put(clk_cdev1); 145 clk_put(data->clk_cdev1);
149 clk_put(clk_pll_a_out0); 146 clk_put(data->clk_pll_a_out0);
150 clk_put(clk_pll_a); 147 clk_put(data->clk_pll_a);
151} 148}
152 149
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 855f8f6e44ca..bbba7afdfc2c 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -23,9 +23,23 @@
23#ifndef __TEGRA_ASOC_UTILS_H__ 23#ifndef __TEGRA_ASOC_UTILS_H__
24#define __TEGRA_ASOC_UTILS_H_ 24#define __TEGRA_ASOC_UTILS_H_
25 25
26int tegra_asoc_utils_set_rate(int srate, int mclk_rate, int *mclk_change); 26struct clk;
27int tegra_asoc_utils_init(void); 27struct device;
28void tegra_asoc_utils_fini(void); 28
29struct tegra_asoc_utils_data {
30 struct device *dev;
31 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1;
34 int set_baseclock;
35 int set_mclk;
36};
37
38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
39 int mclk, int *mclk_change);
40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
41 struct device *dev);
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
29 43
30#endif 44#endif
31 45
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 6d668785e9af..870ee361f757 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -386,7 +386,7 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
386 snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id); 386 snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
387 i2s->clk_i2s = clk_get_sys(clk_name, NULL); 387 i2s->clk_i2s = clk_get_sys(clk_name, NULL);
388 if (IS_ERR(i2s->clk_i2s)) { 388 if (IS_ERR(i2s->clk_i2s)) {
389 pr_err("Can't retrieve i2s clock\n"); 389 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
390 ret = PTR_ERR(i2s->clk_i2s); 390 ret = PTR_ERR(i2s->clk_i2s);
391 goto err_free; 391 goto err_free;
392 } 392 }