]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'fix/hda' into for-linus
authorTakashi Iwai <tiwai@suse.de>
Wed, 7 Apr 2010 07:54:46 +0000 (09:54 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 7 Apr 2010 07:54:46 +0000 (09:54 +0200)
40 files changed:
include/sound/ak4113.h
include/sound/soc-dai.h
include/sound/soc.h
sound/arm/pxa2xx-pcm-lib.c
sound/core/pcm_lib.c
sound/i2c/other/ak4113.c
sound/oss/vidc.c
sound/pci/ac97/ac97_patch.c
sound/pci/cmipci.c
sound/pci/echoaudio/echoaudio.c
sound/pci/mixart/mixart.c
sound/soc/atmel/atmel-pcm.c
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/codecs/ac97.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm_hubs.c
sound/soc/codecs/wm_hubs.h
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-pcm.c
sound/soc/imx/Kconfig
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-ssi.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-pcm.c
sound/soc/pxa/pxa-ssp.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/s3c24xx/s3c-ac97.c
sound/soc/s3c24xx/s3c-dma.c
sound/soc/s3c24xx/s3c-i2s-v2.c
sound/soc/s3c24xx/s3c-pcm.c
sound/soc/s3c24xx/s3c24xx-i2s.c
sound/soc/s6000/s6000-i2s.c
sound/soc/s6000/s6000-pcm.c
sound/soc/sh/Kconfig
sound/soc/soc-core.c

index 8988edae160978f09747e29010fce79be703d56b..2609048c1d442581a2530f79cc2135aa679f8cb1 100644 (file)
@@ -307,7 +307,7 @@ struct ak4113 {
 
 int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
                ak4113_write_t *write,
-               const unsigned char pgm[AK4113_WRITABLE_REGS],
+               const unsigned char *pgm,
                void *private_data, struct ak4113 **r_ak4113);
 void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
                unsigned char mask, unsigned char val);
index 061f16d4c8780b18f15cafaefb760a5e0780af59..0a0b019d41adebf2c10d8505a6d76dbed37a546c 100644 (file)
@@ -219,7 +219,6 @@ struct snd_soc_dai {
        struct snd_soc_codec *codec;
        unsigned int active;
        unsigned char pop_wait:1;
-       void *dma_data;
 
        /* DAI private data */
        void *private_data;
@@ -230,4 +229,21 @@ struct snd_soc_dai {
        struct list_head list;
 };
 
+static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
+                                            const struct snd_pcm_substream *ss)
+{
+       return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+               dai->playback.dma_data : dai->capture.dma_data;
+}
+
+static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
+                                           const struct snd_pcm_substream *ss,
+                                           void *data)
+{
+       if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dai->playback.dma_data = data;
+       else
+               dai->capture.dma_data = data;
+}
+
 #endif
index 5d234a8c2506c74df25d5fbc7f9220c0bdb106ad..a57fbfcd4c8f26877626f34caf122de3216f1da6 100644 (file)
@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream {
        unsigned int channels_min;      /* min channels */
        unsigned int channels_max;      /* max channels */
        unsigned int active:1;          /* stream is in use */
+       void *dma_data;                 /* used by platform code */
 };
 
 /* SoC audio ops */
index 743ac6a2906598fdbd70a04f6a3c6910fd86fdfe..fd51fa8b06a12cea27815c2ec9b121841cbc3076 100644 (file)
@@ -205,6 +205,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
        if (!rtd->dma_desc_array)
                goto err1;
 
+       rtd->dma_ch = -1;
        runtime->private_data = rtd;
        return 0;
 
index b546ac2660f9f64b8436e3efe836cfa0f298afee..a2ff86189d2a583ad208c8e61beed816d3f23a67 100644 (file)
@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
 
 #define xrun_debug(substream, mask) \
                        ((substream)->pstr->xrun_debug & (mask))
+#else
+#define xrun_debug(substream, mask)    0
+#endif
 
 #define dump_stack_on_xrun(substream) do {                     \
                if (xrun_debug(substream, XRUN_DEBUG_STACK))    \
