Patchwork [U-Boot,V2,3/5] ARM: Added I2S0 clocks for audio

login
register
mail settings
Submitter Dani Krishna Mohan
Date Sept. 10, 2013, 3:02 p.m.
Message ID <1378825337-9661-4-git-send-email-krishna.md@samsung.com>
Download mbox | patch
Permalink /patch/273900/
State Superseded
Delegated to: Tom Rini
Headers show

Comments

Dani Krishna Mohan - Sept. 10, 2013, 3:02 p.m.
This patch makes the necessary changes for making use of
I2S0 channel instead of I2S1 channel on smdk board. This
changes are done to maintain the uniformity to use I2S0 channel.

Signed-off-by: Dani Krishna Mohan <krishna.md@samsung.com>
---
 arch/arm/cpu/armv7/exynos/clock.c         |   57 ++++++++++++++++++++++-------
 arch/arm/cpu/armv7/exynos/pinmux.c        |   15 +++++++-
 arch/arm/include/asm/arch-exynos/clk.h    |    5 ++-
 arch/arm/include/asm/arch-exynos/clock.h  |    4 ++
 arch/arm/include/asm/arch-exynos/cpu.h    |    4 ++
 arch/arm/include/asm/arch-exynos/periph.h |    1 +
 drivers/sound/samsung-i2s.c               |   14 +++----
 7 files changed, 75 insertions(+), 25 deletions(-)
Jaehoon Chung - Sept. 11, 2013, 12:39 a.m.
Hi Dani,

You refer to http://www.denx.de/wiki/U-Boot/CodingStyle

And cc'd Minkyu.

