Commit 98d27b8a authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Paul Mundt

ARM: mach-shmobile: mackerel: Add HDMI sound support

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 12c4309b
...@@ -373,6 +373,7 @@ static struct platform_device hdmi_lcdc_device = { ...@@ -373,6 +373,7 @@ static struct platform_device hdmi_lcdc_device = {
static struct sh_mobile_hdmi_info hdmi_info = { static struct sh_mobile_hdmi_info hdmi_info = {
.lcd_chan = &hdmi_lcdc_info.ch[0], .lcd_chan = &hdmi_lcdc_info.ch[0],
.lcd_dev = &hdmi_lcdc_device.dev, .lcd_dev = &hdmi_lcdc_device.dev,
.flags = HDMI_SND_SRC_SPDIF,
}; };
static struct resource hdmi_resources[] = { static struct resource hdmi_resources[] = {
...@@ -534,12 +535,93 @@ static struct platform_device leds_device = { ...@@ -534,12 +535,93 @@ static struct platform_device leds_device = {
/* FSI */ /* FSI */
#define IRQ_FSI evt2irq(0x1840) #define IRQ_FSI evt2irq(0x1840)
static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
{
int ret;
if (rate <= 0)
return 0;
if (!enable) {
clk_disable(clk);
return 0;
}
ret = clk_set_rate(clk, clk_round_rate(clk, rate));
if (ret < 0)
return ret;
return clk_enable(clk);
}
static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
{
struct clk *fsib_clk;
struct clk *fdiv_clk = &sh7372_fsidivb_clk;
long fsib_rate = 0;
long fdiv_rate = 0;
int ackmd_bpfmd;
int ret;
/* FSIA is slave mode. nothing to do here */
if (is_porta)
return 0;
/* clock start */
switch (rate) {
case 44100:
fsib_rate = rate * 256;
ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
break;
case 48000:
fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
fdiv_rate = rate * 256;
ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
break;
default:
pr_err("unsupported rate in FSI2 port B\n");
return -EINVAL;
}
/* FSI B setting */
fsib_clk = clk_get(dev, "ickb");
if (IS_ERR(fsib_clk))
return -EIO;
/* fsib */
ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
if (ret < 0)
goto fsi_set_rate_end;
/* FSI DIV */
ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
if (ret < 0) {
/* disable FSI B */
if (enable)
__fsi_set_round_rate(fsib_clk, fsib_rate, 0);
goto fsi_set_rate_end;
}
ret = ackmd_bpfmd;
fsi_set_rate_end:
clk_put(fsib_clk);
return ret;
}
static struct sh_fsi_platform_info fsi_info = { static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV | .porta_flags = SH_FSI_BRS_INV |
SH_FSI_OUT_SLAVE_MODE | SH_FSI_OUT_SLAVE_MODE |
SH_FSI_IN_SLAVE_MODE | SH_FSI_IN_SLAVE_MODE |
SH_FSI_OFMT(PCM) | SH_FSI_OFMT(PCM) |
SH_FSI_IFMT(PCM), SH_FSI_IFMT(PCM),
.portb_flags = SH_FSI_BRS_INV |
SH_FSI_BRM_INV |
SH_FSI_LRS_INV |
SH_FSI_OFMT(SPDIF),
.set_rate = fsi_set_rate,
}; };
static struct resource fsi_resources[] = { static struct resource fsi_resources[] = {
...@@ -919,9 +1001,11 @@ static void __init mackerel_map_io(void) ...@@ -919,9 +1001,11 @@ static void __init mackerel_map_io(void)
#define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT9CR 0xE6051009
#define GPIO_PORT10CR 0xE605100A #define GPIO_PORT10CR 0xE605100A
#define SRCR4 0xe61580bc #define SRCR4 0xe61580bc
#define USCCR1 0xE6058144
static void __init mackerel_init(void) static void __init mackerel_init(void)
{ {
u32 srcr4; u32 srcr4;
struct clk *clk;
sh7372_pinmux_init(); sh7372_pinmux_init();
...@@ -993,6 +1077,17 @@ static void __init mackerel_init(void) ...@@ -993,6 +1077,17 @@ static void __init mackerel_init(void)
intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */ intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
/* setup FSI2 port B (HDMI) */
gpio_request(GPIO_FN_FSIBCK, NULL);
__raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
/* set SPU2 clock to 119.6 MHz */
clk = clk_get(NULL, "spu_clk");
if (!IS_ERR(clk)) {
clk_set_rate(clk, clk_round_rate(clk, 119600000));
clk_put(clk);
}
/* enable Keypad */ /* enable Keypad */
gpio_request(GPIO_FN_IRQ9_42, NULL); gpio_request(GPIO_FN_IRQ9_42, NULL);
set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
......
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