@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream)
        }
 }
 
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 #define hw_ptr_error(substream, fmt, args...)                          \
        do {                                                            \
                if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {          \
@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
 
 #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
 
-#define xrun_debug(substream, mask)    0
-#define xrun(substream)                        do { } while (0)
 #define hw_ptr_error(substream, fmt, args...) do { } while (0)
 #define xrun_log(substream, pos)       do { } while (0)
 #define xrun_log_show(substream)       do { } while (0)
index fff62cc8607c49bb08daa62a132c0c2d03d1824d..971a84a4fa77692336ab6e520adc651afe721b32 100644 (file)
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
 }
 
 int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
-               ak4113_write_t *write, const unsigned char pgm[5],
+               ak4113_write_t *write, const unsigned char *pgm,
                void *private_data, struct ak4113 **r_ak4113)
 {
        struct ak4113 *chip;
index 725fef0f59a379d5dd8e2a71e1993dcf151046fb..a4127bab9231fcb05ce72ac1c52b470e441b57a1 100644 (file)
@@ -363,13 +363,13 @@ static void vidc_audio_trigger(int dev, int enable_bits)
        struct audio_operations *adev = audio_devs[dev];
 
        if (enable_bits & PCM_ENABLE_OUTPUT) {
-               if (!(adev->flags & DMA_ACTIVE)) {
+               if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
                        unsigned long flags;
 
                        local_irq_save(flags);
 
                        /* prevent recusion */
-                       adev->flags |= DMA_ACTIVE;
+                       adev->dmap_out->flags |= DMA_ACTIVE;
 
                        dma_interrupt = vidc_audio_dma_interrupt;
                        vidc_sound_dma_irq(0, NULL);
index 1caf5e3c1f6ad481064ea70cced23293333de96a..e68c98ef4041508c2f9a2361172ab592be3ec90c 100644 (file)
@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
        0x10140523, /* Thinkpad R40 */
        0x10140534, /* Thinkpad X31 */
        0x10140537, /* Thinkpad T41p */
+       0x1014053e, /* Thinkpad R40e */
        0x10140554, /* Thinkpad T42p/R50p */
        0x10140567, /* Thinkpad T43p 2668-G7U */
        0x10140581, /* Thinkpad X41-2527 */
        0x10280160, /* Dell Dimension 2400 */
        0x104380b0, /* Asus A7V8X-MX */
        0x11790241, /* Toshiba Satellite A-15 S127 */
+       0x1179ff10, /* Toshiba P500 */
        0x144dc01a, /* Samsung NP-X20C004/SEG */
        0 /* end */
 };
index 1ded64e056433e22f8e96d8b0fbeb6dbf2c557d4..329968edca9b840fc622602535b0088cdb73bd6c 100644 (file)
@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
                                                struct snd_pcm_substream *substream)
 {
        size_t ptr;
-       unsigned int reg;
+       unsigned int reg, rem, tries;
+
        if (!rec->running)
                return 0;
 #if 1 // this seems better..
        reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
-       ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1);
-       ptr >>= rec->shift;
+       for (tries = 0; tries < 3; tries++) {
+               rem = snd_cmipci_read_w(cm, reg);
+               if (rem < rec->dma_size)
+                       goto ok;
+       } 
+       printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
+       return SNDRV_PCM_POS_XRUN;
+ok:
+       ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
 #else
        reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
        ptr = snd_cmipci_read(cm, reg) - rec->offset;
index 8dab82d7d19d1368abdcb26dd25b7ae581a058b2..668a5ec044992f227f0f7cf37a61325ea5078549 100644 (file)
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
                        goto ctl_error;
 #endif
 
-       if ((err = snd_card_register(card)) < 0) {
-               snd_card_free(card);
+       err = snd_card_register(card);
+       if (err < 0)
                goto ctl_error;
-       }
        snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
 
        pci_set_drvdata(pci, chip);
index 7e8e7da592a98e01faf4804e6983dba9fc07878c..ea4256b08a38206bfed31079eb341dc23ee76d09 100644 (file)
@@ -1161,13 +1161,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
                                unsigned long count, unsigned long pos)
 {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
 
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos >= MIXART_BA0_SIZE)
                return 0;
-       if(pos + count > MIXART_BA0_SIZE)
-               count = (long)(MIXART_BA0_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
+       maxsize = MIXART_BA0_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
                return -EFAULT;
        return count;
 }
@@ -1180,13 +1182,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
                                unsigned long count, unsigned long pos)
 {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
 
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos > MIXART_BA1_SIZE)
                return 0;
