Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

audio patch #2

Merged
merged 6 commits into from
Aug 15, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions arch/arm/configs/odroidx_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2033,11 +2033,15 @@ CONFIG_SND_USB=y
CONFIG_SND_SOC=y
# CONFIG_SND_DESIGNWARE_I2S is not set
CONFIG_SND_SOC_SAMSUNG=y
CONFIG_SND_SAMSUNG_I2S=y
# CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994 is not set
# CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF is not set
# CONFIG_SND_SOC_SMDK_WM8994_PCM is not set
CONFIG_SND_SOC_HKDK_MAX98090=y
CONFIG_MAX98090_HEADSET=y
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_MAX98090=y
# CONFIG_SND_SIMPLE_CARD is not set
# CONFIG_SOUND_PRIME is not set

Expand Down
264 changes: 249 additions & 15 deletions arch/arm/mach-exynos/clock-exynos4.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-audss.h>
#include <mach/sysmmu.h>

#include "common.h"
Expand Down Expand Up @@ -198,6 +199,11 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
}

static int exynos4_clk_vpll_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(EXYNOS4_VPLL_CON0, clk, enable);
}

int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
Expand All @@ -213,6 +219,16 @@ static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
}

static int exynos4_clksrc_mask_maudio_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_MAUDIO, clk, enable);
}

int exynos4_clk_audss_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
}

/* Core list of CMU_CPU side */

static struct clksrc_clk exynos4_clk_mout_apll = {
Expand Down Expand Up @@ -451,6 +467,25 @@ static struct clksrc_sources exynos4_clkset_sclk_vpll = {
.nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
};

static struct clk *exynos4_clkset_mout_audss_list[] = {
&clk_ext_xtal_mux,
&clk_fout_epll,
};

static struct clksrc_sources clkset_mout_audss = {
.sources = exynos4_clkset_mout_audss_list,
.nr_sources = ARRAY_SIZE(exynos4_clkset_mout_audss_list),
};

static struct clksrc_clk exynos4_clk_mout_audss = {
.clk = {
.name = "mout_audss",
},
.sources = &clkset_mout_audss,
.reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
};


static struct clksrc_clk exynos4_clk_sclk_vpll = {
.clk = {
.name = "sclk_vpll",
Expand All @@ -459,6 +494,43 @@ static struct clksrc_clk exynos4_clk_sclk_vpll = {
.reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
};

static struct clksrc_clk exynos4_clk_dout_audss_srp = {
.clk = {
.name = "dout_srp",
.parent = &exynos4_clk_mout_audss.clk,
},
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
};

static struct clksrc_clk exynos4_clk_sclk_audss_bus = {
.clk = {
.name = "busclk",
.parent = &exynos4_clk_dout_audss_srp.clk,
.enable = exynos4_clk_audss_ctrl,
.ctrlbit = (1 << 2),
},
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
};

static struct clk exynos4_init_audss_clocks[] = {
{
.name = "srpclk",
.enable = exynos4_clk_audss_ctrl,
.parent = &exynos4_clk_dout_audss_srp.clk,
.ctrlbit = (1 << 0),
}, {
.name = "iis",
.devname = "samsung-i2s.0",
.enable = exynos4_clk_audss_ctrl,
.ctrlbit = (1 << 3) | (1 << 2),
}, {
.name = "pcm",
.devname = "samsung-pcm.0",
.enable = exynos4_clk_audss_ctrl,
.ctrlbit = (1 << 5),
},
};

static struct clk exynos4_init_clocks_off[] = {
{
.name = "timers",
Expand Down Expand Up @@ -599,11 +671,6 @@ static struct clk exynos4_init_clocks_off[] = {
.devname = "exynos4210-spi.2",
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit = (1 << 18),
}, {
.name = "iis",
.devname = "samsung-i2s.0",
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit = (1 << 19),
}, {
.name = "iis",
.devname = "samsung-i2s.1",
Expand Down Expand Up @@ -728,7 +795,65 @@ static struct clk exynos4_init_clocks_off[] = {
.devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
.enable = exynos4_clk_ip_lcd0_ctrl,
.ctrlbit = (1 << 4),
}
},
};

struct clksrc_clk exynos4_clk_audiocdclk0 = {
.clk = {
.name = "audiocdclk",
.rate = 16934400,
},
};

static struct clk *clkset_sclk_audio0_list[] = {
[0] = &exynos4_clk_audiocdclk0.clk,
[1] = NULL,
[2] = &exynos4_clk_sclk_hdmi27m,
[3] = &exynos4_clk_sclk_usbphy0,
[4] = &clk_ext_xtal_mux,
[5] = &clk_xusbxti,
[6] = &exynos4_clk_mout_mpll.clk,
[7] = &exynos4_clk_mout_epll.clk,
[8] = &exynos4_clk_sclk_vpll.clk,
};

static struct clksrc_sources exynos4_clkset_sclk_audio0 = {
.sources = clkset_sclk_audio0_list,
.nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
};

static struct clksrc_clk exynos4_clk_sclk_audio0 = {
.clk = {
.name = "audio-bus",
.enable = exynos4_clksrc_mask_maudio_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &exynos4_clkset_sclk_audio0,
.reg_src = { .reg = EXYNOS4_CLKSRC_MAUDIO, .shift = 0, .size = 4 },
.reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 0, .size = 4 },
};

static struct clk *exynos4_clkset_sclk_audss_list[] = {
&exynos4_clk_mout_audss.clk,
&exynos4_clk_audiocdclk0.clk,
&exynos4_clk_sclk_audio0.clk,
};

static struct clksrc_sources exynos4_clkset_sclk_audss = {
.sources = exynos4_clkset_sclk_audss_list,
.nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_audss_list),
};

static struct clksrc_clk exynos4_clk_sclk_audss_i2s = {
.clk = {
.name = "i2sclk",
.parent = &exynos4_clk_mout_audss.clk,
.enable = exynos4_clk_audss_ctrl,
.ctrlbit = (1 << 3),
},
.sources = &exynos4_clkset_sclk_audss,
.reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 8, .size = 4 },
};

static struct clk exynos4_init_clocks_on[] = {
Expand Down Expand Up @@ -1102,15 +1227,7 @@ static struct clksrc_clk exynos4_clksrcs[] = {
.sources = &exynos4_clkset_mout_mfc,
.reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
.reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_dwmmc",
.parent = &exynos4_clk_dout_mmc4.clk,
.enable = exynos4_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 16),
},
.reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
}
},
};

