Date: | 2012-06-16 19:36:31 (11 years 9 months ago) |
---|---|
Author: | Paul Cercueil |
Commit: | ef84c71ff3983379d031ec1eedf2ebb7567a43aa |
Message: | ASoC: JZ4740: delay activation of the DAC to work around a sound bug. A proper fix of that bug would require a big rewrite of the driver, which (I hope) will be done eventually. |
Files: |
sound/soc/codecs/jz4740.c (4 diffs) |
Change Details
sound/soc/codecs/jz4740.c | ||
---|---|---|
18 | 18 | #include <linux/io.h> |
19 | 19 | |
20 | 20 | #include <linux/delay.h> |
21 | #include <linux/completion.h> | |
21 | 22 | |
22 | 23 | #include <sound/core.h> |
23 | 24 | #include <sound/pcm.h> |
... | ... | |
74 | 75 | struct jz4740_codec { |
75 | 76 | void __iomem *base; |
76 | 77 | struct resource *mem; |
78 | ||
79 | struct snd_soc_codec *codec; | |
80 | struct delayed_work dma_work; | |
81 | struct completion completion; | |
77 | 82 | }; |
78 | 83 | |
79 | 84 | static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, |
... | ... | |
247 | 252 | jz4740_codec_write(codec, i, cache[i]); |
248 | 253 | } |
249 | 254 | |
255 | static void jz4740_dma_work(struct work_struct *work) | |
256 | { | |
257 | struct jz4740_codec *jz4740_codec = | |
258 | container_of(work, struct jz4740_codec, dma_work.work); | |
259 | ||
260 | unsigned int mask = JZ4740_CODEC_1_VREF_DISABLE | | |
261 | JZ4740_CODEC_1_VREF_AMP_DISABLE; | |
262 | snd_soc_update_bits(jz4740_codec->codec, | |
263 | JZ4740_REG_CODEC_1, mask, 0); | |
264 | complete_all(&jz4740_codec->completion); | |
265 | } | |
266 | ||
250 | 267 | static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, |
251 | 268 | enum snd_soc_bias_level level) |
252 | 269 | { |
253 | 270 | unsigned int mask; |
254 | 271 | unsigned int value; |
272 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
255 | 273 | |
256 | 274 | switch (level) { |
257 | 275 | case SND_SOC_BIAS_ON: |
258 | 276 | break; |
259 | 277 | case SND_SOC_BIAS_PREPARE: |
260 | mask = JZ4740_CODEC_1_VREF_DISABLE | | |
261 | JZ4740_CODEC_1_VREF_AMP_DISABLE | | |
262 | JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | |
278 | mask = JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M; | |
263 | 279 | value = 0; |
264 | ||
265 | 280 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value); |
281 | ||
282 | INIT_COMPLETION(jz4740_codec->completion); | |
283 | schedule_delayed_work(&jz4740_codec->dma_work, HZ / 2); | |
284 | wait_for_completion_interruptible(&jz4740_codec->completion); | |
266 | 285 | break; |
267 | 286 | case SND_SOC_BIAS_STANDBY: |
268 | 287 | /* The only way to clear the suspend flag is to reset the codec */ |
... | ... | |
295 | 314 | |
296 | 315 | static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) |
297 | 316 | { |
317 | struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec); | |
318 | ||
319 | jz4740_codec->codec = codec; | |
320 | init_completion(&jz4740_codec->completion); | |
321 | INIT_DELAYED_WORK(&jz4740_codec->dma_work, jz4740_dma_work); | |
322 | ||
298 | 323 | snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, |
299 | 324 | JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); |
300 | 325 |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9