-       if(pos + count > MIXART_BA1_SIZE)
-               count = (long)(MIXART_BA1_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
+       maxsize = MIXART_BA1_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
                return -EFAULT;
        return count;
 }
index 9ef6b96373f598cbb2bf670953a6a85a96bf710c..3e6628c8e6659b943b09ece126afe76f11421e97 100644 (file)
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
        runtime->dma_bytes = params_buffer_bytes(params);
 
-       prtd->params = rtd->dai->cpu_dai->dma_data;
+       prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
 
        prtd->dma_buffer = runtime->dma_addr;
index e588e63f18d205e6e7f1d118b4982711f867cd51..0b59806905d1d815a62acfbf395abbf0bebdec3f 100644 (file)
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
        ssc_p->dma_params[dir] = dma_params;
 
        /*
-        * The cpu_dai->dma_data field is only used to communicate the
-        * appropriate DMA parameters to the pcm driver hw_params()
+        * The snd_soc_pcm_stream->dma_data field is only used to communicate
+        * the appropriate DMA parameters to the pcm driver hw_params()
         * function.  It should not be used for other purposes
         * as it is common to all substreams.
         */
-       rtd->dai->cpu_dai->dma_data = dma_params;
+       snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
 
        channels = params_channels(params);
 
index a1bbe16b7f9613e3129ebdb8819125c2b7c7463a..bcfa53271673eb802ae2fe1117aee84087a5663b 100644 (file)
@@ -80,9 +80,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
 static int ac97_soc_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_card *card = socdev->card;
        struct snd_soc_codec *codec;
        struct snd_ac97_bus *ac97_bus;
        struct snd_ac97_template ac97_template;
+       int i;
        int ret = 0;
 
        printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -102,12 +104,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
 
-       ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
-       if (ret < 0) {
-               printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
-               goto err;
-       }
-
        /* register pcms */
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0)
@@ -123,6 +119,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto bus_err;
 
+       for (i = 0; i < card->num_links; i++) {
+               if (card->dai_link[i].codec_dai->ac97_control) {
+                       snd_ac97_dev_add_pdata(codec->ac97,
+                               card->dai_link[i].cpu_dai->ac97_pdata);
+               }
+       }
+
        return 0;
 
 bus_err:
index f9f367d29a9095e8bc5a44be2da0da9b45f4ba7e..d50f1699ccb2e6d63e07984cc0fcd80b0a22dc5c 100644 (file)
@@ -778,7 +778,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
        if (dac33->fifo_mode) {
                /* Generic for all FIFO modes */
                /* 50-51 : ASRC Control registers */
-               dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
+               dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
                dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
 
                /* Write registers 0x34 and 0x35 (MSB, LSB) */
@@ -1038,11 +1038,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
        case SND_SOC_DAIFMT_DSP_A:
                aictrl_a |= DAC33_AFMT_DSP;
                aictrl_b &= ~DAC33_DATA_DELAY_MASK;
-               aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
-               break;
-       case SND_SOC_DAIFMT_DSP_B:
-               aictrl_a |= DAC33_AFMT_DSP;
-               aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
+               aictrl_b |= DAC33_DATA_DELAY(0);
                break;
        case SND_SOC_DAIFMT_RIGHT_J:
                aictrl_a |= DAC33_AFMT_RIGHT_J;
@@ -1066,7 +1062,7 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
 {
        /* 44-46: DAC Control Registers */
        /* A : DAC sample rate Fsref/1.5 */
-       dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
+       dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
        /* B : DAC src=normal, not muted */
        dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
                                             DAC33_DACSRCL_LEFT);
index 29f3771c33a4448838b3934b9f7a430be737e142..f8355ac76a42e736245c52d3a03b2c7c35c5d0c0 100644 (file)
@@ -3007,34 +3007,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               /* Switch over to startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   (1 << WM8994_VMID_RAMP_SHIFT));
-
-               /* Disable main biases */
-               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                   WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
+               if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+                       /* Switch over to startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           (1 << WM8994_VMID_RAMP_SHIFT));
 
-               /* Discharge line */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH);
+                       /* Disable main biases */
+                       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                                           WM8994_BIAS_ENA |
+                                           WM8994_VMID_SEL_MASK, 0);
 
-               msleep(5);
+                       /* Discharge line */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH);
 
-               /* Switch off startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK, 0);
+                       msleep(5);
 
+                       /* Switch off startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK, 0);
+               }
                break;
        }
        codec->bias_level = level;
@@ -3401,7 +3406,7 @@ struct snd_soc_dai wm8994_dai[] = {
                        .rates = WM8994_RATES,
                        .formats = WM8994_FORMATS,
                },
-               .playback = {
+               .capture = {
                        .stream_name = "AIF3 Capture",
                        .channels_min = 2,
                        .channels_max = 2,
@@ -3730,11 +3735,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
        case 3:
                wm8994->hubs.dcs_codes = -5;
                wm8994->hubs.hp_startup_mode = 1;
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        default:
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        }
-                          
 
        /* Remember if AIFnLRCLK is configured as a GPIO.  This should be
         * configured on init - if a system wants to do this dynamically
index 0ad9f5d536c67bf89afe1172ef863cff2fdfd6d0..e1f225a3ac46fbd2869378b273dcc32fa9319aca 100644 (file)
@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = {
 static const struct soc_enum speaker_mode =
        SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
 
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 {
        unsigned int reg;
        int count = 0;
+       unsigned int val;
+
+       val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
+
+       /* Trigger the command */
+       snd_soc_write(codec, WM8993_DC_SERVO_0, val);
 
        dev_dbg(codec->dev, "Waiting for DC servo...\n");
 
        do {
                count++;
                msleep(1);
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
+               reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
                dev_dbg(codec->dev, "DC servo: %x\n", reg);
-       } while (reg & WM8993_DCS_DATAPATH_BUSY);
+       } while (reg & op && count < 400);
 
-       if (reg & WM8993_DCS_DATAPATH_BUSY)
+       if (reg & op)
                dev_err(codec->dev, "Timed out waiting for DC Servo\n");
 }
 
@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
 static void calibrate_dc_servo(struct snd_soc_codec *codec)
 {
        struct wm_hubs_data *hubs = codec->private_data;
-       u16 reg, dcs_cfg;
+       u16 reg, reg_l, reg_r, dcs_cfg;
 
        /* Set for 32 series updates */
        snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
                            WM8993_DCS_SERIES_NO_01_MASK,
                            32 << WM8993_DCS_SERIES_NO_01_SHIFT);
-
-       /* Enable the DC servo.  Write all bits to avoid triggering startup
-        * or write calibration.
-        */
-       snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
-                           0xFFFF,
-                           WM8993_DCS_ENA_CHAN_0 |
-                           WM8993_DCS_ENA_CHAN_1 |
-                           WM8993_DCS_TRIG_SERIES_1 |
-                           WM8993_DCS_TRIG_SERIES_0);
-
-       wait_for_dc_servo(codec);
+       wait_for_dc_servo(codec,
+                         WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
 
        /* Apply correction to DC servo result */
        if (hubs->dcs_codes) {
                dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
                        hubs->dcs_codes);
 
+               /* Different chips in the family support different
+                * readback methods.
+                */
+               switch (hubs->dcs_readback_mode) {
+               case 0:
+                       reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+                               & WM8993_DCS_INTEG_CHAN_0_MASK;;
+                       reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+                               & WM8993_DCS_INTEG_CHAN_1_MASK;
+                       break;
+               case 1:
+                       reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+                       reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+                               >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+                       reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+                       break;
+               default:
+                       WARN(1, "Unknown DCS readback method");
+                       break;
+               }
+
                /* HPOUT1L */
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
-                       WM8993_DCS_INTEG_CHAN_0_MASK;;
-               reg += hubs->dcs_codes;
-               dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+               if (reg_l + hubs->dcs_codes > 0 &&
+                   reg_l + hubs->dcs_codes < 0xff)
+                       reg_l += hubs->dcs_codes;
+               dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
                /* HPOUT1R */
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
-                       WM8993_DCS_INTEG_CHAN_1_MASK;
-               reg += hubs->dcs_codes;
-               dcs_cfg |= reg;
+               if (reg_r + hubs->dcs_codes > 0 &&
+                   reg_r + hubs->dcs_codes < 0xff)
+                       reg_r += hubs->dcs_codes;
+               dcs_cfg |= reg_r;
 
                /* Do it */
                snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
-               snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
-                                   WM8993_DCS_TRIG_DAC_WR_0 |
-                                   WM8993_DCS_TRIG_DAC_WR_1,
-                                   WM8993_DCS_TRIG_DAC_WR_0 |
-                                   WM8993_DCS_TRIG_DAC_WR_1);
-
-               wait_for_dc_servo(codec);
+               wait_for_dc_servo(codec,
+                                 WM8993_DCS_TRIG_DAC_WR_0 |
+                                 WM8993_DCS_TRIG_DAC_WR_1);
        }
 }
 
@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm_hubs_data *hubs = codec->private_data;
        int ret;
 
        ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
 
+       /* If we're applying an offset correction then updating the
+        * callibration would be likely to introduce further offsets. */
+       if (hubs->dcs_codes)
+               return ret;
+
        /* Only need to do this if the outputs are active */
        if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
            & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
index 420104fe9c90467a1c9027c3e9bc234cab28ecc8..e51c16683589ffb612f3ec58761f01ea24c7223e 100644 (file)
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
 /* This *must* be the first element of the codec->private_data struct */
 struct wm_hubs_data {
        int dcs_codes;
+       int dcs_readback_mode;
        int hp_startup_mode;
 };
 
index 6362ca05506e0e011312ff023446b2eb0a7da440..4aad7ecc90a24d974ab86dec2c9f97caa9cf9bb9 100644 (file)
@@ -585,7 +585,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
        dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
 
        davinci_i2s_dai.private_data = dev;
-       davinci_i2s_dai.dma_data = dev->dma_params;
+       davinci_i2s_dai.capture.dma_data = dev->dma_params;
+       davinci_i2s_dai.playback.dma_data = dev->dma_params;
        ret = snd_soc_register_dai(&davinci_i2s_dai);
        if (ret != 0)
                goto err_free_mem;
index ab6518d86f1886c14b18fe4c436cba2a9d6c2f07..c056bfbe03407f8182beb8c487092379e6959bb0 100644 (file)
@@ -917,7 +917,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 
        dma_data->channel = res->start;
        davinci_mcasp_dai[pdata->op_mode].private_data = dev;
-       davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
        davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
        ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
 
index 80c7fdf2f521542d83babc9855d3a362de545a19..2dc406f42fe7f5ca5f92a86649b23a439fba18cc 100644 (file)
@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_hardware *ppcm;
        int ret = 0;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data;
+       struct davinci_pcm_dma_params *pa;
        struct davinci_pcm_dma_params *params;
+
+       pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        if (!pa)
                return -ENODEV;
        params = &pa[substream->stream];
index c7d0fd9b7de884522ee02f1ef838dccd8ed53269..7174b4c710de4451f974214558af0dc27516457d 100644 (file)
@@ -1,6 +1,6 @@
 config SND_IMX_SOC
        tristate "SoC Audio for Freescale i.MX CPUs"
-       depends on ARCH_MXC && BROKEN
+       depends on ARCH_MXC
        select SND_PCM
        select FIQ
        select SND_SOC_AC97_BUS
index 19452e44afdc7190c4ba7995d4a3c802f6d35bde..c78c000e2afe908d8d3b521dfdb4506308029f74 100644 (file)
@@ -83,11 +83,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
 static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int ret;
 
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
        iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
        if (iprtd->dma < 0) {
                pr_err("Failed to claim the audio DMA\n");
@@ -192,10 +194,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int err;
 
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
        iprtd->substream = substream;
        iprtd->buf = (unsigned int *)substream->dma_buffer.area;
        iprtd->period_cnt = 0;
index 56f46a75d2972515f19e3bb89c8bf6f50960375d..28e55c7b14b4cffa35b3b70c352a1a239eb3ed3b 100644 (file)
@@ -234,17 +234,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *cpu_dai)
 {
        struct imx_ssi *ssi = cpu_dai->private_data;
+       struct imx_pcm_dma_params *dma_data;
        u32 reg, sccr;
 
        /* Tx/Rx config */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                reg = SSI_STCCR;
-               cpu_dai->dma_data = &ssi->dma_params_tx;
+               dma_data = &ssi->dma_params_tx;
        } else {
                reg = SSI_SRCCR;
-               cpu_dai->dma_data = &ssi->dma_params_rx;
+               dma_data = &ssi->dma_params_rx;
        }
 
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+
        sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
 
        /* DAI data (word) size */
