Date:2012-06-16 19:36:31 (10 years 3 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
1818#include <linux/io.h>
1919
2020#include <linux/delay.h>
21#include <linux/completion.h>
2122
2223#include <sound/core.h>
2324#include <sound/pcm.h>
...... 
7475struct jz4740_codec {
7576    void __iomem *base;
7677    struct resource *mem;
78
79    struct snd_soc_codec *codec;
80    struct delayed_work dma_work;
81    struct completion completion;
7782};
7883
7984static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
...... 
247252        jz4740_codec_write(codec, i, cache[i]);
248253}
249254
255static 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
250267static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
251268    enum snd_soc_bias_level level)
252269{
253270    unsigned int mask;
254271    unsigned int value;
272    struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
255273
256274    switch (level) {
257275    case SND_SOC_BIAS_ON:
258276        break;
259277    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;
263279        value = 0;
264
265280        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);
266285        break;
267286    case SND_SOC_BIAS_STANDBY:
268287        /* The only way to clear the suspend flag is to reset the codec */
...... 
295314
296315static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
297316{
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
298323    snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
299324            JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
300325

Archive Download the corresponding diff file



interactive