static struct clksrc_clk exynos4_clk_sclk_uart0 = {
Expand Down Expand Up @@ -1279,6 +1396,14 @@ static struct clksrc_clk exynos4_clk_sclk_spi2 = {
.reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
};

static struct clksrc_clk exynos4_clk_sclk_pcm0 = {
.clk = {
.name = "sclk_pcm",
.parent = &exynos4_clk_sclk_audio0.clk,
},
.reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 4, .size = 8 },
};

/* Clock initialization code */
static struct clksrc_clk *exynos4_sysclks[] = {
&exynos4_clk_mout_apll,
Expand Down Expand Up @@ -1311,6 +1436,13 @@ static struct clksrc_clk *exynos4_sysclks[] = {
&exynos4_clk_dout_mmc4,
&exynos4_clk_mout_mfc0,
&exynos4_clk_mout_mfc1,
&exynos4_clk_audiocdclk0,
&exynos4_clk_mout_audss,
&exynos4_clk_sclk_audss_bus,
&exynos4_clk_sclk_audss_i2s,
&exynos4_clk_dout_audss_srp,
&exynos4_clk_sclk_audio0,
&exynos4_clk_sclk_pcm0,
};

static struct clk *exynos4_clk_cdev[] = {
Expand Down Expand Up @@ -1438,6 +1570,92 @@ static struct clk_ops exynos4_vpll_ops = {
.set_rate = exynos4_vpll_set_rate,
};

static unsigned long exynos4_epll_get_rate(struct clk *clk)
{
return clk->rate;
}

static u32 epll_div[][6] = {
{ 192000000, 0, 48, 3, 1, 0 },
{ 180000000, 0, 45, 3, 1, 0 },
{ 73728000, 1, 73, 3, 3, 47710 },
{ 67737600, 1, 90, 4, 3, 20762 },
{ 49152000, 0, 49, 3, 3, 9961 },
{ 45158400, 0, 45, 3, 3, 10381 },
{ 180633600, 0, 45, 3, 1, 10381 },
};

static int exynos4_epll_set_rate(struct clk *clk, unsigned long rate)
{
unsigned int epll_con, epll_con_k;
unsigned int i;
unsigned int tmp;
unsigned int epll_rate;
unsigned int locktime;
unsigned int lockcnt;

/* Return if nothing changed */
if (clk->rate == rate)
return 0;

if (clk->parent)
epll_rate = clk_get_rate(clk->parent);
else
epll_rate = clk_ext_xtal_mux.rate;

if (epll_rate != 24000000) {
pr_err("Invalid Clock : recommended clock is 24MHz.\n");
return -EINVAL;
}


epll_con = __raw_readl(EXYNOS4_EPLL_CON0);
epll_con &= ~(0x1 << 27 | \
PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);

for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
if (epll_div[i][0] == rate) {
epll_con_k = epll_div[i][5] << 0;
epll_con |= epll_div[i][1] << 27;
epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
break;
}
}

if (i == ARRAY_SIZE(epll_div)) {
pr_err("%s: Invalid Clock EPLL Frequency\n", __func__);
return -EINVAL;
}

epll_rate /= 1000000;

/* 3000 max_cycls : specification data */
locktime = 3000 / epll_rate * epll_div[i][3];
lockcnt = locktime * 10000 / (10000 / epll_rate);

__raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);

__raw_writel(epll_con, EXYNOS4_EPLL_CON0);
__raw_writel(epll_con_k, EXYNOS4_EPLL_CON1);

do {
tmp = __raw_readl(EXYNOS4_EPLL_CON0);
} while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));