On 09/11/2013 12:02 AM, Dani Krishna Mohan wrote:
> This patch makes the necessary changes for making use of
> I2S0 channel instead of I2S1 channel on smdk board. This
> changes are done to maintain the uniformity to use I2S0 channel.
> 
> Signed-off-by: Dani Krishna Mohan <krishna.md@samsung.com>
> ---
>  arch/arm/cpu/armv7/exynos/clock.c         |   57 ++++++++++++++++++++++-------
>  arch/arm/cpu/armv7/exynos/pinmux.c        |   15 +++++++-
>  arch/arm/include/asm/arch-exynos/clk.h    |    5 ++-
>  arch/arm/include/asm/arch-exynos/clock.h  |    4 ++
>  arch/arm/include/asm/arch-exynos/cpu.h    |    4 ++
>  arch/arm/include/asm/arch-exynos/periph.h |    1 +
>  drivers/sound/samsung-i2s.c               |   14 +++----
>  7 files changed, 75 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
> index 0cb1a61..80ed282 100644
> --- a/arch/arm/cpu/armv7/exynos/clock.c
> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> @@ -282,6 +282,9 @@ static unsigned long exynos5_get_periph_rate(int peripheral)
>  		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);
> @@ -1146,17 +1149,29 @@ int exynos5_set_epll_clk(unsigned long rate)
>  	return 0;
>  }
>  
> -void exynos5_set_i2s_clk_source(void)
> +void 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));
> +	}
Can i2c_id get other value beside 0 or 1?
And Could you change the coding style.
>  }
>  
>  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();
> @@ -1169,13 +1184,26 @@ int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
>  	}
>  
>  	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);
> -		return -1;
> +	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));
>  	}
> -	clrsetbits_le32(&clk->div_peric4, AUDIO_1_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));
> +	}
Ditto.
>  	return 0;
>  }
>  
> @@ -1415,19 +1443,20 @@ int set_spi_clk(int periph_id, unsigned int rate)
>  		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)
> +void set_i2s_clk_source(unsigned int i2s_id)
>  {
>  	if (cpu_is_exynos5())
> -		exynos5_set_i2s_clk_source();
> +		exynos5_set_i2s_clk_source(i2s_id);
>  }
>  
>  int set_epll_clk(unsigned long rate)
> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
> index 1b05ebf..6d1029e 100644
> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
> @@ -221,9 +221,19 @@ static void exynos5_i2s_config(int peripheral)
>  	int i;
>  	struct exynos5_gpio_part1 *gpio1 =
>  		(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)
> @@ -296,6 +306,7 @@ static int exynos5_pinmux_config(int peripheral, int flags)
>  	case PERIPH_ID_I2C7:
>  		exynos5_i2c_config(peripheral, flags);
>  		break;
> +	case PERIPH_ID_I2S0:
>  	case PERIPH_ID_I2S1:
>  		exynos5_i2s_config(peripheral);
>  		break;
> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
> index 71075bd..a240ec7 100644
> --- a/arch/arm/include/asm/arch-exynos/clk.h
> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> @@ -31,8 +31,9 @@ void set_mmc_clk(int dev_index, unsigned int div);
>  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);
> +void 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);
>  
> diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h
> index 2b97b9a..cf26eef 100644
> --- a/arch/arm/include/asm/arch-exynos/clock.h
> +++ b/arch/arm/include/asm/arch-exynos/clock.h
> @@ -876,8 +876,12 @@ struct set_epll_con_val {
>  #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
> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
> index cb924fb..4b67191 100644
> --- a/arch/arm/include/asm/arch-exynos/cpu.h
> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
> @@ -50,6 +50,7 @@
>  #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
> @@ -85,10 +86,12 @@
>  #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
> @@ -226,6 +229,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
>  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 */
> diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
> index 9952155..64bd8b7 100644
> --- a/arch/arm/include/asm/arch-exynos/periph.h
> +++ b/arch/arm/include/asm/arch-exynos/periph.h
> @@ -34,6 +34,7 @@ enum periph_id {
>  	PERIPH_ID_SDMMC1,
>  	PERIPH_ID_SDMMC2,
>  	PERIPH_ID_SDMMC3,
> +	PERIPH_ID_I2S0 = 98,
>  	PERIPH_ID_I2S1 = 99,
>  
>  	/* Since following peripherals do
> diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c
> index 49921e5..9caa4d2 100644
> --- a/drivers/sound/samsung-i2s.c
> +++ b/drivers/sound/samsung-i2s.c
> @@ -67,7 +67,6 @@ static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
>  		con &= ~CON_TXCH_PAUSE;
>  
>  	} else {
> -
>  		con |=  CON_TXCH_PAUSE;
>  		con &= ~CON_ACTIVE;
>  	}
> @@ -172,7 +171,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
>  		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;
>  	}
>  
> @@ -191,7 +190,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
>  		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;
>  	}
>  
> @@ -209,7 +208,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
>  		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;
>  	}
>  
> @@ -250,7 +249,7 @@ int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc)
>  		break;
>  	default:
>  		debug("%s: Invalid sample size input [0x%x]\n",
> -			__func__, blc);
> +		      __func__, blc);
>  		return -1;
>  	}
>  	writel(mod, &i2s_reg->mod);
> @@ -313,11 +312,12 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx)
>  	}
>  
>  	/* Select Clk Source for Audio1 */
> -	set_i2s_clk_source();
> +	set_i2s_clk_source(pi2s_tx->id);
>  
>  	/* Set Prescaler to get MCLK */
>  	set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
> -				(pi2s_tx->samplingrate * (pi2s_tx->rfs)));
> +			      (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
> +			      pi2s_tx->id);
>  
>  	/* Configure I2s format */
>  	ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
>
Dani Krishna Mohan - Sept. 11, 2013, 11:10 a.m.
Hello Mr Jaehoon,
    I have done the changes as suggested by you and resubmitted
all 5 patches. Request you to verify them and let me know if
there are any issues.

Regards,
-Krishna

--------------------------------------------------
From: "Jaehoon Chung" <jh80.chung@samsung.com>
Sent: Wednesday, September 11, 2013 6:09 AM
To: "Dani Krishna Mohan" <krishna.md@samsung.com>
Cc: <u-boot@lists.denx.de>; <rajeshwari.s@samsung.com>; "Minkyu Kang" 
<mk7.kang@samsung.com>
Subject: Re: [U-Boot] [PATCH V2 3/5] ARM: Added I2S0 clocks for audio

> Hi Dani,
>
> You refer to http://www.denx.de/wiki/U-Boot/CodingStyle
>
> And cc'd Minkyu.
>
> On 09/11/2013 12:02 AM, Dani Krishna Mohan wrote:
>> This patch makes the necessary changes for making use of
>> I2S0 channel instead of I2S1 channel on smdk board. This
>> changes are done to maintain the uniformity to use I2S0 channel.
>>
>> Signed-off-by: Dani Krishna Mohan <krishna.md@samsung.com>
>> ---
>>  arch/arm/cpu/armv7/exynos/clock.c         |   57 
>> ++++++++++++++++++++++-------
>>  arch/arm/cpu/armv7/exynos/pinmux.c        |   15 +++++++-
>>  arch/arm/include/asm/arch-exynos/clk.h    |    5 ++-
>>  arch/arm/include/asm/arch-exynos/clock.h  |    4 ++
>>  arch/arm/include/asm/arch-exynos/cpu.h    |    4 ++
>>  arch/arm/include/asm/arch-exynos/periph.h |    1 +
>>  drivers/sound/samsung-i2s.c               |   14 +++----
>>  7 files changed, 75 insertions(+), 25 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/exynos/clock.c 
>> b/arch/arm/cpu/armv7/exynos/clock.c
>> index 0cb1a61..80ed282 100644
>> --- a/arch/arm/cpu/armv7/exynos/clock.c
>> +++ b/arch/arm/cpu/armv7/exynos/clock.c
>> @@ -282,6 +282,9 @@ static unsigned long exynos5_get_periph_rate(int 
>> peripheral)
>>  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);
>> @@ -1146,17 +1149,29 @@ int exynos5_set_epll_clk(unsigned long rate)
>>  return 0;
>>  }
>>
>> -void exynos5_set_i2s_clk_source(void)
>> +void 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));
>> + }
> Can i2c_id get other value beside 0 or 1?
> And Could you change the coding style.
>>  }
>>
>>  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();
>> @@ -1169,13 +1184,26 @@ int exynos5_set_i2s_clk_prescaler(unsigned int 
>> src_frq,
>>  }
>>
>>  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);
>> - return -1;
>> + 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));
>>  }
>> - clrsetbits_le32(&clk->div_peric4, AUDIO_1_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));
>> + }
> Ditto.
>>  return 0;
>>  }
>>
>> @@ -1415,19 +1443,20 @@ int set_spi_clk(int periph_id, unsigned int rate)
>>  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)
>> +void set_i2s_clk_source(unsigned int i2s_id)
>>  {
>>  if (cpu_is_exynos5())
>> - exynos5_set_i2s_clk_source();
>> + exynos5_set_i2s_clk_source(i2s_id);
>>  }
>>
>>  int set_epll_clk(unsigned long rate)
>> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c 
>> b/arch/arm/cpu/armv7/exynos/pinmux.c
>> index 1b05ebf..6d1029e 100644
>> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
>> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
>> @@ -221,9 +221,19 @@ static void exynos5_i2s_config(int peripheral)
>>  int i;
>>  struct exynos5_gpio_part1 *gpio1 =
>>  (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)
>> @@ -296,6 +306,7 @@ static int exynos5_pinmux_config(int peripheral, int 
>> flags)
>>  case PERIPH_ID_I2C7:
>>  exynos5_i2c_config(peripheral, flags);
>>  break;
>> + case PERIPH_ID_I2S0:
>>  case PERIPH_ID_I2S1:
>>  exynos5_i2s_config(peripheral);
>>  break;
>> diff --git a/arch/arm/include/asm/arch-exynos/clk.h 
>> b/arch/arm/include/asm/arch-exynos/clk.h
>> index 71075bd..a240ec7 100644
>> --- a/arch/arm/include/asm/arch-exynos/clk.h
>> +++ b/arch/arm/include/asm/arch-exynos/clk.h
>> @@ -31,8 +31,9 @@ void set_mmc_clk(int dev_index, unsigned int div);
>>  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);
>> +void 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);
>>
>> diff --git a/arch/arm/include/asm/arch-exynos/clock.h 
>> b/arch/arm/include/asm/arch-exynos/clock.h
>> index 2b97b9a..cf26eef 100644
>> --- a/arch/arm/include/asm/arch-exynos/clock.h
>> +++ b/arch/arm/include/asm/arch-exynos/clock.h
>> @@ -876,8 +876,12 @@ struct set_epll_con_val {
>>  #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
>> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h 
>> b/arch/arm/include/asm/arch-exynos/cpu.h
>> index cb924fb..4b67191 100644
>> --- a/arch/arm/include/asm/arch-exynos/cpu.h
>> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
>> @@ -50,6 +50,7 @@
>>  #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
>> @@ -85,10 +86,12 @@
>>  #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
>> @@ -226,6 +229,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
>>  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 */
>> diff --git a/arch/arm/include/asm/arch-exynos/periph.h 
>> b/arch/arm/include/asm/arch-exynos/periph.h
>> index 9952155..64bd8b7 100644
>> --- a/arch/arm/include/asm/arch-exynos/periph.h
>> +++ b/arch/arm/include/asm/arch-exynos/periph.h
>> @@ -34,6 +34,7 @@ enum periph_id {
>>  PERIPH_ID_SDMMC1,
>>  PERIPH_ID_SDMMC2,
>>  PERIPH_ID_SDMMC3,
>> + PERIPH_ID_I2S0 = 98,
>>  PERIPH_ID_I2S1 = 99,
>>
>>  /* Since following peripherals do
>> diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c
>> index 49921e5..9caa4d2 100644
>> --- a/drivers/sound/samsung-i2s.c
>> +++ b/drivers/sound/samsung-i2s.c
>> @@ -67,7 +67,6 @@ static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
>>  con &= ~CON_TXCH_PAUSE;
>>
>>  } else {
>> -
>>  con |=  CON_TXCH_PAUSE;
>>  con &= ~CON_ACTIVE;
>>  }
>> @@ -172,7 +171,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int 
>> fmt)
>>  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;
>>  }
>>
>> @@ -191,7 +190,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int 
>> fmt)
>>  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;
>>  }
>>
>> @@ -209,7 +208,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int 
>> fmt)
>>  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;
>>  }
>>
>> @@ -250,7 +249,7 @@ int i2s_set_samplesize(struct i2s_reg *i2s_reg, 
>> unsigned int blc)
>>  break;
>>  default:
>>  debug("%s: Invalid sample size input [0x%x]\n",
>> - __func__, blc);
>> +       __func__, blc);
>>  return -1;
>>  }
>>  writel(mod, &i2s_reg->mod);
>> @@ -313,11 +312,12 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx)
>>  }
>>
>>  /* Select Clk Source for Audio1 */
>> - set_i2s_clk_source();
>> + set_i2s_clk_source(pi2s_tx->id);
>>
>>  /* Set Prescaler to get MCLK */
>>  set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
>> - (pi2s_tx->samplingrate * (pi2s_tx->rfs)));
>> +       (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
>> +       pi2s_tx->id);
>>
>>  /* Configure I2s format */
>>  ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
>>
>

Patch

diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 0cb1a61..80ed282 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -282,6 +282,9 @@  static unsigned long exynos5_get_periph_rate(int peripheral)
 		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);
