[PATCH 2/3] ARM: S5P64X0: Add PCM audio support for WM8580
Sangbeom Kim
sbkim73 at samsung.com
Wed Apr 6 20:31:09 EDT 2011
This patch add pcm audio configuration for SMDK6450 and SMDK6440.
Platform device and pcm clock initialization code is added.
Signed-off-by: Sangbeom Kim <sbkim73 at samsung.com>
---
arch/arm/mach-s5p64x0/clock-s5p6440.c | 63 +++++++++++---------
arch/arm/mach-s5p64x0/clock-s5p6450.c | 27 +++++++--
arch/arm/mach-s5p64x0/clock.c | 11 ++++
arch/arm/mach-s5p64x0/dev-audio.c | 56 ++++++++++++++++-
arch/arm/mach-s5p64x0/include/mach/regs-clock.h | 3 +
arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h | 4 +
arch/arm/mach-s5p64x0/mach-smdk6440.c | 1 +
arch/arm/mach-s5p64x0/mach-smdk6450.c | 1 +
8 files changed, 129 insertions(+), 37 deletions(-)
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 9f12c2e..3e03040 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -372,14 +372,12 @@ static struct clk init_clocks[] = {
},
};
-static struct clk clk_iis_cd_v40 = {
- .name = "iis_cdclk_v40",
- .id = -1,
-};
-
-static struct clk clk_pcm_cd = {
- .name = "pcm_cdclk",
- .id = -1,
+static struct clksrc_clk clk_dout_epll = {
+ .clk = {
+ .name = "dout_epll",
+ .id = -1,
+ .parent = &clk_mout_epll.clk,
+ },
};
static struct clk *clkset_group1_list[] = {
@@ -403,17 +401,30 @@ static struct clksrc_sources clkset_uart = {
.nr_sources = ARRAY_SIZE(clkset_uart_list),
};
-static struct clk *clkset_audio_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll.clk,
- &clk_fin_epll,
- &clk_iis_cd_v40,
- &clk_pcm_cd,
+static struct clk *clkset_sclk_audio_list[] = {
+ [0] = &clk_dout_epll.clk,
+ [1] = &clk_dout_mpll.clk,
+ [2] = &clk_ext,
+ [3] = &clk_i2s_v40_cdclk,
+ [4] = &clk_pcmcdclk0,
};
-static struct clksrc_sources clkset_audio = {
- .sources = clkset_audio_list,
- .nr_sources = ARRAY_SIZE(clkset_audio_list),
+static struct clksrc_sources clkset_sclk_audio = {
+ .sources = clkset_sclk_audio_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio_list),
+};
+
+struct clksrc_clk clk_sclk_audio = {
+ .clk = {
+ .name = "audio-bus",
+ .id = -1,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 11),
+ .parent = &clk_ext_xtal_mux,
+ },
+ .sources = &clkset_sclk_audio,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 },
};
static struct clksrc_clk clksrcs[] = {
@@ -507,16 +518,6 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group1,
.reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
.reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_audio2",
- .id = -1,
- .ctrlbit = (1 << 11),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_audio,
- .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 },
},
};
@@ -526,11 +527,13 @@ static struct clksrc_clk *sysclks[] = {
&clk_mout_epll,
&clk_mout_mpll,
&clk_dout_mpll,
+ &clk_dout_epll,
&clk_armclk,
&clk_hclk,
&clk_pclk,
&clk_hclk_low,
&clk_pclk_low,
+ &clk_sclk_audio,
};
void __init_or_cpufreq s5p6440_setup_clocks(void)
@@ -590,14 +593,16 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
clk_h.rate = hclk;
clk_p.rate = pclk;
+ clk_set_parent(&clk_sclk_audio.clk, &clk_pcmcdclk0);
+
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_set_clksrc(&clksrcs[ptr], true);
}
static struct clk *clks[] __initdata = {
&clk_ext,
- &clk_iis_cd_v40,
- &clk_pcm_cd,
+ &clk_i2s_v40_cdclk,
+ &clk_pcmcdclk0,
};
void __init s5p6440_register_clocks(void)
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 4eec457..27c7d4a 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -290,7 +290,14 @@ static struct clk init_clocks_off[] = {
.parent = &clk_pclk.clk,
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 30),
- }
+ }, {
+ .name = "pcm",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_PCM0,
+ },
+
};
/*
@@ -408,9 +415,9 @@ static struct clksrc_sources clkset_hsmmc44 = {
static struct clk *clkset_sclk_audio0_list[] = {
[0] = &clk_dout_epll.clk,
[1] = &clk_dout_mpll.clk,
- [2] = &clk_ext_xtal_mux,
- [3] = NULL,
- [4] = NULL,
+ [2] = &clk_ext,
+ [3] = &clk_i2s_v40_cdclk,
+ [4] = &clk_pcmcdclk0,
};
static struct clksrc_sources clkset_sclk_audio0 = {
@@ -418,7 +425,7 @@ static struct clksrc_sources clkset_sclk_audio0 = {
.nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
};
-static struct clksrc_clk clk_sclk_audio0 = {
+struct clksrc_clk clk_sclk_audio0 = {
.clk = {
.name = "audio-bus",
.id = -1,
@@ -647,12 +654,22 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_set_clksrc(&clksrcs[ptr], true);
+
+ clk_set_parent(&clk_sclk_audio0.clk, &clk_pcmcdclk0);
}
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_i2s_v40_cdclk,
+ &clk_pcmcdclk0,
+};
+
void __init s5p6450_register_clocks(void)
{
int ptr;
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
s3c_register_clksrc(sysclks[ptr], 1);
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index b52c6e2..432bb06 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -233,3 +233,14 @@ int s5p64x0_clk48m_ctrl(struct clk *clk, int enable)
return 0;
}
+
+struct clk clk_pcmcdclk0 = {
+ .name = "pcmcdclk",
+ .id = 0,
+ .rate = 4096000,
+};
+
+struct clk clk_i2s_v40_cdclk = {
+ .name = "i2s_v40_cdclk",
+ .id = 0,
+};
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
index 35f1f22..a777363 100644
--- a/arch/arm/mach-s5p64x0/dev-audio.c
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -207,7 +207,7 @@ static struct s3c_audio_pdata s5p6440_pcm_pdata = {
.cfg_gpio = s5p6440_pcm_cfg_gpio,
};
-static struct resource s5p6440_pcm0_resource[] = {
+static struct resource s5p6440_pcm_resource[] = {
[0] = {
.start = S5P64X0_PA_PCM,
.end = S5P64X0_PA_PCM + 0x100 - 1,
@@ -228,9 +228,59 @@ static struct resource s5p6440_pcm0_resource[] = {
struct platform_device s5p6440_device_pcm = {
.name = "samsung-pcm",
.id = 0,
- .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource),
- .resource = s5p6440_pcm0_resource,
+ .num_resources = ARRAY_SIZE(s5p6440_pcm_resource),
+ .resource = s5p6440_pcm_resource,
.dev = {
.platform_data = &s5p6440_pcm_pdata,
},
};
+
+static int s5p6450_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(2));
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+ .cfg_gpio = s5p6450_pcm_cfg_gpio,
+};
+
+static struct resource s5p6450_pcm0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_PCM,
+ .end = S5P64X0_PA_PCM + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM0_TX,
+ .end = DMACH_PCM0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM0_RX,
+ .end = DMACH_PCM0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6450_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p6450_pcm0_resource),
+ .resource = s5p6450_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index a133f22..9b72a1c 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -62,4 +62,7 @@
#define S5P_EPLL_CON S5P64X0_EPLL_CON
+#define S5P_CLKCON_SCLK0_AUDIO0 (1<<8)
+#define S5P_CLKCON_PCLK_PCM0 (1<<8)
+
#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
index ff85b4b..88a8065 100644
--- a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
@@ -34,6 +34,10 @@ extern struct clksrc_clk clk_dout_mpll;
extern struct clk *clkset_hclk_low_list[];
extern struct clksrc_sources clkset_hclk_low;
+extern struct clksrc_clk clk_sclk_audio0;
+extern struct clk clk_pcmcdclk0;
+extern struct clk clk_i2s_v40_cdclk;
+
extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable);
extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable);
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 2d559f1..2620cb4 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -139,6 +139,7 @@ static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6440_device_iis,
+ &s5p6440_device_pcm,
&s3c_device_timer[1],
&smdk6440_backlight_device,
};
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d19c469..b573186 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -157,6 +157,7 @@ static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6450_device_iis0,
+ &s5p6450_device_pcm0,
&s3c_device_timer[1],
&smdk6450_backlight_device,
/* s5p6450_device_spi0 will be added */
--
1.7.1
More information about the linux-arm-kernel
mailing list