clk->rate = rate;

return 0;
}

static struct clk_ops exynos4_epll_ops = {
.get_rate = exynos4_epll_get_rate,
.set_rate = exynos4_epll_set_rate,
};

void __init_or_cpufreq exynos4_setup_clocks(void)
{
struct clk *xtal_clk;
Expand Down Expand Up @@ -1494,6 +1712,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)

clk_fout_apll.ops = &exynos4_fout_apll_ops;
clk_fout_mpll.rate = mpll;
clk_fout_epll.ops = &exynos4_epll_ops;
clk_fout_epll.rate = epll;
clk_fout_vpll.ops = &exynos4_vpll_ops;
clk_fout_vpll.rate = vpll;
Expand All @@ -1518,6 +1737,16 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
clk_h.rate = sclk_dmc;
clk_p.rate = aclk_100;

clk_set_parent(&exynos4_clk_mout_audss.clk, &clk_fout_epll);
clk_set_parent(&exynos4_clk_sclk_audio0.clk,
&exynos4_clk_mout_epll.clk);
clk_set_parent(&exynos4_clk_mout_epll.clk, &clk_fout_epll);

clk_fout_vpll.enable = exynos4_clk_vpll_ctrl;
clk_fout_vpll.ops = &exynos4_vpll_ops;

clk_set_rate(&exynos4_clk_sclk_apll.clk, 100000000);

for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
}
Expand Down Expand Up @@ -1577,6 +1806,11 @@ void __init exynos4_register_clocks(void)
s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));

s3c_register_clocks(exynos4_init_audss_clocks,
ARRAY_SIZE(exynos4_init_audss_clocks));
s3c_disable_clocks(exynos4_init_audss_clocks,
ARRAY_SIZE(exynos4_init_audss_clocks));

register_syscore_ops(&exynos4_clock_syscore_ops);
s3c24xx_register_clock(&dummy_apb_pclk);

Expand Down
5 changes: 5 additions & 0 deletions arch/arm/mach-exynos/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ static struct map_desc exynos4_iodesc[] __initdata = {
.pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_AUDSS,
.pfn = __phys_to_pfn(EXYNOS4_PA_AUDSS),
.length = SZ_4K,
.type = MT_DEVICE,
},
};

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-exynos/include/mach/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

#define EXYNOS4_PA_JPEG 0x11840000

#define EXYNOS4_PA_AUDSS 0x03810000

/* x = 0...1 */
#define EXYNOS4_PA_FIMC_LITE(x) (0x12390000 + ((x) * 0x10000))

Expand Down
Loading