@@ -1146,17 +1149,29 @@  int exynos5_set_epll_clk(unsigned long rate)
 	return 0;
 }
 
-void exynos5_set_i2s_clk_source(void)
+void 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));
+	}
 }
 
 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();
@@ -1169,13 +1184,26 @@  int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
 	}
 
 	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);
-		return -1;
+	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));
 	}
-	clrsetbits_le32(&clk->div_peric4, AUDIO_1_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));
+	}
 	return 0;
 }
 
@@ -1415,19 +1443,20 @@  int set_spi_clk(int periph_id, unsigned int rate)
 		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)
+void set_i2s_clk_source(unsigned int i2s_id)
 {
 	if (cpu_is_exynos5())
-		exynos5_set_i2s_clk_source();
+		exynos5_set_i2s_clk_source(i2s_id);
 }
 
 int set_epll_clk(unsigned long rate)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index 1b05ebf..6d1029e 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -221,9 +221,19 @@  static void exynos5_i2s_config(int peripheral)
 	int i;
 	struct exynos5_gpio_part1 *gpio1 =
 		(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)
@@ -296,6 +306,7 @@  static int exynos5_pinmux_config(int peripheral, int flags)
 	case PERIPH_ID_I2C7:
 		exynos5_i2c_config(peripheral, flags);
 		break;