index e814a9591f78057553e877549a40e31f3522de66..8ad9dc9010078f3b07d744a04030ad31bab7bf8b 100644 (file)
@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
        omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
        omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
                                                        OMAP_DMA_DATA_TYPE_S16;
-       cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream,
+               &omap_mcbsp_dai_dma_params[id][substream->stream]);
 
        if (mcbsp_data->configured) {
                /* McBSP already configured by another stream */
index 25f19e4728bf50df3616075ba28d7666ed455fd6..b7f4f7e015f3f4ef4c0dc91f46e1e4573ce39259 100644 (file)
@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
        int stream = substream->stream;
        int channels, err, link_mask = 0;
 
-       cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
+       snd_soc_dai_set_dma_data(cpu_dai, substream,
+                                &omap_mcpdm_dai_dma_params[stream]);
 
        channels = params_channels(params);
        switch (channels) {
index 825db385f01f16d3b0f64a21fbfc3238c801e873..39456447132c86405730249f8cc48af7589e64a7 100644 (file)
@@ -60,12 +60,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
        struct omap_runtime_data *prtd = runtime->private_data;
        unsigned long flags;
 
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
+       if ((cpu_is_omap1510())) {
                /*
                 * OMAP1510 doesn't fully support DMA progress counter
                 * and there is no software emulation implemented yet,
-                * so have to maintain our own playback progress counter
+                * so have to maintain our own progress counters
                 * that can be used by omap_pcm_pointer() instead.
                 */
                spin_lock_irqsave(&prtd->lock, flags);
@@ -100,9 +99,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct omap_runtime_data *prtd = runtime->private_data;
-       struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
+       struct omap_pcm_dma_data *dma_data;
        int err = 0;
 
+       dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
        /* return if this is a bufferless transfer e.g.
         * codec <--> BT codec or GSM modem -- lg FIXME */
        if (!dma_data)
@@ -189,8 +190,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
        dma_params.frame_count  = runtime->periods;
        omap_set_dma_params(prtd->dma_ch, &dma_params);
 
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
+       if ((cpu_is_omap1510()))
                omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
                              OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
        else
@@ -248,14 +248,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
        dma_addr_t ptr;
        snd_pcm_uframes_t offset;
 
-       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+       if (cpu_is_omap1510()) {
+               offset = prtd->period_index * runtime->period_size;
+       } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
                ptr = omap_get_dma_dst_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else if (!(cpu_is_omap1510())) {
+       } else {
                ptr = omap_get_dma_src_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else
-               offset = prtd->period_index * runtime->period_size;
+       }
 
        if (offset >= runtime->buffer_size)
                offset = 0;
index 9e95e5117c88f8c6a95cbfe25e60cd66f22c92e2..6959c5199160305c98ed7300f3ea13162a7b9348 100644 (file)
@@ -121,10 +121,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
                ssp_disable(ssp);
        }
 
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
+
        return ret;
 }
 
@@ -141,10 +140,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
                clk_disable(ssp->clk);
        }
 
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
 }
 
 #ifdef CONFIG_PM
@@ -569,19 +566,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
        u32 sspsp;
        int width = snd_pcm_format_physical_width(params_format(params));
        int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+       struct pxa2xx_pcm_dma_params *dma_data;
+
+       dma_data = snd_soc_dai_get_dma_data(dai, substream);
 
        /* generate correct DMA params */
-       if (cpu_dai->dma_data)
-               kfree(cpu_dai->dma_data);
+       kfree(dma_data);
 
        /* Network mode with one active slot (ttsa == 1) can be used
         * to force 16-bit frame width on the wire (for S16_LE), even
         * with two channels. Use 16-bit DMA transfers for this case.
         */
