X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap2%2Fboard-n800-audio.c;h=e28390e0c195f7599af9b3f80664e1cffa57e076;hb=5e7d1bcc0ccb834c7ab6ac7aa9a346de7c889a2e;hp=8e366919c8f5b232533ce882c9e0ed1fc6dcab15;hpb=ebb235f909c30b4a4b16c485402daf5172874c10;p=linux-2.6-omap-h63xx.git diff --git a/arch/arm/mach-omap2/board-n800-audio.c b/arch/arm/mach-omap2/board-n800-audio.c index 8e366919c8f..e28390e0c19 100644 --- a/arch/arm/mach-omap2/board-n800-audio.c +++ b/arch/arm/mach-omap2/board-n800-audio.c @@ -2,7 +2,7 @@ * linux/arch/arm/mach-omap2/board-n800-audio.c * * Copyright (C) 2006 Nokia Corporation - * Contact: Juha Yrj?l? + * Contact: Juha Yrjola * Jarkko Nikula * * This program is free software; you can redistribute it and/or @@ -23,19 +23,19 @@ #include #include -#include #include #include #include -#include +#include -#include "../plat-omap/dsp/dsp_common.h" +#include #if defined(CONFIG_SPI_TSC2301_AUDIO) && defined(CONFIG_SND_OMAP24XX_EAC) #define AUDIO_ENABLED static struct clk *sys_clkout2; +static struct clk *sys_clkout2_src; static struct clk *func96m_clk; static struct device *eac_device; static struct device *tsc2301_device; @@ -44,47 +44,63 @@ static int enable_audio; static int audio_ok; static spinlock_t audio_lock; - /* - * Leaving EAC pins multiplexed to EAC functionality results - * in about 2 mA extra current leaked. The workaround is to - * multiplex the EAC pins to protected mode (with pull-ups enabled) + * Leaving EAC and sys_clkout2 pins multiplexed to those subsystems results + * in about 2 mA extra current leak when audios are powered down. The + * workaround is to multiplex them to protected mode (with pull-ups enabled) * whenever audio is not being used. */ -static int mux_disabled; +static int eac_mux_disabled = 0; +static int clkout2_mux_disabled = 0; static u32 saved_mux[2]; static void n800_enable_eac_mux(void) { - if (!mux_disabled) + if (!eac_mux_disabled) return; - __raw_writel(saved_mux[0], IO_ADDRESS(0x480000e8)); - __raw_writel(saved_mux[1], IO_ADDRESS(0x48000124)); - mux_disabled = 0; + __raw_writel(saved_mux[1], OMAP2_IO_ADDRESS(0x48000124)); + eac_mux_disabled = 0; } static void n800_disable_eac_mux(void) +{ + if (eac_mux_disabled) { + WARN_ON(eac_mux_disabled); + return; + } + saved_mux[1] = __raw_readl(OMAP2_IO_ADDRESS(0x48000124)); + __raw_writel(0x1f1f1f1f, OMAP2_IO_ADDRESS(0x48000124)); + eac_mux_disabled = 1; +} + +static void n800_enable_clkout2_mux(void) +{ + if (!clkout2_mux_disabled) + return; + __raw_writel(saved_mux[0], OMAP2_IO_ADDRESS(0x480000e8)); + clkout2_mux_disabled = 0; +} + +static void n800_disable_clkout2_mux(void) { u32 l; - if (mux_disabled) { - WARN_ON(mux_disabled); + if (clkout2_mux_disabled) { + WARN_ON(clkout2_mux_disabled); return; } - saved_mux[0] = __raw_readl(IO_ADDRESS(0x480000e8)); - saved_mux[1] = __raw_readl(IO_ADDRESS(0x48000124)); + saved_mux[0] = __raw_readl(OMAP2_IO_ADDRESS(0x480000e8)); l = saved_mux[0] & ~0xff; l |= 0x1f; - __raw_writel(l, IO_ADDRESS(0x480000e8)); - __raw_writel(0x1f1f1f1f, IO_ADDRESS(0x48000124)); - mux_disabled = 1; + __raw_writel(l, OMAP2_IO_ADDRESS(0x480000e8)); + clkout2_mux_disabled = 1; } static int n800_eac_enable_ext_clocks(struct device *dev) { BUG_ON(tsc2301_device == NULL); n800_enable_eac_mux(); - tsc2301_enable_mclk(tsc2301_device); + tsc2301_mixer_enable_mclk(tsc2301_device); return 0; } @@ -92,8 +108,8 @@ static int n800_eac_enable_ext_clocks(struct device *dev) static void n800_eac_disable_ext_clocks(struct device *dev) { BUG_ON(tsc2301_device == NULL); + tsc2301_mixer_disable_mclk(tsc2301_device); n800_disable_eac_mux(); - tsc2301_disable_mclk(tsc2301_device); } static int n800_audio_set_power(void *pdata, int dac, int adc) @@ -112,7 +128,7 @@ static int n800_audio_register_controls(void *pdata, struct snd_card *card) static struct eac_codec n800_eac_codec = { .mclk_src = EAC_MCLK_EXT_2x12288000, - .codec_mode = EAC_CODEC_I2S, + .codec_mode = EAC_CODEC_I2S_MASTER, .codec_conf.i2s.polarity_changed_mode = 0, .codec_conf.i2s.sync_delay_enable = 0, .default_rate = 48000, @@ -171,21 +187,28 @@ static void n800_eac_cleanup(struct device *dev) static int n800_codec_get_clocks(struct device *dev) { + sys_clkout2_src = clk_get(dev, "sys_clkout2_src"); + if (IS_ERR(sys_clkout2_src)) { + dev_err(dev, "Could not get sys_clkout2_src clock\n"); + return -ENODEV; + } sys_clkout2 = clk_get(dev, "sys_clkout2"); if (IS_ERR(sys_clkout2)) { - printk(KERN_ERR "Could not get sys_clkout2\n"); + dev_err(dev, "Could not get sys_clkout2 clock\n"); + clk_put(sys_clkout2_src); return -ENODEV; } /* configure 12 MHz output on SYS_CLKOUT2. Therefore we must use * 96 MHz as its parent in order to get 12 MHz */ func96m_clk = clk_get(dev, "func_96m_ck"); if (IS_ERR(func96m_clk)) { - printk(KERN_ERR "could not get func 96M clock\n"); + dev_err(dev, "Could not get func 96M clock\n"); clk_put(sys_clkout2); + clk_put(sys_clkout2_src); return -ENODEV; } - clk_set_parent(sys_clkout2, func96m_clk); + clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); return 0; @@ -195,24 +218,19 @@ static void n800_codec_put_clocks(struct device *dev) { clk_put(func96m_clk); clk_put(sys_clkout2); + clk_put(sys_clkout2_src); } static int n800_codec_enable_clock(struct device *dev) { - int err; - - err = clk_enable(sys_clkout2); - if (err) - return err; - /* TODO: 'educated' guess for audio codec's PLL startup delay */ - mdelay(1); - - return 0; + n800_enable_clkout2_mux(); + return clk_enable(sys_clkout2); } static void n800_codec_disable_clock(struct device *dev) { clk_disable(sys_clkout2); + n800_disable_clkout2_mux(); } static int n800_codec_init(struct device *dev) @@ -298,7 +316,7 @@ void __init n800_audio_init(struct tsc2301_platform_data *tc) #else -void __init n800_audio_init(void) +void __init n800_audio_init(struct tsc2301_platform_data *tc) { }