aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-mackerel.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-01-05 21:44:15 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-05 22:17:18 -0500
commit98d27b8abf413a310df6676f7d2128ada1cccc08 (patch)
tree5fc2a5cc95b1e3188f341194c2d79045b3cb690c /arch/arm/mach-shmobile/board-mackerel.c
parent12c4309b78854ba117ea38a9178018591abd16ab (diff)
ARM: mach-shmobile: mackerel: Add HDMI sound support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/arm/mach-shmobile/board-mackerel.c')
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index c7d378b57cf..6a5ce9a0dcf 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -373,6 +373,7 @@ static struct platform_device hdmi_lcdc_device = {
373static struct sh_mobile_hdmi_info hdmi_info = { 373static struct sh_mobile_hdmi_info hdmi_info = {
374 .lcd_chan = &hdmi_lcdc_info.ch[0], 374 .lcd_chan = &hdmi_lcdc_info.ch[0],
375 .lcd_dev = &hdmi_lcdc_device.dev, 375 .lcd_dev = &hdmi_lcdc_device.dev,
376 .flags = HDMI_SND_SRC_SPDIF,
376}; 377};
377 378
378static struct resource hdmi_resources[] = { 379static struct resource hdmi_resources[] = {
@@ -534,12 +535,93 @@ static struct platform_device leds_device = {
534 535
535/* FSI */ 536/* FSI */
536#define IRQ_FSI evt2irq(0x1840) 537#define IRQ_FSI evt2irq(0x1840)
538static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
539{
540 int ret;
541
542 if (rate <= 0)
543 return 0;
544
545 if (!enable) {
546 clk_disable(clk);
547 return 0;
548 }
549
550 ret = clk_set_rate(clk, clk_round_rate(clk, rate));
551 if (ret < 0)
552 return ret;
553
554 return clk_enable(clk);
555}
556
557static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
558{
559 struct clk *fsib_clk;
560 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
561 long fsib_rate = 0;
562 long fdiv_rate = 0;
563 int ackmd_bpfmd;
564 int ret;
565
566 /* FSIA is slave mode. nothing to do here */
567 if (is_porta)
568 return 0;
569
570 /* clock start */
571 switch (rate) {
572 case 44100:
573 fsib_rate = rate * 256;
574 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
575 break;
576 case 48000:
577 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
578 fdiv_rate = rate * 256;
579 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
580 break;
581 default:
582 pr_err("unsupported rate in FSI2 port B\n");
583 return -EINVAL;
584 }
585
586 /* FSI B setting */
587 fsib_clk = clk_get(dev, "ickb");
588 if (IS_ERR(fsib_clk))
589 return -EIO;
590
591 /* fsib */
592 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
593 if (ret < 0)
594 goto fsi_set_rate_end;
595
596 /* FSI DIV */
597 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
598 if (ret < 0) {
599 /* disable FSI B */
600 if (enable)
601 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
602 goto fsi_set_rate_end;
603 }
604
605 ret = ackmd_bpfmd;
606
607fsi_set_rate_end:
608 clk_put(fsib_clk);
609 return ret;
610}
611
537static struct sh_fsi_platform_info fsi_info = { 612static struct sh_fsi_platform_info fsi_info = {
538 .porta_flags = SH_FSI_BRS_INV | 613 .porta_flags = SH_FSI_BRS_INV |
539 SH_FSI_OUT_SLAVE_MODE | 614 SH_FSI_OUT_SLAVE_MODE |
540 SH_FSI_IN_SLAVE_MODE | 615 SH_FSI_IN_SLAVE_MODE |
541 SH_FSI_OFMT(PCM) | 616 SH_FSI_OFMT(PCM) |
542 SH_FSI_IFMT(PCM), 617 SH_FSI_IFMT(PCM),
618
619 .portb_flags = SH_FSI_BRS_INV |
620 SH_FSI_BRM_INV |
621 SH_FSI_LRS_INV |
622 SH_FSI_OFMT(SPDIF),
623
624 .set_rate = fsi_set_rate,
543}; 625};
544 626
545static struct resource fsi_resources[] = { 627static struct resource fsi_resources[] = {
@@ -919,9 +1001,11 @@ static void __init mackerel_map_io(void)
919#define GPIO_PORT9CR 0xE6051009 1001#define GPIO_PORT9CR 0xE6051009
920#define GPIO_PORT10CR 0xE605100A 1002#define GPIO_PORT10CR 0xE605100A
921#define SRCR4 0xe61580bc 1003#define SRCR4 0xe61580bc
1004#define USCCR1 0xE6058144
922static void __init mackerel_init(void) 1005static void __init mackerel_init(void)
923{ 1006{
924 u32 srcr4; 1007 u32 srcr4;
1008 struct clk *clk;
925 1009
926 sh7372_pinmux_init(); 1010 sh7372_pinmux_init();
927 1011
@@ -993,6 +1077,17 @@ static void __init mackerel_init(void)
993 1077
994 intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */ 1078 intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
995 1079
1080 /* setup FSI2 port B (HDMI) */
1081 gpio_request(GPIO_FN_FSIBCK, NULL);
1082 __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
1083
1084 /* set SPU2 clock to 119.6 MHz */
1085 clk = clk_get(NULL, "spu_clk");
1086 if (!IS_ERR(clk)) {
1087 clk_set_rate(clk, clk_round_rate(clk, 119600000));
1088 clk_put(clk);
1089 }
1090
996 /* enable Keypad */ 1091 /* enable Keypad */
997 gpio_request(GPIO_FN_IRQ9_42, NULL); 1092 gpio_request(GPIO_FN_IRQ9_42, NULL);
998 set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); 1093 set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);