Commit 6e03a615 authored by Mark Brown's avatar Mark Brown

Merge branch 'ep93xx' into for-2.6.36

Trivial add/add fixup required in the clock table.

Conflicts:
	arch/arm/mach-ep93xx/clock.c
parents 9eb34302 ed67ea82
...@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk); ...@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);
static int set_keytchclk_rate(struct clk *clk, unsigned long rate); static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
static int set_div_rate(struct clk *clk, unsigned long rate); static int set_div_rate(struct clk *clk, unsigned long rate);
static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
static struct clk clk_xtali = { static struct clk clk_xtali = {
.rate = EP93XX_EXT_CLK_RATE, .rate = EP93XX_EXT_CLK_RATE,
...@@ -112,6 +113,29 @@ static struct clk clk_video = { ...@@ -112,6 +113,29 @@ static struct clk clk_video = {
.set_rate = set_div_rate, .set_rate = set_div_rate,
}; };
static struct clk clk_i2s_mclk = {
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
.set_rate = set_div_rate,
};
static struct clk clk_i2s_sclk = {
.sw_locked = 1,
.parent = &clk_i2s_mclk,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
.set_rate = set_i2s_sclk_rate,
};
static struct clk clk_i2s_lrclk = {
.sw_locked = 1,
.parent = &clk_i2s_sclk,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
.set_rate = set_i2s_lrclk_rate,
};
/* DMA Clocks */ /* DMA Clocks */
static struct clk clk_m2p0 = { static struct clk clk_m2p0 = {
.parent = &clk_h, .parent = &clk_h,
...@@ -191,6 +215,9 @@ static struct clk_lookup clocks[] = { ...@@ -191,6 +215,9 @@ static struct clk_lookup clocks[] = {
INIT_CK("ep93xx-keypad", NULL, &clk_keypad), INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK("ep93xx-fb", NULL, &clk_video),
INIT_CK("ep93xx-spi.0", NULL, &clk_spi), INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
INIT_CK(NULL, "pwm_clk", &clk_pwm), INIT_CK(NULL, "pwm_clk", &clk_pwm),
INIT_CK(NULL, "m2p0", &clk_m2p0), INIT_CK(NULL, "m2p0", &clk_m2p0),
INIT_CK(NULL, "m2p1", &clk_m2p1), INIT_CK(NULL, "m2p1", &clk_m2p1),
...@@ -401,6 +428,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate) ...@@ -401,6 +428,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate)
return 0; return 0;
} }
static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
{
unsigned val = __raw_readl(clk->enable_reg);
if (rate == clk_i2s_mclk.rate / 2)
ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV,
clk->enable_reg);
else if (rate == clk_i2s_mclk.rate / 4)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV,
clk->enable_reg);
else
return -EINVAL;
clk_i2s_sclk.rate = rate;
return 0;
}
static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
{
unsigned val = __raw_readl(clk->enable_reg) &
~EP93XX_I2SCLKDIV_LRDIV_MASK;
if (rate == clk_i2s_sclk.rate / 32)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
clk->enable_reg);
else if (rate == clk_i2s_sclk.rate / 64)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
clk->enable_reg);
else if (rate == clk_i2s_sclk.rate / 128)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
clk->enable_reg);
else
return -EINVAL;
clk_i2s_lrclk.rate = rate;
return 0;
}
int clk_set_rate(struct clk *clk, unsigned long rate) int clk_set_rate(struct clk *clk, unsigned long rate)
{ {
if (clk->set_rate) if (clk->set_rate)
......
...@@ -714,6 +714,73 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev) ...@@ -714,6 +714,73 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev)
} }
EXPORT_SYMBOL(ep93xx_keypad_release_gpio); EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
/*************************************************************************
* EP93xx I2S audio peripheral handling
*************************************************************************/
static struct resource ep93xx_i2s_resource[] = {
{
.start = EP93XX_I2S_PHYS_BASE,
.end = EP93XX_I2S_PHYS_BASE + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ep93xx_i2s_device = {
.name = "ep93xx-i2s",
.id = -1,
.num_resources = ARRAY_SIZE(ep93xx_i2s_resource),
.resource = ep93xx_i2s_resource,
};
void __init ep93xx_register_i2s(void)
{
platform_device_register(&ep93xx_i2s_device);
}
#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \
EP93XX_SYSCON_DEVCFG_I2SONAC97)
#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
EP93XX_SYSCON_I2SCLKDIV_SPOL)
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
{
unsigned val;
/* Sanity check */
if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK)
return -EINVAL;
if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
return -EINVAL;
/* Must have only one of I2SONSSP/I2SONAC97 set */
if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
(i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
return -EINVAL;
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
ep93xx_devcfg_set_bits(i2s_pins);
/*
* This is potentially racy with the clock api for i2s_mclk, sclk and
* lrclk. Since the i2s driver is the only user of those clocks we
* rely on it to prevent parallel use of this function and the
* clock api for the i2s clocks.
*/
val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
val &= ~EP93XX_I2SCLKDIV_MASK;
val |= i2s_config;
ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
return 0;
}
EXPORT_SYMBOL(ep93xx_i2s_acquire);
void ep93xx_i2s_release(void)
{
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
}
EXPORT_SYMBOL(ep93xx_i2s_release);
extern void ep93xx_gpio_init(void); extern void ep93xx_gpio_init(void);
......
...@@ -93,6 +93,7 @@ ...@@ -93,6 +93,7 @@
/* APB peripherals */ /* APB peripherals */
#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) #define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)
#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) #define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) #define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
...@@ -194,6 +195,15 @@ ...@@ -194,6 +195,15 @@
#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14) #define EP93XX_SYSCON_CLKDIV_ESEL (1<<14)
#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13) #define EP93XX_SYSCON_CLKDIV_PSEL (1<<13)
#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 #define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c)
#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31)
#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29)
#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19)
#define EP93XX_I2SCLKDIV_SDIV (1 << 16)
#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17)
#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17)
#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17)
#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17)
#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) #define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
......
...@@ -55,6 +55,9 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev); ...@@ -55,6 +55,9 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev);
void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data); void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
int ep93xx_keypad_acquire_gpio(struct platform_device *pdev); int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
void ep93xx_keypad_release_gpio(struct platform_device *pdev); void ep93xx_keypad_release_gpio(struct platform_device *pdev);
void ep93xx_register_i2s(void);
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config);
void ep93xx_i2s_release(void);
void ep93xx_init_devices(void); void ep93xx_init_devices(void);
extern struct sys_timer ep93xx_timer; extern struct sys_timer ep93xx_timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment