Skip to content

Commit 1bde2d6

Browse files
committed
Merge pull request #2 from tobetter/odroidx-next
audio patch
2 parents 5d0fd34 + 1b15681 commit 1bde2d6

File tree

15 files changed

+2371
-15
lines changed

15 files changed

+2371
-15
lines changed

arch/arm/configs/odroidx_defconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,11 +2033,15 @@ CONFIG_SND_USB=y
20332033
CONFIG_SND_SOC=y
20342034
# CONFIG_SND_DESIGNWARE_I2S is not set
20352035
CONFIG_SND_SOC_SAMSUNG=y
2036+
CONFIG_SND_SAMSUNG_I2S=y
20362037
# CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994 is not set
20372038
# CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF is not set
20382039
# CONFIG_SND_SOC_SMDK_WM8994_PCM is not set
2040+
CONFIG_SND_SOC_HKDK_MAX98090=y
2041+
CONFIG_MAX98090_HEADSET=y
20392042
CONFIG_SND_SOC_I2C_AND_SPI=y
20402043
# CONFIG_SND_SOC_ALL_CODECS is not set
2044+
CONFIG_SND_SOC_MAX98090=y
20412045
# CONFIG_SND_SIMPLE_CARD is not set
20422046
# CONFIG_SOUND_PRIME is not set
20432047

arch/arm/mach-exynos/clock-exynos4.c

Lines changed: 249 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <mach/map.h>
2626
#include <mach/regs-clock.h>
27+
#include <mach/regs-audss.h>
2728
#include <mach/sysmmu.h>
2829

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

202+
static int exynos4_clk_vpll_ctrl(struct clk *clk, int enable)
203+
{
204+
return s5p_gatectrl(EXYNOS4_VPLL_CON0, clk, enable);
205+
}
206+
201207
int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
202208
{
203209
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
@@ -213,6 +219,16 @@ static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
213219
return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
214220
}
215221

222+
static int exynos4_clksrc_mask_maudio_ctrl(struct clk *clk, int enable)
223+
{
224+
return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_MAUDIO, clk, enable);
225+
}
226+
227+
int exynos4_clk_audss_ctrl(struct clk *clk, int enable)
228+
{
229+
return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
230+
}
231+
216232
/* Core list of CMU_CPU side */
217233

218234
static struct clksrc_clk exynos4_clk_mout_apll = {
@@ -451,6 +467,25 @@ static struct clksrc_sources exynos4_clkset_sclk_vpll = {
451467
.nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
452468
};
453469

470+
static struct clk *exynos4_clkset_mout_audss_list[] = {
471+
&clk_ext_xtal_mux,
472+
&clk_fout_epll,
473+
};
474+
475+
static struct clksrc_sources clkset_mout_audss = {
476+
.sources = exynos4_clkset_mout_audss_list,
477+
.nr_sources = ARRAY_SIZE(exynos4_clkset_mout_audss_list),
478+
};
479+
480+
static struct clksrc_clk exynos4_clk_mout_audss = {
481+
.clk = {
482+
.name = "mout_audss",
483+
},
484+
.sources = &clkset_mout_audss,
485+
.reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
486+
};
487+
488+
454489
static struct clksrc_clk exynos4_clk_sclk_vpll = {
455490
.clk = {
456491
.name = "sclk_vpll",
@@ -459,6 +494,43 @@ static struct clksrc_clk exynos4_clk_sclk_vpll = {
459494
.reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
460495
};
461496

497+
static struct clksrc_clk exynos4_clk_dout_audss_srp = {
498+
.clk = {
499+
.name = "dout_srp",
500+
.parent = &exynos4_clk_mout_audss.clk,
501+
},
502+
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
503+
};
504+
505+
static struct clksrc_clk exynos4_clk_sclk_audss_bus = {
506+
.clk = {
507+
.name = "busclk",
508+
.parent = &exynos4_clk_dout_audss_srp.clk,
509+
.enable = exynos4_clk_audss_ctrl,
510+
.ctrlbit = (1 << 2),
511+
},
512+
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
513+
};
514+
515+
static struct clk exynos4_init_audss_clocks[] = {
516+
{
517+
.name = "srpclk",
518+
.enable = exynos4_clk_audss_ctrl,
519+
.parent = &exynos4_clk_dout_audss_srp.clk,
520+
.ctrlbit = (1 << 0),
521+
}, {
522+
.name = "iis",
523+
.devname = "samsung-i2s.0",
524+
.enable = exynos4_clk_audss_ctrl,
525+
.ctrlbit = (1 << 3) | (1 << 2),
526+
}, {
527+
.name = "pcm",
528+
.devname = "samsung-pcm.0",
529+
.enable = exynos4_clk_audss_ctrl,
530+
.ctrlbit = (1 << 5),
531+
},
532+
};
533+
462534
static struct clk exynos4_init_clocks_off[] = {
463535
{
464536
.name = "timers",
@@ -599,11 +671,6 @@ static struct clk exynos4_init_clocks_off[] = {
599671
.devname = "exynos4210-spi.2",
600672
.enable = exynos4_clk_ip_peril_ctrl,
601673
.ctrlbit = (1 << 18),
602-
}, {
603-
.name = "iis",
604-
.devname = "samsung-i2s.0",
605-
.enable = exynos4_clk_ip_peril_ctrl,
606-
.ctrlbit = (1 << 19),
607674
}, {
608675
.name = "iis",
609676
.devname = "samsung-i2s.1",
@@ -728,7 +795,65 @@ static struct clk exynos4_init_clocks_off[] = {
728795
.devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
729796
.enable = exynos4_clk_ip_lcd0_ctrl,
730797
.ctrlbit = (1 << 4),
731-
}
798+
},
799+
};
800+
801+
struct clksrc_clk exynos4_clk_audiocdclk0 = {
802+
.clk = {
803+
.name = "audiocdclk",
804+
.rate = 16934400,
805+
},
806+
};
807+
808+
static struct clk *clkset_sclk_audio0_list[] = {
809+
[0] = &exynos4_clk_audiocdclk0.clk,
810+
[1] = NULL,
811+
[2] = &exynos4_clk_sclk_hdmi27m,
812+
[3] = &exynos4_clk_sclk_usbphy0,
813+
[4] = &clk_ext_xtal_mux,
814+
[5] = &clk_xusbxti,
815+
[6] = &exynos4_clk_mout_mpll.clk,
816+
[7] = &exynos4_clk_mout_epll.clk,
817+
[8] = &exynos4_clk_sclk_vpll.clk,
818+
};
819+
820+
static struct clksrc_sources exynos4_clkset_sclk_audio0 = {
821+
.sources = clkset_sclk_audio0_list,
822+
.nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
823+
};
824+
825+
static struct clksrc_clk exynos4_clk_sclk_audio0 = {
826+
.clk = {
827+
.name = "audio-bus",
828+
.enable = exynos4_clksrc_mask_maudio_ctrl,
829+
.ctrlbit = (1 << 0),
830+
},
831+
.sources = &exynos4_clkset_sclk_audio0,
832+
.reg_src = { .reg = EXYNOS4_CLKSRC_MAUDIO, .shift = 0, .size = 4 },
833+
.reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 0, .size = 4 },
834+
};
835+
836+
static struct clk *exynos4_clkset_sclk_audss_list[] = {
837+
&exynos4_clk_mout_audss.clk,
838+
&exynos4_clk_audiocdclk0.clk,
839+
&exynos4_clk_sclk_audio0.clk,
840+
};
841+
842+
static struct clksrc_sources exynos4_clkset_sclk_audss = {
843+
.sources = exynos4_clkset_sclk_audss_list,
844+
.nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_audss_list),
845+
};
846+
847+
static struct clksrc_clk exynos4_clk_sclk_audss_i2s = {
848+
.clk = {
849+
.name = "i2sclk",
850+
.parent = &exynos4_clk_mout_audss.clk,
851+
.enable = exynos4_clk_audss_ctrl,
852+
.ctrlbit = (1 << 3),
853+
},
854+
.sources = &exynos4_clkset_sclk_audss,
855+
.reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
856+
.reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 8, .size = 4 },
732857
};
733858

734859
static struct clk exynos4_init_clocks_on[] = {
@@ -1102,15 +1227,7 @@ static struct clksrc_clk exynos4_clksrcs[] = {
11021227
.sources = &exynos4_clkset_mout_mfc,
11031228
.reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
11041229
.reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
1105-
}, {
1106-
.clk = {
1107-
.name = "sclk_dwmmc",
1108-
.parent = &exynos4_clk_dout_mmc4.clk,
1109-
.enable = exynos4_clksrc_mask_fsys_ctrl,
1110-
.ctrlbit = (1 << 16),
1111-
},
1112-
.reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
1113-
}
1230+
},
11141231
};
11151232

11161233
static struct clksrc_clk exynos4_clk_sclk_uart0 = {
@@ -1279,6 +1396,14 @@ static struct clksrc_clk exynos4_clk_sclk_spi2 = {
12791396
.reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
12801397
};
12811398

1399+
static struct clksrc_clk exynos4_clk_sclk_pcm0 = {
1400+
.clk = {
1401+
.name = "sclk_pcm",
1402+
.parent = &exynos4_clk_sclk_audio0.clk,
1403+
},
1404+
.reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 4, .size = 8 },
1405+
};
1406+
12821407
/* Clock initialization code */
12831408
static struct clksrc_clk *exynos4_sysclks[] = {
12841409
&exynos4_clk_mout_apll,
@@ -1311,6 +1436,13 @@ static struct clksrc_clk *exynos4_sysclks[] = {
13111436
&exynos4_clk_dout_mmc4,
13121437
&exynos4_clk_mout_mfc0,
13131438
&exynos4_clk_mout_mfc1,
1439+
&exynos4_clk_audiocdclk0,
1440+
&exynos4_clk_mout_audss,
1441+
&exynos4_clk_sclk_audss_bus,
1442+
&exynos4_clk_sclk_audss_i2s,
1443+
&exynos4_clk_dout_audss_srp,
1444+
&exynos4_clk_sclk_audio0,
1445+
&exynos4_clk_sclk_pcm0,
13141446
};
13151447

13161448
static struct clk *exynos4_clk_cdev[] = {
@@ -1438,6 +1570,92 @@ static struct clk_ops exynos4_vpll_ops = {
14381570
.set_rate = exynos4_vpll_set_rate,
14391571
};
14401572

1573+
static unsigned long exynos4_epll_get_rate(struct clk *clk)
1574+
{
1575+
return clk->rate;
1576+
}
1577+
1578+
static u32 epll_div[][6] = {
1579+
{ 192000000, 0, 48, 3, 1, 0 },
1580+
{ 180000000, 0, 45, 3, 1, 0 },
1581+
{ 73728000, 1, 73, 3, 3, 47710 },
1582+
{ 67737600, 1, 90, 4, 3, 20762 },
1583+
{ 49152000, 0, 49, 3, 3, 9961 },
1584+
{ 45158400, 0, 45, 3, 3, 10381 },
1585+
{ 180633600, 0, 45, 3, 1, 10381 },
1586+
};
1587+
1588+
static int exynos4_epll_set_rate(struct clk *clk, unsigned long rate)
1589+
{
1590+
unsigned int epll_con, epll_con_k;
1591+
unsigned int i;
1592+
unsigned int tmp;
1593+
unsigned int epll_rate;
1594+
unsigned int locktime;
1595+
unsigned int lockcnt;
1596+
1597+
/* Return if nothing changed */
1598+
if (clk->rate == rate)
1599+
return 0;
1600+
1601+
if (clk->parent)
1602+
epll_rate = clk_get_rate(clk->parent);
1603+
else
1604+
epll_rate = clk_ext_xtal_mux.rate;
1605+
1606+
if (epll_rate != 24000000) {
1607+
pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1608+
return -EINVAL;
1609+
}
1610+
1611+
1612+
epll_con = __raw_readl(EXYNOS4_EPLL_CON0);
1613+
epll_con &= ~(0x1 << 27 | \
1614+
PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1615+
PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1616+
PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1617+
1618+
for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1619+
if (epll_div[i][0] == rate) {
1620+
epll_con_k = epll_div[i][5] << 0;
1621+
epll_con |= epll_div[i][1] << 27;
1622+
epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
1623+
epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
1624+
epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
1625+
break;
1626+
}
1627+
}
1628+
1629+
if (i == ARRAY_SIZE(epll_div)) {
1630+
pr_err("%s: Invalid Clock EPLL Frequency\n", __func__);
1631+
return -EINVAL;
1632+
}
1633+
1634+
epll_rate /= 1000000;
1635+
1636+
/* 3000 max_cycls : specification data */
1637+
locktime = 3000 / epll_rate * epll_div[i][3];
1638+
lockcnt = locktime * 10000 / (10000 / epll_rate);
1639+
1640+
__raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);
1641+
1642+
__raw_writel(epll_con, EXYNOS4_EPLL_CON0);
1643+
__raw_writel(epll_con_k, EXYNOS4_EPLL_CON1);
1644+
1645+
do {
1646+
tmp = __raw_readl(EXYNOS4_EPLL_CON0);
1647+
} while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));
1648+
1649+
clk->rate = rate;
1650+
1651+
return 0;
1652+
}
1653+
1654+
static struct clk_ops exynos4_epll_ops = {
1655+
.get_rate = exynos4_epll_get_rate,
1656+
.set_rate = exynos4_epll_set_rate,
1657+
};
1658+
14411659
void __init_or_cpufreq exynos4_setup_clocks(void)
14421660
{
14431661
struct clk *xtal_clk;
@@ -1494,6 +1712,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
14941712

14951713
clk_fout_apll.ops = &exynos4_fout_apll_ops;
14961714
clk_fout_mpll.rate = mpll;
1715+
clk_fout_epll.ops = &exynos4_epll_ops;
14971716
clk_fout_epll.rate = epll;
14981717
clk_fout_vpll.ops = &exynos4_vpll_ops;
14991718
clk_fout_vpll.rate = vpll;
@@ -1518,6 +1737,16 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
15181737
clk_h.rate = sclk_dmc;
15191738
clk_p.rate = aclk_100;
15201739

1740+
clk_set_parent(&exynos4_clk_mout_audss.clk, &clk_fout_epll);
1741+
clk_set_parent(&exynos4_clk_sclk_audio0.clk,
1742+
&exynos4_clk_mout_epll.clk);
1743+
clk_set_parent(&exynos4_clk_mout_epll.clk, &clk_fout_epll);
1744+
1745+
clk_fout_vpll.enable = exynos4_clk_vpll_ctrl;
1746+
clk_fout_vpll.ops = &exynos4_vpll_ops;
1747+
1748+
clk_set_rate(&exynos4_clk_sclk_apll.clk, 100000000);
1749+
15211750
for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
15221751
s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
15231752
}
@@ -1577,6 +1806,11 @@ void __init exynos4_register_clocks(void)
15771806
s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
15781807
clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
15791808

