writel(iismod, i2s->regs + S3C2412_IISMOD);
        pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
+
+       return 0;
+}
+
+static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
+                                 int clk_id, unsigned int freq, int dir)
+{
+       struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
+       u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
+
+       pr_debug("Entered %s\n", __func__);
+       pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
+
+       switch (clk_id) {
+       case S3C_I2SV2_CLKSRC_PCLK:
+               iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
+               break;
+
+       case S3C_I2SV2_CLKSRC_AUDIOBUS:
+               iismod |= S3C2412_IISMOD_IMS_SYSMUX;
+               break;
+
+       case S3C_I2SV2_CLKSRC_CDCLK:
+               /* Error if controller doesn't have the CDCLKCON bit */
+               if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
+                       return -EINVAL;
+
+               switch (dir) {
+               case SND_SOC_CLOCK_IN:
+                       iismod |= S3C64XX_IISMOD_CDCLKCON;
+                       break;
+               case SND_SOC_CLOCK_OUT:
+                       iismod &= ~S3C64XX_IISMOD_CDCLKCON;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       writel(iismod, i2s->regs + S3C2412_IISMOD);
+       pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
+
        return 0;
 }
 
                ops->hw_params = s3c_i2sv2_hw_params;
        ops->set_fmt = s3c2412_i2s_set_fmt;
        ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
+       ops->set_sysclk = s3c_i2sv2_set_sysclk;
 
        /* Allow overriding by (for example) IISv4 */
        if (!ops->delay)
 
 
 static struct s3c_i2sv2_info s3c2412_i2s;
 
-/*
- * Set S3C2412 Clock source
- */
-static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
-                                 int clk_id, unsigned int freq, int dir)
-{
-       u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
-
-       pr_debug("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id,
-           freq, dir);
-
-       switch (clk_id) {
-       case S3C2412_CLKSRC_PCLK:
-               iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
-               break;
-       case S3C2412_CLKSRC_I2SCLK:
-               iismod |= S3C2412_IISMOD_IMS_SYSMUX;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD);
-       return 0;
-}
-
 static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
 {
        return cpu_dai->private_data;
        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
 
 static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
-       .set_sysclk     = s3c2412_i2s_set_sysclk,
        .hw_params      = s3c2412_i2s_hw_params,
 };
 
 
        return cpu_dai->private_data;
 }
 
-static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
-                                 int clk_id, unsigned int freq, int dir)
-{
-       struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
-       u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
-
-       switch (clk_id) {
-       case S3C64XX_CLKSRC_PCLK:
-               iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
-               break;
-
-       case S3C64XX_CLKSRC_MUX:
-               iismod |= S3C2412_IISMOD_IMS_SYSMUX;
-               break;
-
-       case S3C64XX_CLKSRC_CDCLK:
-               switch (dir) {
-               case SND_SOC_CLOCK_IN:
-                       iismod |= S3C64XX_IISMOD_CDCLKCON;
-                       break;
-               case SND_SOC_CLOCK_OUT:
-                       iismod &= ~S3C64XX_IISMOD_CDCLKCON;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       writel(iismod, i2s->regs + S3C2412_IISMOD);
-
-       return 0;
-}
-
 static int s3c64xx_i2s_probe(struct platform_device *pdev,
                             struct snd_soc_dai *dai)
 {
 }
 
 
-static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
-       .set_sysclk     = s3c64xx_i2s_set_sysclk,       
-};
+static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
 
 static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
 {
        dai->probe = s3c64xx_i2s_probe;
        dai->ops = &s3c64xx_i2s_dai_ops;
 
+       i2s->feature |= S3C_FEATURE_CDCLKCON;
+
        i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
        i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];