diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/Kconfig | 20 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/cs4270.c | 805 | ||||
-rw-r--r-- | sound/soc/codecs/cs4270.h | 28 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 1 | ||||
-rw-r--r-- | sound/soc/s3c24xx/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c24xx-i2s.c | 1 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c24xx-pcm.c | 22 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 20 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 2 |
10 files changed, 871 insertions, 32 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index e5fb437b86e8..78248808a9d8 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -17,3 +17,23 @@ config SND_SOC_WM8753 | |||
17 | config SND_SOC_WM9712 | 17 | config SND_SOC_WM9712 |
18 | tristate | 18 | tristate |
19 | depends on SND_SOC | 19 | depends on SND_SOC |
20 | |||
21 | # Cirrus Logic CS4270 Codec | ||
22 | config SND_SOC_CS4270 | ||
23 | tristate | ||
24 | depends on SND_SOC | ||
25 | |||
26 | # Cirrus Logic CS4270 Codec Hardware Mute Support | ||
27 | # Select if you have external muting circuitry attached to your CS4270. | ||
28 | config SND_SOC_CS4270_HWMUTE | ||
29 | bool | ||
30 | depends on SND_SOC_CS4270 | ||
31 | |||
32 | # Cirrus Logic CS4270 Codec VD = 3.3V Errata | ||
33 | # Select if you are affected by the errata where the part will not function | ||
34 | # if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will | ||
35 | # not select any sample rates that require MCLK to be divided by 1.5. | ||
36 | config SND_SOC_CS4270_VD33_ERRATA | ||
37 | bool | ||
38 | depends on SND_SOC_CS4270 | ||
39 | |||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index e39a747a17cf..7ad78e36d506 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -3,9 +3,11 @@ snd-soc-wm8731-objs := wm8731.o | |||
3 | snd-soc-wm8750-objs := wm8750.o | 3 | snd-soc-wm8750-objs := wm8750.o |
4 | snd-soc-wm8753-objs := wm8753.o | 4 | snd-soc-wm8753-objs := wm8753.o |
5 | snd-soc-wm9712-objs := wm9712.o | 5 | snd-soc-wm9712-objs := wm9712.o |
6 | snd-soc-cs4270-objs := cs4270.o | ||
6 | 7 | ||
7 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 8 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
8 | obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o | 9 | obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o |
9 | obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o | 10 | obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o |
10 | obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o | 11 | obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o |
11 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o | 12 | obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o |
13 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | ||
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c new file mode 100644 index 000000000000..5d601ad6da70 --- /dev/null +++ b/sound/soc/codecs/cs4270.c | |||
@@ -0,0 +1,805 @@ | |||
1 | /* | ||
2 | * CS4270 ALSA SoC (ASoC) codec driver | ||
3 | * | ||
4 | * Author: Timur Tabi <timur@freescale.com> | ||
5 | * | ||
6 | * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | * | ||
11 | * This is an ASoC device driver for the Cirrus Logic CS4270 codec. | ||
12 | * | ||
13 | * Current features/limitations: | ||
14 | * | ||
15 | * 1) Software mode is supported. Stand-alone mode is automatically | ||
16 | * selected if I2C is disabled or if a CS4270 is not found on the I2C | ||
17 | * bus. However, stand-alone mode is only partially implemented because | ||
18 | * there is no mechanism yet for this driver and the machine driver to | ||
19 | * communicate the values of the M0, M1, MCLK1, and MCLK2 pins. | ||
20 | * 2) Only I2C is supported, not SPI | ||
21 | * 3) Only Master mode is supported, not Slave. | ||
22 | * 4) The machine driver's 'startup' function must call | ||
23 | * cs4270_set_dai_sysclk() with the value of MCLK. | ||
24 | * 5) Only I2S and left-justified modes are supported | ||
25 | * 6) Power management is not supported | ||
26 | * 7) The only supported control is volume and hardware mute (if enabled) | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <sound/driver.h> | ||
32 | #include <sound/core.h> | ||
33 | #include <sound/soc.h> | ||
34 | #include <sound/initval.h> | ||
35 | #include <linux/i2c.h> | ||
36 | |||
37 | #include "cs4270.h" | ||
38 | |||
39 | /* If I2C is defined, then we support software mode. However, if we're | ||
40 | not compiled as module but I2C is, then we can't use I2C calls. */ | ||
41 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
42 | #define USE_I2C | ||
43 | #endif | ||
44 | |||
45 | /* Private data for the CS4270 */ | ||
46 | struct cs4270_private { | ||
47 | unsigned int mclk; /* Input frequency of the MCLK pin */ | ||
48 | unsigned int mode; /* The mode (I2S or left-justified) */ | ||
49 | }; | ||
50 | |||
51 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ | ||
52 | #define NUM_MCLK_RATIOS 9 | ||
53 | |||
54 | /* The actual MCLK/LRCK ratios, in increasing numerical order */ | ||
55 | static unsigned int mclk_ratios[NUM_MCLK_RATIOS] = | ||
56 | {64, 96, 128, 192, 256, 384, 512, 768, 1024}; | ||
57 | |||
58 | /* | ||
59 | * Determine the CS4270 samples rates. | ||
60 | * | ||
61 | * 'freq' is the input frequency to MCLK. The other parameters are ignored. | ||
62 | * | ||
63 | * The value of MCLK is used to determine which sample rates are supported | ||
64 | * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine | ||
65 | * support values: 64, 96, 128, 192, 256, 384, 512, 768, and 1024. | ||
66 | * | ||
67 | * This function calculates the nine ratios and determines which ones match | ||
68 | * a standard sample rate. If there's a match, then it is added to the list | ||
69 | * of support sample rates. | ||
70 | * | ||
71 | * This function must be called by the machine driver's 'startup' function, | ||
72 | * otherwise the list of supported sample rates will not be available in | ||
73 | * time for ALSA. | ||
74 | * | ||
75 | * Note that in stand-alone mode, the sample rate is determined by input | ||
76 | * pins M0, M1, MDIV1, and MDIV2. Also in stand-alone mode, divide-by-3 | ||
77 | * is not a programmable option. However, divide-by-3 is not an available | ||
78 | * option in stand-alone mode. This cases two problems: a ratio of 768 is | ||
79 | * not available (it requires divide-by-3) and B) ratios 192 and 384 can | ||
80 | * only be selected with divide-by-1.5, but there is an errate that make | ||
81 | * this selection difficult. | ||
82 | * | ||
83 | * In addition, there is no mechanism for communicating with the machine | ||
84 | * driver what the input settings can be. This would need to be implemented | ||
85 | * for stand-alone mode to work. | ||
86 | */ | ||
87 | static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, | ||
88 | int clk_id, unsigned int freq, int dir) | ||
89 | { | ||
90 | struct snd_soc_codec *codec = codec_dai->codec; | ||
91 | struct cs4270_private *cs4270 = codec->private_data; | ||
92 | unsigned int rates = 0; | ||
93 | unsigned int rate_min = -1; | ||
94 | unsigned int rate_max = 0; | ||
95 | unsigned int i; | ||
96 | |||
97 | cs4270->mclk = freq; | ||
98 | |||
99 | for (i = 0; i < NUM_MCLK_RATIOS; i++) { | ||
100 | unsigned int rate = freq / mclk_ratios[i]; | ||
101 | rates |= snd_pcm_rate_to_rate_bit(rate); | ||
102 | if (rate < rate_min) | ||
103 | rate_min = rate; | ||
104 | if (rate > rate_max) | ||
105 | rate_max = rate; | ||
106 | } | ||
107 | /* FIXME: soc should support a rate list */ | ||
108 | rates &= ~SNDRV_PCM_RATE_KNOT; | ||
109 | |||
110 | if (!rates) { | ||
111 | printk(KERN_ERR "cs4270: could not find a valid sample rate\n"); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | codec_dai->playback.rates = rates; | ||
116 | codec_dai->playback.rate_min = rate_min; | ||
117 | codec_dai->playback.rate_max = rate_max; | ||
118 | |||
119 | codec_dai->capture.rates = rates; | ||
120 | codec_dai->capture.rate_min = rate_min; | ||
121 | codec_dai->capture.rate_max = rate_max; | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Configure the codec for the selected audio format | ||
128 | * | ||
129 | * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the | ||
130 | * codec accordingly. | ||
131 | * | ||
132 | * Currently, this function only supports SND_SOC_DAIFMT_I2S and | ||
133 | * SND_SOC_DAIFMT_LEFT_J. The CS4270 codec also supports right-justified | ||
134 | * data for playback only, but ASoC currently does not support different | ||
135 | * formats for playback vs. record. | ||
136 | */ | ||
137 | static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | ||
138 | unsigned int format) | ||
139 | { | ||
140 | struct snd_soc_codec *codec = codec_dai->codec; | ||
141 | struct cs4270_private *cs4270 = codec->private_data; | ||
142 | int ret = 0; | ||
143 | |||
144 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
145 | case SND_SOC_DAIFMT_I2S: | ||
146 | case SND_SOC_DAIFMT_LEFT_J: | ||
147 | cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; | ||
148 | break; | ||
149 | default: | ||
150 | printk(KERN_ERR "cs4270: invalid DAI format\n"); | ||
151 | ret = -EINVAL; | ||
152 | } | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * The codec isn't really big-endian or little-endian, since the I2S | ||
159 | * interface requires data to be sent serially with the MSbit first. | ||
160 | * However, to support BE and LE I2S devices, we specify both here. That | ||
161 | * way, ALSA will always match the bit patterns. | ||
162 | */ | ||
163 | #define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ | ||
164 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
165 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ | ||
166 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ | ||
167 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ | ||
168 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) | ||
169 | |||
170 | #ifdef USE_I2C | ||
171 | |||
172 | /* CS4270 registers addresses */ | ||
173 | #define CS4270_CHIPID 0x01 /* Chip ID */ | ||
174 | #define CS4270_PWRCTL 0x02 /* Power Control */ | ||
175 | #define CS4270_MODE 0x03 /* Mode Control */ | ||
176 | #define CS4270_FORMAT 0x04 /* Serial Format, ADC/DAC Control */ | ||
177 | #define CS4270_TRANS 0x05 /* Transition Control */ | ||
178 | #define CS4270_MUTE 0x06 /* Mute Control */ | ||
179 | #define CS4270_VOLA 0x07 /* DAC Channel A Volume Control */ | ||
180 | #define CS4270_VOLB 0x08 /* DAC Channel B Volume Control */ | ||
181 | |||
182 | #define CS4270_FIRSTREG 0x01 | ||
183 | #define CS4270_LASTREG 0x08 | ||
184 | #define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1) | ||
185 | |||
186 | /* Bit masks for the CS4270 registers */ | ||
187 | #define CS4270_CHIPID_ID 0xF0 | ||
188 | #define CS4270_CHIPID_REV 0x0F | ||
189 | #define CS4270_PWRCTL_FREEZE 0x80 | ||
190 | #define CS4270_PWRCTL_PDN_ADC 0x20 | ||
191 | #define CS4270_PWRCTL_PDN_DAC 0x02 | ||
192 | #define CS4270_PWRCTL_PDN 0x01 | ||
193 | #define CS4270_MODE_SPEED_MASK 0x30 | ||
194 | #define CS4270_MODE_1X 0x00 | ||
195 | #define CS4270_MODE_2X 0x10 | ||
196 | #define CS4270_MODE_4X 0x20 | ||
197 | #define CS4270_MODE_SLAVE 0x30 | ||
198 | #define CS4270_MODE_DIV_MASK 0x0E | ||
199 | #define CS4270_MODE_DIV1 0x00 | ||
200 | #define CS4270_MODE_DIV15 0x02 | ||
201 | #define CS4270_MODE_DIV2 0x04 | ||
202 | #define CS4270_MODE_DIV3 0x06 | ||
203 | #define CS4270_MODE_DIV4 0x08 | ||
204 | #define CS4270_MODE_POPGUARD 0x01 | ||
205 | #define CS4270_FORMAT_FREEZE_A 0x80 | ||
206 | #define CS4270_FORMAT_FREEZE_B 0x40 | ||
207 | #define CS4270_FORMAT_LOOPBACK 0x20 | ||
208 | #define CS4270_FORMAT_DAC_MASK 0x18 | ||
209 | #define CS4270_FORMAT_DAC_LJ 0x00 | ||
210 | #define CS4270_FORMAT_DAC_I2S 0x08 | ||
211 | #define CS4270_FORMAT_DAC_RJ16 0x18 | ||
212 | #define CS4270_FORMAT_DAC_RJ24 0x10 | ||
213 | #define CS4270_FORMAT_ADC_MASK 0x01 | ||
214 | #define CS4270_FORMAT_ADC_LJ 0x00 | ||
215 | #define CS4270_FORMAT_ADC_I2S 0x01 | ||
216 | #define CS4270_TRANS_ONE_VOL 0x80 | ||
217 | #define CS4270_TRANS_SOFT 0x40 | ||
218 | #define CS4270_TRANS_ZERO 0x20 | ||
219 | #define CS4270_TRANS_INV_ADC_A 0x08 | ||
220 | #define CS4270_TRANS_INV_ADC_B 0x10 | ||
221 | #define CS4270_TRANS_INV_DAC_A 0x02 | ||
222 | #define CS4270_TRANS_INV_DAC_B 0x04 | ||
223 | #define CS4270_TRANS_DEEMPH 0x01 | ||
224 | #define CS4270_MUTE_AUTO 0x20 | ||
225 | #define CS4270_MUTE_ADC_A 0x08 | ||
226 | #define CS4270_MUTE_ADC_B 0x10 | ||
227 | #define CS4270_MUTE_POLARITY 0x04 | ||
228 | #define CS4270_MUTE_DAC_A 0x01 | ||
229 | #define CS4270_MUTE_DAC_B 0x02 | ||
230 | |||
231 | /* | ||
232 | * A list of addresses on which this CS4270 could use. I2C addresses are | ||
233 | * 7 bits. For the CS4270, the upper four bits are always 1001, and the | ||
234 | * lower three bits are determined via the AD2, AD1, and AD0 pins | ||
235 | * (respectively). | ||
236 | */ | ||
237 | static unsigned short normal_i2c[] = { | ||
238 | 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END | ||
239 | }; | ||
240 | I2C_CLIENT_INSMOD; | ||
241 | |||
242 | /* | ||
243 | * Pre-fill the CS4270 register cache. | ||
244 | * | ||
245 | * We use the auto-increment feature of the CS4270 to read all registers in | ||
246 | * one shot. | ||
247 | */ | ||
248 | static int cs4270_fill_cache(struct snd_soc_codec *codec) | ||
249 | { | ||
250 | u8 *cache = codec->reg_cache; | ||
251 | struct i2c_client *i2c_client = codec->control_data; | ||
252 | s32 length; | ||
253 | |||
254 | length = i2c_smbus_read_i2c_block_data(i2c_client, | ||
255 | CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); | ||
256 | |||
257 | if (length != CS4270_NUMREGS) { | ||
258 | printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n", | ||
259 | i2c_client->addr); | ||
260 | return -EIO; | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Read from the CS4270 register cache. | ||
268 | * | ||
269 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. | ||
270 | * After the initial read to pre-fill the cache, the CS4270 never updates | ||
271 | * the register values, so we won't have a cache coherncy problem. | ||
272 | */ | ||
273 | static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, | ||
274 | unsigned int reg) | ||
275 | { | ||
276 | u8 *cache = codec->reg_cache; | ||
277 | |||
278 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||
279 | return -EIO; | ||
280 | |||
281 | return cache[reg - CS4270_FIRSTREG]; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Write to a CS4270 register via the I2C bus. | ||
286 | * | ||
287 | * This function writes the given value to the given CS4270 register, and | ||
288 | * also updates the register cache. | ||
289 | * | ||
290 | * Note that we don't use the hw_write function pointer of snd_soc_codec. | ||
291 | * That's because it's too clunky: the hw_write_t prototype does not match | ||
292 | * i2c_smbus_write_byte_data(), and it's just another layer of overhead. | ||
293 | */ | ||
294 | static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, | ||
295 | unsigned int value) | ||
296 | { | ||
297 | u8 *cache = codec->reg_cache; | ||
298 | |||
299 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||
300 | return -EIO; | ||
301 | |||
302 | /* Only perform an I2C operation if the new value is different */ | ||
303 | if (cache[reg - CS4270_FIRSTREG] != value) { | ||
304 | struct i2c_client *client = codec->control_data; | ||
305 | if (i2c_smbus_write_byte_data(client, reg, value)) { | ||
306 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
307 | return -EIO; | ||
308 | } | ||
309 | |||
310 | /* We've written to the hardware, so update the cache */ | ||
311 | cache[reg - CS4270_FIRSTREG] = value; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | /* | ||
318 | * Clock Ratio Selection for Master Mode with I2C enabled | ||
319 | * | ||
320 | * The data for this chart is taken from Table 5 of the CS4270 reference | ||
321 | * manual. | ||
322 | * | ||
323 | * This table is used to determine how to program the Mode Control register. | ||
324 | * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling | ||
325 | * rates the CS4270 currently supports. | ||
326 | * | ||
327 | * Each element in this array corresponds to the ratios in mclk_ratios[]. | ||
328 | * These two arrays need to be in sync. | ||
329 | * | ||
330 | * 'speed_mode' is the corresponding bit pattern to be written to the | ||
331 | * MODE bits of the Mode Control Register | ||
332 | * | ||
333 | * 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of | ||
334 | * the Mode Control Register. | ||
335 | * | ||
336 | * In situations where a single ratio is represented by multiple speed | ||
337 | * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick | ||
338 | * double-speed instead of quad-speed. However, the CS4270 errata states | ||
339 | * that Divide-By-1.5 can cause failures, so we avoid that mode where | ||
340 | * possible. | ||
341 | * | ||
342 | * ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not | ||
343 | * work if VD = 3.3V. If this effects you, select the | ||
344 | * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will | ||
345 | * never select any sample rates that require divide-by-1.5. | ||
346 | */ | ||
347 | static struct { | ||
348 | u8 speed_mode; | ||
349 | u8 mclk; | ||
350 | } cs4270_mode_ratios[NUM_MCLK_RATIOS] = { | ||
351 | {CS4270_MODE_4X, CS4270_MODE_DIV1}, /* 64 */ | ||
352 | #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA | ||
353 | {CS4270_MODE_4X, CS4270_MODE_DIV15}, /* 96 */ | ||
354 | #endif | ||
355 | {CS4270_MODE_2X, CS4270_MODE_DIV1}, /* 128 */ | ||
356 | {CS4270_MODE_4X, CS4270_MODE_DIV3}, /* 192 */ | ||
357 | {CS4270_MODE_1X, CS4270_MODE_DIV1}, /* 256 */ | ||
358 | {CS4270_MODE_2X, CS4270_MODE_DIV3}, /* 384 */ | ||
359 | {CS4270_MODE_1X, CS4270_MODE_DIV2}, /* 512 */ | ||
360 | {CS4270_MODE_1X, CS4270_MODE_DIV3}, /* 768 */ | ||
361 | {CS4270_MODE_1X, CS4270_MODE_DIV4} /* 1024 */ | ||
362 | }; | ||
363 | |||
364 | /* | ||
365 | * Program the CS4270 with the given hardware parameters. | ||
366 | * | ||
367 | * The .dai_ops functions are used to provide board-specific data, like | ||
368 | * input frequencies, to this driver. This function takes that information, | ||
369 | * combines it with the hardware parameters provided, and programs the | ||
370 | * hardware accordingly. | ||
371 | */ | ||
372 | static int cs4270_hw_params(struct snd_pcm_substream *substream, | ||
373 | struct snd_pcm_hw_params *params) | ||
374 | { | ||
375 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
376 | struct snd_soc_device *socdev = rtd->socdev; | ||
377 | struct snd_soc_codec *codec = socdev->codec; | ||
378 | struct cs4270_private *cs4270 = codec->private_data; | ||
379 | unsigned int ret = 0; | ||
380 | unsigned int i; | ||
381 | unsigned int rate; | ||
382 | unsigned int ratio; | ||
383 | int reg; | ||
384 | |||
385 | /* Figure out which MCLK/LRCK ratio to use */ | ||
386 | |||
387 | rate = params_rate(params); /* Sampling rate, in Hz */ | ||
388 | ratio = cs4270->mclk / rate; /* MCLK/LRCK ratio */ | ||
389 | |||
390 | for (i = 0; i < NUM_MCLK_RATIOS; i++) { | ||
391 | if (mclk_ratios[i] == ratio) | ||
392 | break; | ||
393 | } | ||
394 | |||
395 | if (i == NUM_MCLK_RATIOS) { | ||
396 | /* We did not find a matching ratio */ | ||
397 | printk(KERN_ERR "cs4270: could not find matching ratio\n"); | ||
398 | return -EINVAL; | ||
399 | } | ||
400 | |||
401 | /* Freeze and power-down the codec */ | ||
402 | |||
403 | ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE | | ||
404 | CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | | ||
405 | CS4270_PWRCTL_PDN); | ||
406 | if (ret < 0) { | ||
407 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | /* Program the mode control register */ | ||
412 | |||
413 | reg = snd_soc_read(codec, CS4270_MODE); | ||
414 | reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); | ||
415 | reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk; | ||
416 | |||
417 | ret = snd_soc_write(codec, CS4270_MODE, reg); | ||
418 | if (ret < 0) { | ||
419 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | /* Program the format register */ | ||
424 | |||
425 | reg = snd_soc_read(codec, CS4270_FORMAT); | ||
426 | reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); | ||
427 | |||
428 | switch (cs4270->mode) { | ||
429 | case SND_SOC_DAIFMT_I2S: | ||
430 | reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S; | ||
431 | break; | ||
432 | case SND_SOC_DAIFMT_LEFT_J: | ||
433 | reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ; | ||
434 | break; | ||
435 | default: | ||
436 | printk(KERN_ERR "cs4270: unknown format\n"); | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | ret = snd_soc_write(codec, CS4270_FORMAT, reg); | ||
441 | if (ret < 0) { | ||
442 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
443 | return ret; | ||
444 | } | ||
445 | |||
446 | /* Disable auto-mute. This feature appears to be buggy, because in | ||
447 | some situations, auto-mute will not deactivate when it should. */ | ||
448 | |||
449 | reg = snd_soc_read(codec, CS4270_MUTE); | ||
450 | reg &= ~CS4270_MUTE_AUTO; | ||
451 | ret = snd_soc_write(codec, CS4270_MUTE, reg); | ||
452 | if (ret < 0) { | ||
453 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | /* Thaw and power-up the codec */ | ||
458 | |||
459 | ret = snd_soc_write(codec, CS4270_PWRCTL, 0); | ||
460 | if (ret < 0) { | ||
461 | printk(KERN_ERR "cs4270: I2C write failed\n"); | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | #ifdef CONFIG_SND_SOC_CS4270_HWMUTE | ||
469 | |||
470 | /* | ||
471 | * Set the CS4270 external mute | ||
472 | * | ||
473 | * This function toggles the mute bits in the MUTE register. The CS4270's | ||
474 | * mute capability is intended for external muting circuitry, so if the | ||
475 | * board does not have the MUTEA or MUTEB pins connected to such circuitry, | ||
476 | * then this function will do nothing. | ||
477 | */ | ||
478 | static int cs4270_mute(struct snd_soc_codec_dai *dai, int mute) | ||
479 | { | ||
480 | struct snd_soc_codec *codec = dai->codec; | ||
481 | int reg6; | ||
482 | |||
483 | reg6 = snd_soc_read(codec, CS4270_MUTE); | ||
484 | |||
485 | if (mute) | ||
486 | reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | | ||
487 | CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; | ||
488 | else | ||
489 | reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | | ||
490 | CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); | ||
491 | |||
492 | return snd_soc_write(codec, CS4270_MUTE, reg6); | ||
493 | } | ||
494 | |||
495 | #endif | ||
496 | |||
497 | static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind); | ||
498 | |||
499 | /* | ||
500 | * Notify the driver that a new I2C bus has been found. | ||
501 | * | ||
502 | * This function is called for each I2C bus in the system. The function | ||
503 | * then asks the I2C subsystem to probe that bus at the addresses on which | ||
504 | * our device (the CS4270) could exist. If a device is found at one of | ||
505 | * those addresses, then our probe function (cs4270_i2c_probe) is called. | ||
506 | */ | ||
507 | static int cs4270_i2c_attach(struct i2c_adapter *adapter) | ||
508 | { | ||
509 | return i2c_probe(adapter, &addr_data, cs4270_i2c_probe); | ||
510 | } | ||
511 | |||
512 | static int cs4270_i2c_detach(struct i2c_client *client) | ||
513 | { | ||
514 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | ||
515 | |||
516 | i2c_detach_client(client); | ||
517 | codec->control_data = NULL; | ||
518 | |||
519 | kfree(codec->reg_cache); | ||
520 | codec->reg_cache = NULL; | ||
521 | |||
522 | kfree(client); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /* A list of non-DAPM controls that the CS4270 supports */ | ||
527 | static const struct snd_kcontrol_new cs4270_snd_controls[] = { | ||
528 | SOC_DOUBLE_R("Master Playback Volume", | ||
529 | CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) | ||
530 | }; | ||
531 | |||
532 | static struct i2c_driver cs4270_i2c_driver = { | ||
533 | .driver = { | ||
534 | .name = "CS4270 I2C", | ||
535 | .owner = THIS_MODULE, | ||
536 | }, | ||
537 | .id = I2C_DRIVERID_CS4270, | ||
538 | .attach_adapter = cs4270_i2c_attach, | ||
539 | .detach_client = cs4270_i2c_detach, | ||
540 | }; | ||
541 | |||
542 | /* | ||
543 | * Global variable to store socdev for i2c probe function. | ||
544 | * | ||
545 | * If struct i2c_driver had a private_data field, we wouldn't need to use | ||
546 | * cs4270_socdec. This is the only way to pass the socdev structure to | ||
547 | * cs4270_i2c_probe(). | ||
548 | * | ||
549 | * The real solution to cs4270_socdev is to create a mechanism | ||
550 | * that maps I2C addresses to snd_soc_device structures. Perhaps the | ||
551 | * creation of the snd_soc_device object should be moved out of | ||
552 | * cs4270_probe() and into cs4270_i2c_probe(), but that would make this | ||
553 | * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby | ||
554 | * the chip is *not* connected to the I2C bus, but is instead configured via | ||
555 | * input pins. | ||
556 | */ | ||
557 | static struct snd_soc_device *cs4270_socdev; | ||
558 | |||
559 | /* | ||
560 | * Initialize the I2C interface of the CS4270 | ||
561 | * | ||
562 | * This function is called for whenever the I2C subsystem finds a device | ||
563 | * at a particular address. | ||
564 | * | ||
565 | * Note: snd_soc_new_pcms() must be called before this function can be called, | ||
566 | * because of snd_ctl_add(). | ||
567 | */ | ||
568 | static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) | ||
569 | { | ||
570 | struct snd_soc_device *socdev = cs4270_socdev; | ||
571 | struct snd_soc_codec *codec = socdev->codec; | ||
572 | struct i2c_client *i2c_client = NULL; | ||
573 | int i; | ||
574 | int ret = 0; | ||
575 | |||
576 | /* Probing all possible addresses has one drawback: if there are | ||
577 | multiple CS4270s on the bus, then you cannot specify which | ||
578 | socdev is matched with which CS4270. For now, we just reject | ||
579 | this I2C device if the socdev already has one attached. */ | ||
580 | if (codec->control_data) | ||
581 | return -ENODEV; | ||
582 | |||
583 | /* Note: codec_dai->codec is NULL here */ | ||
584 | |||
585 | i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
586 | if (!i2c_client) { | ||
587 | printk(KERN_ERR "cs4270: could not allocate I2C client\n"); | ||
588 | return -ENOMEM; | ||
589 | } | ||
590 | |||
591 | codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); | ||
592 | if (!codec->reg_cache) { | ||
593 | printk(KERN_ERR "cs4270: could not allocate register cache\n"); | ||
594 | ret = -ENOMEM; | ||
595 | goto error; | ||
596 | } | ||
597 | |||
598 | i2c_set_clientdata(i2c_client, codec); | ||
599 | strcpy(i2c_client->name, "CS4270"); | ||
600 | |||
601 | i2c_client->driver = &cs4270_i2c_driver; | ||
602 | i2c_client->adapter = adapter; | ||
603 | i2c_client->addr = addr; | ||
604 | |||
605 | /* Verify that we have a CS4270 */ | ||
606 | |||
607 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | ||
608 | if (ret < 0) { | ||
609 | printk(KERN_ERR "cs4270: failed to read I2C\n"); | ||
610 | goto error; | ||
611 | } | ||
612 | /* The top four bits of the chip ID should be 1100. */ | ||
613 | if ((ret & 0xF0) != 0xC0) { | ||
614 | /* The device at this address is not a CS4270 codec */ | ||
615 | ret = -ENODEV; | ||
616 | goto error; | ||
617 | } | ||
618 | |||
619 | printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr); | ||
620 | printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); | ||
621 | |||
622 | /* Tell the I2C layer a new client has arrived */ | ||
623 | |||
624 | ret = i2c_attach_client(i2c_client); | ||
625 | if (ret) { | ||
626 | printk(KERN_ERR "cs4270: could not attach codec, " | ||
627 | "I2C address %x, error code %i\n", addr, ret); | ||
628 | goto error; | ||
629 | } | ||
630 | |||
631 | codec->control_data = i2c_client; | ||
632 | codec->read = cs4270_read_reg_cache; | ||
633 | codec->write = cs4270_i2c_write; | ||
634 | codec->reg_cache_size = CS4270_NUMREGS; | ||
635 | |||
636 | /* The I2C interface is set up, so pre-fill our register cache */ | ||
637 | |||
638 | ret = cs4270_fill_cache(codec); | ||
639 | if (ret < 0) { | ||
640 | printk(KERN_ERR "cs4270: failed to fill register cache\n"); | ||
641 | goto error; | ||
642 | } | ||
643 | |||
644 | /* Add the non-DAPM controls */ | ||
645 | |||
646 | for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) { | ||
647 | struct snd_kcontrol *kctrl = | ||
648 | snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL); | ||
649 | |||
650 | ret = snd_ctl_add(codec->card, kctrl); | ||
651 | if (ret < 0) | ||
652 | goto error; | ||
653 | } | ||
654 | |||
655 | return 0; | ||
656 | |||
657 | error: | ||
658 | if (codec->control_data) { | ||
659 | i2c_detach_client(i2c_client); | ||
660 | codec->control_data = NULL; | ||
661 | } | ||
662 | |||
663 | kfree(codec->reg_cache); | ||
664 | codec->reg_cache = NULL; | ||
665 | codec->reg_cache_size = 0; | ||
666 | |||
667 | kfree(i2c_client); | ||
668 | |||
669 | return ret; | ||
670 | } | ||
671 | |||
672 | #endif | ||
673 | |||
674 | struct snd_soc_codec_dai cs4270_dai = { | ||
675 | .name = "CS4270", | ||
676 | .playback = { | ||
677 | .stream_name = "Playback", | ||
678 | .channels_min = 1, | ||
679 | .channels_max = 2, | ||
680 | .rates = 0, | ||
681 | .formats = CS4270_FORMATS, | ||
682 | }, | ||
683 | .capture = { | ||
684 | .stream_name = "Capture", | ||
685 | .channels_min = 1, | ||
686 | .channels_max = 2, | ||
687 | .rates = 0, | ||
688 | .formats = CS4270_FORMATS, | ||
689 | }, | ||
690 | .dai_ops = { | ||
691 | .set_sysclk = cs4270_set_dai_sysclk, | ||
692 | .set_fmt = cs4270_set_dai_fmt, | ||
693 | } | ||
694 | }; | ||
695 | EXPORT_SYMBOL_GPL(cs4270_dai); | ||
696 | |||
697 | /* | ||
698 | * ASoC probe function | ||
699 | * | ||
700 | * This function is called when the machine driver calls | ||
701 | * platform_device_add(). | ||
702 | */ | ||
703 | static int cs4270_probe(struct platform_device *pdev) | ||
704 | { | ||
705 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
706 | struct snd_soc_codec *codec; | ||
707 | int ret = 0; | ||
708 | |||
709 | printk(KERN_INFO "CS4270 ALSA SoC Codec\n"); | ||
710 | |||
711 | /* Allocate enough space for the snd_soc_codec structure | ||
712 | and our private data together. */ | ||
713 | codec = kzalloc(ALIGN(sizeof(struct snd_soc_codec), 4) + | ||
714 | sizeof(struct cs4270_private), GFP_KERNEL); | ||
715 | if (!codec) { | ||
716 | printk(KERN_ERR "cs4270: Could not allocate codec structure\n"); | ||
717 | return -ENOMEM; | ||
718 | } | ||
719 | |||
720 | mutex_init(&codec->mutex); | ||
721 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
722 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
723 | |||
724 | codec->name = "CS4270"; | ||
725 | codec->owner = THIS_MODULE; | ||
726 | codec->dai = &cs4270_dai; | ||
727 | codec->num_dai = 1; | ||
728 | codec->private_data = codec + ALIGN(sizeof(struct snd_soc_codec), 4); | ||
729 | |||
730 | socdev->codec = codec; | ||
731 | |||
732 | /* Register PCMs */ | ||
733 | |||
734 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
735 | if (ret < 0) { | ||
736 | printk(KERN_ERR "cs4270: failed to create PCMs\n"); | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | #ifdef USE_I2C | ||
741 | cs4270_socdev = socdev; | ||
742 | |||
743 | ret = i2c_add_driver(&cs4270_i2c_driver); | ||
744 | if (ret) { | ||
745 | printk(KERN_ERR "cs4270: failed to attach driver"); | ||
746 | snd_soc_free_pcms(socdev); | ||
747 | return ret; | ||
748 | } | ||
749 | |||
750 | /* Did we find a CS4270 on the I2C bus? */ | ||
751 | if (codec->control_data) { | ||
752 | /* Initialize codec ops */ | ||
753 | cs4270_dai.ops.hw_params = cs4270_hw_params; | ||
754 | #ifdef CONFIG_SND_SOC_CS4270_HWMUTE | ||
755 | cs4270_dai.dai_ops.digital_mute = cs4270_mute; | ||
756 | #endif | ||
757 | } else | ||
758 | printk(KERN_INFO "cs4270: no I2C device found, " | ||
759 | "using stand-alone mode\n"); | ||
760 | #else | ||
761 | printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); | ||
762 | #endif | ||
763 | |||
764 | ret = snd_soc_register_card(socdev); | ||
765 | if (ret < 0) { | ||
766 | printk(KERN_ERR "cs4270: failed to register card\n"); | ||
767 | snd_soc_free_pcms(socdev); | ||
768 | return ret; | ||
769 | } | ||
770 | |||
771 | return ret; | ||
772 | } | ||
773 | |||
774 | static int cs4270_remove(struct platform_device *pdev) | ||
775 | { | ||
776 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
777 | |||
778 | snd_soc_free_pcms(socdev); | ||
779 | |||
780 | #ifdef USE_I2C | ||
781 | if (socdev->codec->control_data) | ||
782 | i2c_del_driver(&cs4270_i2c_driver); | ||
783 | #endif | ||
784 | |||
785 | kfree(socdev->codec); | ||
786 | socdev->codec = NULL; | ||
787 | |||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * ASoC codec device structure | ||
793 | * | ||
794 | * Assign this variable to the codec_dev field of the machine driver's | ||
795 | * snd_soc_device structure. | ||
796 | */ | ||
797 | struct snd_soc_codec_device soc_codec_device_cs4270 = { | ||
798 | .probe = cs4270_probe, | ||
799 | .remove = cs4270_remove | ||
800 | }; | ||
801 | EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); | ||
802 | |||
803 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
804 | MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); | ||
805 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h new file mode 100644 index 000000000000..0ced49b7804d --- /dev/null +++ b/sound/soc/codecs/cs4270.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Cirrus Logic CS4270 ALSA SoC Codec Driver | ||
3 | * | ||
4 | * Author: Timur Tabi <timur@freescale.com> | ||
5 | * | ||
6 | * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef _CS4270_H | ||
13 | #define _CS4270_H | ||
14 | |||
15 | /* | ||
16 | * The ASoC codec DAI structure for the CS4270. Assign this structure to | ||
17 | * the .codec_dai field of your machine driver's snd_soc_dai_link structure. | ||
18 | */ | ||
19 | extern struct snd_soc_codec_dai cs4270_dai; | ||
20 | |||
21 | /* | ||
22 | * The ASoC codec device structure for the CS4270. Assign this structure | ||
23 | * to the .codec_dev field of your machine driver's snd_soc_device | ||
24 | * structure. | ||
25 | */ | ||
26 | extern struct snd_soc_codec_device soc_codec_device_cs4270; | ||
27 | |||
28 | #endif | ||
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 80e82109fef7..4dd8f35312b3 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <asm/arch/hardware.h> | 34 | #include <asm/arch/hardware.h> |
35 | #include <asm/arch/akita.h> | 35 | #include <asm/arch/akita.h> |
36 | #include <asm/arch/spitz.h> | 36 | #include <asm/arch/spitz.h> |
37 | #include <asm/mach-types.h> | ||
38 | #include "../codecs/wm8750.h" | 37 | #include "../codecs/wm8750.h" |
39 | #include "pxa2xx-pcm.h" | 38 | #include "pxa2xx-pcm.h" |
40 | #include "pxa2xx-i2s.h" | 39 | #include "pxa2xx-i2s.h" |
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index e97c68306a9a..5632a2e1518d 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig | |||
@@ -18,7 +18,7 @@ config SND_S3C2443_SOC_AC97 | |||
18 | 18 | ||
19 | config SND_S3C24XX_SOC_NEO1973_WM8753 | 19 | config SND_S3C24XX_SOC_NEO1973_WM8753 |
20 | tristate "SoC I2S Audio support for NEO1973 - WM8753" | 20 | tristate "SoC I2S Audio support for NEO1973 - WM8753" |
21 | depends on SND_S3C24XX_SOC && MACH_GTA01 | 21 | depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 |
22 | select SND_S3C24XX_SOC_I2S | 22 | select SND_S3C24XX_SOC_I2S |
23 | select SND_SOC_WM8753 | 23 | select SND_SOC_WM8753 |
24 | help | 24 | help |
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 39f02462e07d..cd89c4105fcd 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c | |||
@@ -385,6 +385,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev) | |||
385 | s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis"); | 385 | s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis"); |
386 | if (s3c24xx_i2s.iis_clk == NULL) { | 386 | if (s3c24xx_i2s.iis_clk == NULL) { |
387 | DBG("failed to get iis_clock\n"); | 387 | DBG("failed to get iis_clock\n"); |
388 | iounmap(s3c24xx_i2s.regs); | ||
388 | return -ENODEV; | 389 | return -ENODEV; |
389 | } | 390 | } |
390 | clk_enable(s3c24xx_i2s.iis_clk); | 391 | clk_enable(s3c24xx_i2s.iis_clk); |
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index bfbdc3cbd43b..4107a87d4de3 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c | |||
@@ -158,18 +158,22 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
158 | if (!dma) | 158 | if (!dma) |
159 | return 0; | 159 | return 0; |
160 | 160 | ||
161 | /* prepare DMA */ | 161 | /* this may get called several times by oss emulation |
162 | prtd->params = dma; | 162 | * with different params -HW */ |
163 | if (prtd->params == NULL) { | ||
164 | /* prepare DMA */ | ||
165 | prtd->params = dma; | ||
163 | 166 | ||
164 | DBG("params %p, client %p, channel %d\n", prtd->params, | 167 | DBG("params %p, client %p, channel %d\n", prtd->params, |
165 | prtd->params->client, prtd->params->channel); | 168 | prtd->params->client, prtd->params->channel); |
166 | 169 | ||
167 | ret = s3c2410_dma_request(prtd->params->channel, | 170 | ret = s3c2410_dma_request(prtd->params->channel, |
168 | prtd->params->client, NULL); | 171 | prtd->params->client, NULL); |
169 | 172 | ||
170 | if (ret) { | 173 | if (ret) { |
171 | DBG(KERN_ERR "failed to get dma channel\n"); | 174 | DBG(KERN_ERR "failed to get dma channel\n"); |
172 | return ret; | 175 | return ret; |
176 | } | ||
173 | } | 177 | } |
174 | 178 | ||
175 | /* channel needs configuring for mem=>device, increment memory addr, | 179 | /* channel needs configuring for mem=>device, increment memory addr, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 92d5d917b73b..91651bdfa761 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1362,26 +1362,6 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, | |||
1362 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); | 1362 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); |
1363 | 1363 | ||
1364 | /** | 1364 | /** |
1365 | * snd_soc_info_bool_ext - external single boolean mixer info callback | ||
1366 | * @kcontrol: mixer control | ||
1367 | * @uinfo: control element information | ||
1368 | * | ||
1369 | * Callback to provide information about a single boolean external mixer control. | ||
1370 | * | ||
1371 | * Returns 0 for success. | ||
1372 | */ | ||
1373 | int snd_soc_info_bool_ext(struct snd_kcontrol *kcontrol, | ||
1374 | struct snd_ctl_elem_info *uinfo) | ||
1375 | { | ||
1376 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1377 | uinfo->count = 1; | ||
1378 | uinfo->value.integer.min = 0; | ||
1379 | uinfo->value.integer.max = 1; | ||
1380 | return 0; | ||
1381 | } | ||
1382 | EXPORT_SYMBOL_GPL(snd_soc_info_bool_ext); | ||
1383 | |||
1384 | /** | ||
1385 | * snd_soc_info_volsw - single mixer info callback | 1365 | * snd_soc_info_volsw - single mixer info callback |
1386 | * @kcontrol: mixer control | 1366 | * @kcontrol: mixer control |
1387 | * @uinfo: control element information | 1367 | * @uinfo: control element information |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 96bce55572a0..b3193e687db7 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #define POP_DEBUG 0 | 63 | #define POP_DEBUG 0 |
64 | #if POP_DEBUG | 64 | #if POP_DEBUG |
65 | #define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */ | 65 | #define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */ |
66 | #define pop_wait(time) schedule_timeout_interruptible(msecs_to_jiffies(time)) | 66 | #define pop_wait(time) schedule_timeout_uninterruptible(msecs_to_jiffies(time)) |
67 | #define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME) | 67 | #define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME) |
68 | #else | 68 | #else |
69 | #define pop_dbg(format, arg...) | 69 | #define pop_dbg(format, arg...) |