1809+
s3c_register_clocks(exynos4_init_audss_clocks,
1810+
ARRAY_SIZE(exynos4_init_audss_clocks));
1811+
s3c_disable_clocks(exynos4_init_audss_clocks,
1812+
ARRAY_SIZE(exynos4_init_audss_clocks));
1813+
15801814
register_syscore_ops(&exynos4_clock_syscore_ops);
15811815
s3c24xx_register_clock(&dummy_apb_pclk);
15821816

arch/arm/mach-exynos/common.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ static struct map_desc exynos4_iodesc[] __initdata = {
198198
.pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
199199
.length = SZ_4K,
200200
.type = MT_DEVICE,
201+
}, {
202+
.virtual = (unsigned long)S5P_VA_AUDSS,
203+
.pfn = __phys_to_pfn(EXYNOS4_PA_AUDSS),
204+
.length = SZ_4K,
205+
.type = MT_DEVICE,
201206
},
202207
};
203208

arch/arm/mach-exynos/include/mach/map.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
#define EXYNOS4_PA_JPEG 0x11840000
3636

37+
#define EXYNOS4_PA_AUDSS 0x03810000
38+
3739
/* x = 0...1 */
3840
#define EXYNOS4_PA_FIMC_LITE(x) (0x12390000 + ((x) * 0x10000))
3941

0 commit comments

Comments
 (0)