+	case PERIPH_ID_I2S0:
 	case PERIPH_ID_I2S1:
 		exynos5_i2s_config(peripheral);
 		break;
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index 71075bd..a240ec7 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -31,8 +31,9 @@  void set_mmc_clk(int dev_index, unsigned int div);
 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);
+void 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);
 
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h
index 2b97b9a..cf26eef 100644
--- a/arch/arm/include/asm/arch-exynos/clock.h
+++ b/arch/arm/include/asm/arch-exynos/clock.h
@@ -876,8 +876,12 @@  struct set_epll_con_val {
 #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
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
index cb924fb..4b67191 100644
--- a/arch/arm/include/asm/arch-exynos/cpu.h
+++ b/arch/arm/include/asm/arch-exynos/cpu.h
@@ -50,6 +50,7 @@ 
 #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
@@ -85,10 +86,12 @@ 
 #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
@@ -226,6 +229,7 @@  SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
 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 */
diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h
index 9952155..64bd8b7 100644
--- a/arch/arm/include/asm/arch-exynos/periph.h
+++ b/arch/arm/include/asm/arch-exynos/periph.h
@@ -34,6 +34,7 @@  enum periph_id {
 	PERIPH_ID_SDMMC1,
 	PERIPH_ID_SDMMC2,
 	PERIPH_ID_SDMMC3,
+	PERIPH_ID_I2S0 = 98,
 	PERIPH_ID_I2S1 = 99,
 
 	/* Since following peripherals do
diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c
index 49921e5..9caa4d2 100644
--- a/drivers/sound/samsung-i2s.c
+++ b/drivers/sound/samsung-i2s.c
@@ -67,7 +67,6 @@  static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
 		con &= ~CON_TXCH_PAUSE;
 
 	} else {
-
 		con |=  CON_TXCH_PAUSE;
 		con &= ~CON_ACTIVE;
 	}
@@ -172,7 +171,7 @@  int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
 		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;
 	}
 
@@ -191,7 +190,7 @@  int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
 		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;
 	}
 
@@ -209,7 +208,7 @@  int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
 		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;
 	}
 
@@ -250,7 +249,7 @@  int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc)
 		break;
 	default:
 		debug("%s: Invalid sample size input [0x%x]\n",
-			__func__, blc);
+		      __func__, blc);
 		return -1;
 	}
 	writel(mod, &i2s_reg->mod);
@@ -313,11 +312,12 @@  int i2s_tx_init(struct i2stx_info *pi2s_tx)
 	}
 
 	/* Select Clk Source for Audio1 */
-	set_i2s_clk_source();
+	set_i2s_clk_source(pi2s_tx->id);
 
 	/* Set Prescaler to get MCLK */
 	set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
-				(pi2s_tx->samplingrate * (pi2s_tx->rfs)));
+			      (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+			      pi2s_tx->id);
 
 	/* Configure I2s format */
 	ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |