src = readl(&clk->src_peric0);
                div = readl(&clk->div_peric3);
                break;
+       case PERIPH_ID_I2S0:
+               src = readl(&clk->src_mau);
+               div = readl(&clk->div_mau);
        case PERIPH_ID_SPI0:
        case PERIPH_ID_SPI1:
                src = readl(&clk->src_peric1);
        return 0;
 }
 
-void exynos5_set_i2s_clk_source(void)
+int exynos5_set_i2s_clk_source(unsigned int i2s_id)
 {
        struct exynos5_clock *clk =
                (struct exynos5_clock *)samsung_get_base_clock();
-
-       clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
-                       (CLK_SRC_SCLK_EPLL));
+       unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
+
+       if (i2s_id == 0) {
+               setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
+               clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
+                               (CLK_SRC_SCLK_EPLL));
+               setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
+       } else if (i2s_id == 1) {
+               clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
+                               (CLK_SRC_SCLK_EPLL));
+       } else {
+               return -1;
+       }
+       return 0;
 }
 
 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
-                                       unsigned int dst_frq)
+                                 unsigned int dst_frq,
+                                 unsigned int i2s_id)
 {
        struct exynos5_clock *clk =
                (struct exynos5_clock *)samsung_get_base_clock();
        }
 
        div = (src_frq / dst_frq);
-       if (div > AUDIO_1_RATIO_MASK) {
-               debug("%s: Frequency ratio is out of range\n", __func__);
-               debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+       if (i2s_id == 0) {
+               if (div > AUDIO_0_RATIO_MASK) {
+                       debug("%s: Frequency ratio is out of range\n",
+                             __func__);
+                       debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+                       return -1;
+               }
+               clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
+                               (div & AUDIO_0_RATIO_MASK));
+       } else if(i2s_id == 1) {
+               if (div > AUDIO_1_RATIO_MASK) {
+                       debug("%s: Frequency ratio is out of range\n",
+                             __func__);
+                       debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+                       return -1;
+               }
+               clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
+                               (div & AUDIO_1_RATIO_MASK));
+       } else {
                return -1;
        }
-       clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
-                               (div & AUDIO_1_RATIO_MASK));
        return 0;
 }
 
                return 0;
 }
 
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+                         unsigned int i2s_id)
 {
-
        if (cpu_is_exynos5())
-               return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq);
+               return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
        else
                return 0;
 }
 