-       cpu_dai->dma_data = ssp_get_dma_params(ssp,
+       dma_data = ssp_get_dma_params(ssp,
                        ((chn == 2) && (ttsa != 1)) || (width == 32),
                        substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 
+       snd_soc_dai_set_dma_data(dai, substream, dma_data);
+
        /* we can only change the settings if the port is not in use */
        if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
                return 0;
index e9ae7b3a7e006cc33cc74e128f9f1429f3ebc9ac..d314115e3dd726750afbb8706b72cc51fbb3104b 100644 (file)
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
+               dma_data = &pxa2xx_ac97_pcm_stereo_out;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in;
+               dma_data = &pxa2xx_ac97_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
+               dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+               dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in;
+               snd_soc_dai_set_dma_data(cpu_dai, substream,
+                                        &pxa2xx_ac97_pcm_mic_mono_in);
 
        return 0;
 }
index 6b8f655d1ad826d7556317b17e1f1074fa7e49f3..c1a5275721e4f0eb2812842d31555c84b16f206c 100644 (file)
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        BUG_ON(IS_ERR(clk_i2s));
        clk_enable(clk_i2s);
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
        pxa_i2s_wait();
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out;
+               dma_data = &pxa2xx_i2s_pcm_stereo_out;
        else
-               cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in;
+               dma_data = &pxa2xx_i2s_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        /* is port used by another stream */
        if (!(SACR0 & SACR0_ENB)) {
index d38e39575f510a6519b0b115189848012dc7a73a..adc7e6f15f9367b5acbf16c02f633af3583a16da 100644 (file)
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct pxa2xx_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+       struct pxa2xx_pcm_dma_params *dma;
        int ret;
 
+       dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
        /* return if this is a bufferless transfer e.g.
         * codec <--> BT codec or GSM modem -- lg FIXME */
        if (!dma)
index ee8ed9d7e7033318ae563fcc7cf827c65d08d427..ecf4fd04ae9651c2a264c9428fcf6d1caae6777f 100644 (file)
@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct s3c_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &s3c_ac97_pcm_out;
+               dma_data = &s3c_ac97_pcm_out;
        else
-               cpu_dai->dma_data = &s3c_ac97_pcm_in;
+               dma_data = &s3c_ac97_pcm_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        u32 ac_glbctrl;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
        writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-       s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+       s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
        return 0;
 }
@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
        else
-               cpu_dai->dma_data = &s3c_ac97_mic_in;
+               snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
 
        return 0;
 }
@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 {
        u32 ac_glbctrl;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
        ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 
        writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-       s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+       s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
        return 0;
 }
index 7725e26d6c914c99ad84ce89864320c944abbd00..1b61c23ff300be0ef2c593cf5e813e20aeb2cb5d 100644 (file)
@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s3c24xx_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
        unsigned long totbytes = params_buffer_bytes(params);
+       struct s3c_dma_params *dma =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        int ret = 0;
 
+
        pr_debug("Entered %s\n", __func__);
 
        /* return if this is a bufferless transfer e.g.
index e994d8374fe62dc313aca6077e8bed20c5fb186f..88515946b6c06560810fabf8bcabd8ea560cafc2 100644 (file)
@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai_link *dai = rtd->dai;
        struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
+       struct s3c_dma_params *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dai->cpu_dai->dma_data = i2s->dma_playback;
+               dma_data = i2s->dma_playback;
        else
-               dai->cpu_dai->dma_data = i2s->dma_capture;
+               dma_data = i2s->dma_capture;
+
+       snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
 
        /* Working copies of register */
        iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
        unsigned long irqs;
        int ret = 0;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                 * of the auto reload mechanism of S3C24XX.
                 * This call won't bother S3C64XX.
                 */
-               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
                break;
 
index a98f40c3cd291eea98e9a4b9778d5cc5a910c401..326f0a9e7e3076ebbce6af2500c86cb56fce5f60 100644 (file)
@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai_link *dai = rtd->dai;
        struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
+       struct s3c_dma_params *dma_data;
        void __iomem *regs = pcm->regs;
        struct clk *clk;
        int sclk_div, sync_div;
@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
        dev_dbg(pcm->dev, "Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dai->cpu_dai->dma_data = pcm->dma_playback;
+               dma_data = pcm->dma_playback;
        else
-               dai->cpu_dai->dma_data = pcm->dma_capture;
+               dma_data = pcm->dma_capture;
+
+       snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
 
        /* Strictly check for sample size */
        switch (params_format(params)) {
index 0bc5950b9f0299d1dd6d7c6bdf830e2f12380747..c3ac890a3986184f86ed00a1dc300fdb10d7d258 100644 (file)
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct s3c_dma_params *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+               dma_data = &s3c24xx_i2s_pcm_stereo_out;
        else
-               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+               dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
 
        /* Working copies of register */
        iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S8:
                iismod &= ~S3C2410_IISMOD_16BIT;
-               ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
+               dma_data->dma_size = 1;
                break;
        case SNDRV_PCM_FORMAT_S16_LE:
                iismod |= S3C2410_IISMOD_16BIT;
-               ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
+               dma_data->dma_size = 2;
                break;
        default:
                return -EINVAL;
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        int ret = 0;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                else
                        s3c24xx_snd_txctrl(1);
 
-               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
index c5cda187ecab6d5f72285959e39e525d34f3ffb9..fa23854c5f3aa6297e45bb5f2a50fee9edf65df5 100644 (file)
@@ -518,7 +518,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
 
        s6000_i2s_dai.dev = &pdev->dev;
        s6000_i2s_dai.private_data = dev;
-       s6000_i2s_dai.dma_data = &dev->dma_params;
+       s6000_i2s_dai.capture.dma_data = &dev->dma_params;
+       s6000_i2s_dai.playback.dma_data = &dev->dma_params;
 
        dev->sifbase = sifmem->start;
        dev->scbbase = mmio;
index 1d61109e09fa272e3b7e6855e8f2ba303f2e8a95..9c7f7f00cebb45706aa6c8f7302b4a371d469ceb 100644 (file)
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int channel;
        unsigned int period_size;
        unsigned int dma_offset;
        dma_addr_t dma_pos;
        dma_addr_t src, dst;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        period_size = snd_pcm_lib_period_bytes(substream);
        dma_offset = prtd->period * period_size;
        dma_pos = runtime->dma_addr + dma_offset;
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
 {
        struct snd_pcm *pcm = data;
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
        struct s6000_runtime_data *prtd;
        unsigned int has_xrun;
        int i, ret = IRQ_NONE;
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
 {
        struct s6000_runtime_data *prtd = substream->runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        unsigned long flags;
        int srcinc;
        u32 dma;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        spin_lock_irqsave(&prtd->lock, flags);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
 {
        struct s6000_runtime_data *prtd = substream->runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        unsigned long flags;
        u32 channel;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                channel = par->dma_out;
        else
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
 static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int ret;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        ret = par->trigger(substream, cmd, 0);
        if (ret < 0)
                return ret;
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
 static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd = runtime->private_data;
        unsigned long flags;
        unsigned int offset;
        dma_addr_t count;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        spin_lock_irqsave(&prtd->lock, flags);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
 static int s6000_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd;
        int ret;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
        snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
 
        ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *hw_params)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int ret;
        ret = snd_pcm_lib_malloc_pages(substream,
                                       params_buffer_bytes(hw_params));
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (par->same_rate) {
                spin_lock(&par->lock);
                if (par->rate == -1 ||
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
 static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
 
        spin_lock(&par->lock);
        par->in_use &= ~(1 << substream->stream);
@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = {
 static void s6000_pcm_free(struct snd_pcm *pcm)
 {
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
 
        free_irq(params->irq, pcm);
        snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card,
                         struct snd_soc_dai *dai, struct snd_pcm *pcm)
 {
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params;
        int res;
 
+       params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (!card->dev->dma_mask)
                card->dev->dma_mask = &s6000_pcm_dmamask;
        if (!card->dev->coherent_dma_mask)
index 106674979b535a54110ba0b1a0e47048178bb9e9..f07f6d8b93e14cf8f038416154361bc7b8038aee 100644 (file)
@@ -32,6 +32,7 @@ config SND_SOC_SH4_SIU
        select DMA_ENGINE
        select DMADEVICES
        select SH_DMAE
+       select FW_LOADER
 
 ##
 ## Boards
index c8b0556ef4316a0030a4b392226fc733dbf48877..d0efd5eaaa0b33d53a1c89948f274bbe29eb7ea4 100644 (file)
@@ -1548,7 +1548,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
                        mutex_unlock(&codec->mutex);
                        return ret;
                }
-               if (card->dai_link[i].codec_dai->ac97_control) {
+               /* Check for codec->ac97 to handle the ac97.c fun */
+               if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
                        snd_ac97_dev_add_pdata(codec->ac97,
                                card->dai_link[i].cpu_dai->ac97_pdata);
                }