-void set_i2s_clk_source(void)
+int set_i2s_clk_source(unsigned int i2s_id)
 {
        if (cpu_is_exynos5())
-               exynos5_set_i2s_clk_source();
+               return exynos5_set_i2s_clk_source(i2s_id);
+       else
+               return 0;
 }
 
 int set_epll_clk(unsigned long rate)
 
 {
        int i;
        struct exynos5_gpio_part1 *gpio1 =
-               (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
+               (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
+       struct exynos5_gpio_part4 *gpio4 =
+               (struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
 
-       for (i = 0; i < 5; i++)
-               s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+       switch (peripheral) {
+       case PERIPH_ID_I2S0:
+               for (i = 0; i < 5; i++)
+                       s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
+               break;
+       case PERIPH_ID_I2S1:
+               for (i = 0; i < 5; i++)
+                       s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
+               break;
+       }
 }
 
 void exynos5_spi_config(int peripheral)
        case PERIPH_ID_I2C7:
                exynos5_i2c_config(peripheral, flags);
                break;
+       case PERIPH_ID_I2S0:
        case PERIPH_ID_I2S1:
                exynos5_i2s_config(peripheral);
                break;
 
 int exynos_pinmux_config(int peripheral, int flags)
 {
-       if (cpu_is_exynos5())
+       if (cpu_is_exynos5()) {
                return exynos5_pinmux_config(peripheral, flags);
-       else if (cpu_is_exynos4())
+       } else if (cpu_is_exynos4()) {
                return exynos4_pinmux_config(peripheral, flags);
-       else {
+       } else {
                debug("pinmux functionality not supported\n");
                return -1;
        }
 
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
-void set_i2s_clk_source(void);
-int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
+int set_i2s_clk_source(unsigned int i2s_id);
+int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
+                               unsigned int i2s_id);
 int set_epll_clk(unsigned long rate);
 int set_spi_clk(int periph_id, unsigned int rate);
 
 
 #define AUDIO_0_RATIO_MASK             0x0f
 #define AUDIO_1_RATIO_MASK             0x0f
 
+#define AUDIO0_SEL_MASK                        0xf
 #define AUDIO1_SEL_MASK                        0xf
+
 #define CLK_SRC_SCLK_EPLL              0x7
+#define CLK_SRC_MOUT_EPLL              (1<<12)
+#define AUDIO_CLKMUX_ASS               (1<<0)
 
 /* CON0 bit-fields */
 #define EPLL_CON0_MDIV_MASK            0x1ff
 
 #define EXYNOS4_SPI_ISP_BASE           DEVICE_NOT_AVAILABLE
 #define EXYNOS4_ACE_SFR_BASE           DEVICE_NOT_AVAILABLE
 #define EXYNOS4_DMC_PHY_BASE           DEVICE_NOT_AVAILABLE
+#define EXYNOS4_AUDIOSS_BASE           DEVICE_NOT_AVAILABLE
 
 /* EXYNOS4X12 */
 #define EXYNOS4X12_GPIO_PART3_BASE     0x03860000
 #define EXYNOS4X12_SPI_ISP_BASE                DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_ACE_SFR_BASE                DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_DMC_PHY_BASE                DEVICE_NOT_AVAILABLE
+#define EXYNOS4X12_AUDIOSS_BASE                DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5 Common*/
 #define EXYNOS5_I2C_SPACING            0x10000
 
+#define EXYNOS5_AUDIOSS_BASE           0x03810000
 #define EXYNOS5_GPIO_PART4_BASE                0x03860000
 #define EXYNOS5_PRO_ID                 0x10000000
 #define EXYNOS5_CLOCK_BASE             0x10010000
 SAMSUNG_BASE(tzpc, TZPC_BASE)
 SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
 SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
+SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
 #endif
 
 #endif /* _EXYNOS4_CPU_H */
 
        PERIPH_ID_SDMMC1,
        PERIPH_ID_SDMMC2,
        PERIPH_ID_SDMMC3,
+       PERIPH_ID_I2S0 = 98,
        PERIPH_ID_I2S1 = 99,
 
        /* Since following peripherals do
 
                con &= ~CON_TXCH_PAUSE;
 
        } else {
-
                con |=  CON_TXCH_PAUSE;
                con &= ~CON_ACTIVE;
        }
                break;
        default:
                debug("%s: Invalid format priority [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
+                     (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
                return -1;
        }
 
                break;
        default:
                debug("%s: Invalid clock ploarity input [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_INV_MASK));
+                     (fmt & SND_SOC_DAIFMT_INV_MASK));
                return -1;
        }
 
                break;
        default:
                debug("%s: Invalid master selection [0x%x]\n", __func__,
-                       (fmt & SND_SOC_DAIFMT_MASTER_MASK));
+                     (fmt & SND_SOC_DAIFMT_MASTER_MASK));
                return -1;
        }
 
                break;
        default:
                debug("%s: Invalid sample size input [0x%x]\n",
-                       __func__, blc);
+                     __func__, blc);
                return -1;
        }
        writel(mod, &i2s_reg->mod);
        }
 
        /* Select Clk Source for Audio1 */
-       set_i2s_clk_source();
+       ret = set_i2s_clk_source(pi2s_tx->id);
+       if (ret == -1) {
+               debug("%s: unsupported clock for i2s-%d\n", __func__,
+                     pi2s_tx->id);
+               return -1;
+       }
 
        /* Set Prescaler to get MCLK */
-       set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
-                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)));
+       ret = set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
+                             (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                             pi2s_tx->id);
+       if (ret == -1) {
+               debug("%s: unsupported prescalar for i2s-%d\n", __func__,
+                     pi2s_tx->id);
+               return -1;
+       }
 
        /* Configure I2s format */
        ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |