diff options
Diffstat (limited to 'packages/linux')
13 files changed, 1802 insertions, 45 deletions
diff --git a/packages/linux/linux-kaiser_2.6.24+git.bb b/packages/linux/linux-kaiser_2.6.24+git.bb index 758cbdcc0b..879c6e23be 100644 --- a/packages/linux/linux-kaiser_2.6.24+git.bb +++ b/packages/linux/linux-kaiser_2.6.24+git.bb @@ -4,13 +4,14 @@ PV = "2.6.24+git${SRCREV}" PR = "r1" COMPATIBLE_MACHINE = "htckaiser" +COMPATIBLE_MACHINE = "htcpolaris" + SRC_URI = "git://git.linuxtogo.org/home/groups/mobile-linux/kernel.git;branch=htc-msm;protocol=git" S = "${WORKDIR}/git" do_configure_prepend() { - cp arch/arm/configs/htckaiser_defconfig ../defconfig + cp arch/arm/configs/${MACHINE}_defconfig ../defconfig } - diff --git a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init new file mode 100644 index 0000000000..5123bafe54 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init @@ -0,0 +1,25 @@ +clear + +From: Paul Walmsley <paul@pwsan.com> + + +--- + + arch/arm/plat-omap/dmtimer.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c +index f22506a..e38a11e 100644 +--- a/arch/arm/plat-omap/dmtimer.c ++++ b/arch/arm/plat-omap/dmtimer.c +@@ -703,6 +703,10 @@ int __init omap_dm_timer_init(void) + timer->fclk = clk_get(NULL, clk_name); + } + #endif ++ omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW | ++ OMAP_TIMER_INT_MATCH | ++ OMAP_TIMER_INT_CAPTURE); ++ + } + + return 0; diff --git a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick new file mode 100644 index 0000000000..6eb6c9b477 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick @@ -0,0 +1,97 @@ +OMAP2/3 system tick GPTIMER: use match interrupts rather than overflow interrupts + +From: Paul Walmsley <paul@pwsan.com> + +On some OMAP3 chips, GPTIMER1 will occasionally decline to interrupt +the MPU when a timer overflow event occurs. The timer stops running; +and TOCR is sometimes incremented; but the MPU apparently never receives +the interrupt. This patch was an experiment in using the GPTIMER +match interrupt to determine if it resolves the problem. +Unfortunately, it does not; the same problem occurs with match +interrupts; but this patch is preserved as the base for a +match+overflow interrupt workaround used in a following patch. +--- + + arch/arm/mach-omap2/timer-gp.c | 32 ++++++++++---------------------- + 1 files changed, 10 insertions(+), 22 deletions(-) + +diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c +index 557603f..51996ba 100644 +--- a/arch/arm/mach-omap2/timer-gp.c ++++ b/arch/arm/mach-omap2/timer-gp.c +@@ -36,6 +36,8 @@ + #include <asm/mach/time.h> + #include <asm/arch/dmtimer.h> + ++#define GPTIMER_MATCH_VAL 0xffff0000 ++ + static struct omap_dm_timer *gptimer; + static struct clock_event_device clockevent_gpt; + +@@ -44,7 +46,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) + struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id; + struct clock_event_device *evt = &clockevent_gpt; + +- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW); ++ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH); + + evt->event_handler(evt); + return IRQ_HANDLED; +@@ -59,7 +61,7 @@ static struct irqaction omap2_gp_timer_irq = { + static int omap2_gp_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) + { +- omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); ++ omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles); + + return 0; + } +@@ -67,29 +69,12 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles, + static void omap2_gp_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) + { +- u32 period; +- + omap_dm_timer_stop(gptimer); +- +- switch (mode) { +- case CLOCK_EVT_MODE_PERIODIC: +- period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; +- period -= 1; +- +- omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); +- break; +- case CLOCK_EVT_MODE_ONESHOT: +- break; +- case CLOCK_EVT_MODE_UNUSED: +- case CLOCK_EVT_MODE_SHUTDOWN: +- case CLOCK_EVT_MODE_RESUME: +- break; +- } + } + + static struct clock_event_device clockevent_gpt = { + .name = "gp timer", +- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, ++ .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_next_event = omap2_gp_timer_set_next_event, + .set_mode = omap2_gp_timer_set_mode, +@@ -111,12 +96,15 @@ static void __init omap2_gp_clockevent_init(void) + + omap2_gp_timer_irq.dev_id = (void *)gptimer; + setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); +- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); ++ omap_dm_timer_stop(gptimer); ++ /* omap_dm_timer_set_load(gptimer, 0, 0);*/ ++ omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL); ++ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH); + + clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, + clockevent_gpt.shift); + clockevent_gpt.max_delta_ns = +- clockevent_delta2ns(0xffffffff, &clockevent_gpt); ++ clockevent_delta2ns(GPTIMER_MATCH_VAL, &clockevent_gpt); + clockevent_gpt.min_delta_ns = + clockevent_delta2ns(1, &clockevent_gpt); + diff --git a/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf new file mode 100644 index 0000000000..3de6e05042 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf @@ -0,0 +1,94 @@ +OMAP2/3 system tick GPTIMER: use overflow interrupts to detect missing match interrupts + +From: Paul Walmsley <paul@pwsan.com> + +GPTIMER1 on some OMAP3 chips occasionally misses match conditions +between the timer counter and the target register value, and does not +interrupt to the MPU. This patch adds another line of defense by +setting the timer to generate an overflow interrupt 0.5 seconds after the +timer passes the original comparison value. + +If interrupts are masked for a long period of time, one would expect +both a match and an overflow interrupt to be logged. This is considered +a normal condition. However, if only an overflow interrupt is logged, +this is considered evidence of a hardware bug and the kernel will issue +a warning. + +This workaround is unlikely to be 100% effective, since GPTIMER1 has +also been observed to lose overflow interrupts occasionally. It is +hoped that the probability of losing both will be significantly lower +than the probability of losing either one. +--- + + arch/arm/mach-omap2/timer-gp.c | 36 ++++++++++++++++++++++++++++++++---- + 1 files changed, 32 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c +index 51996ba..ce5c2b4 100644 +--- a/arch/arm/mach-omap2/timer-gp.c ++++ b/arch/arm/mach-omap2/timer-gp.c +@@ -36,17 +36,43 @@ + #include <asm/mach/time.h> + #include <asm/arch/dmtimer.h> + +-#define GPTIMER_MATCH_VAL 0xffff0000 ++/* ++ * The number of timer ticks to delay will be subtracted from ++ * GPTIMER_MATCH_VAL before loading into the timer. So GPTIMER_MATCH_VAL ++ * constrains the longest delay that can be generated with the timer. ++ * Since the current code uses overflow interrupts as protection against ++ * missed comparison interrupts, this value should also be sufficiently ++ * large such that there is not an excessively long delay between ticks ++ * if the comparison interrupt fails to arrive. The 0xfffff800 value ++ * below results in a half-second delay in such a case when using ++ * the 32kHz timer as source. ++ */ ++#define GPTIMER_MATCH_VAL (0xffffffff - (32768/2)) + + static struct omap_dm_timer *gptimer; + static struct clock_event_device clockevent_gpt; + ++static u32 last_load; ++ + static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) + { + struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id; + struct clock_event_device *evt = &clockevent_gpt; +- +- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH); ++ u32 v; ++ ++ v = omap_dm_timer_read_status(gpt); ++ if ((v & OMAP_TIMER_INT_OVERFLOW) && !(v & OMAP_TIMER_INT_MATCH)) { ++ /* ++ * Should never happen. Current belief is that this is ++ * due to a hardware bug in the GPTIMER block on some ++ * OMAP3 revisions. ++ */ ++ pr_err("*** GPTIMER missed match interrupt! last load: %08x\n", ++ last_load); ++ WARN_ON(1); ++ } ++ ++ omap_dm_timer_write_status(gpt, v); + + evt->event_handler(evt); + return IRQ_HANDLED; +@@ -61,6 +87,7 @@ static struct irqaction omap2_gp_timer_irq = { + static int omap2_gp_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) + { ++ last_load = GPTIMER_MATCH_VAL - cycles; + omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles); + + return 0; +@@ -99,7 +126,8 @@ static void __init omap2_gp_clockevent_init(void) + omap_dm_timer_stop(gptimer); + /* omap_dm_timer_set_load(gptimer, 0, 0);*/ + omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL); +- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH); ++ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH | ++ OMAP_TIMER_INT_OVERFLOW); + + clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, + clockevent_gpt.shift); diff --git a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q new file mode 100644 index 0000000000..aa9f09811a --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q @@ -0,0 +1,110 @@ +Add extra debug for the q_d_w_o() when work fn is already active. + +From: Paul Walmsley <paul@pwsan.com> + + +--- + + arch/arm/mach-omap2/timer-gp.c | 3 ++- + arch/arm/plat-omap/dmtimer.c | 20 ++++++++++++++++++++ + include/asm-arm/arch-omap/dmtimer.h | 1 + + kernel/time/timer_list.c | 8 ++++++++ + 4 files changed, 31 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c +index ce5c2b4..e3ed368 100644 +--- a/arch/arm/mach-omap2/timer-gp.c ++++ b/arch/arm/mach-omap2/timer-gp.c +@@ -50,6 +50,7 @@ + #define GPTIMER_MATCH_VAL (0xffffffff - (32768/2)) + + static struct omap_dm_timer *gptimer; ++struct omap_dm_timer *gptimer_pub; + static struct clock_event_device clockevent_gpt; + + static u32 last_load; +@@ -111,7 +112,7 @@ static void __init omap2_gp_clockevent_init(void) + { + u32 tick_rate; + +- gptimer = omap_dm_timer_request_specific(1); ++ gptimer = gptimer_pub = omap_dm_timer_request_specific(1); + BUG_ON(gptimer == NULL); + + #if defined(CONFIG_OMAP_32K_TIMER) +diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c +index e38a11e..b10f8ac 100644 +--- a/arch/arm/plat-omap/dmtimer.c ++++ b/arch/arm/plat-omap/dmtimer.c +@@ -614,6 +614,26 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, + omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); + } + ++void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer) ++{ ++ u32 l; ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); ++ pr_err("GPT TCRR: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG); ++ pr_err("GPT TMAT: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); ++ pr_err("GPT TISR: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_INT_EN_REG); ++ pr_err("GPT TIER: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); ++ pr_err("GPT TCLR: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG); ++ pr_err("GPT TOCR: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_COUNT_REG); ++ pr_err("GPT TOWR: %08x\n", l); ++} ++ ++ + unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) + { + unsigned int l; +diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h +index 02b29e8..a8123e9 100644 +--- a/include/asm-arm/arch-omap/dmtimer.h ++++ b/include/asm-arm/arch-omap/dmtimer.h +@@ -73,6 +73,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler); + + void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value); + ++void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer); + unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer); + void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value); + unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer); +diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c +index a40e20f..452eab7 100644 +--- a/kernel/time/timer_list.c ++++ b/kernel/time/timer_list.c +@@ -18,6 +18,8 @@ + #include <linux/kallsyms.h> + #include <linux/tick.h> + ++#include <asm/arch/dmtimer.h> ++ + #include <asm/uaccess.h> + + typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes); +@@ -239,6 +241,8 @@ static void timer_list_show_tickdevices(struct seq_file *m) + static void timer_list_show_tickdevices(struct seq_file *m) { } + #endif + ++extern struct omap_dm_timer *gptimer_pub; ++ + static int timer_list_show(struct seq_file *m, void *v) + { + u64 now = ktime_to_ns(ktime_get()); +@@ -254,6 +258,10 @@ static int timer_list_show(struct seq_file *m, void *v) + SEQ_printf(m, "\n"); + timer_list_show_tickdevices(m); + ++ SEQ_printf(m, "\n"); ++ ++ omap_dm_timer_dump_int_enable(gptimer_pub); ++ + return 0; + } + diff --git a/packages/linux/linux-omap2-git/beagleboard/ASoC-TWL4030-codec-driver.patch b/packages/linux/linux-omap2-git/beagleboard/ASoC-TWL4030-codec-driver.patch new file mode 100644 index 0000000000..ef9a0ed0fe --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/ASoC-TWL4030-codec-driver.patch @@ -0,0 +1,831 @@ +From: Steve Sakoman <steve@sakoman.com> +Date: Fri, 18 Jul 2008 16:41:27 +0000 (-0700) +Subject: ASoC TWL4030 codec driver +X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=67b73de03016cc31b1f91af93c57b8e749c13520;hp=d3b3ae0fe6c71641da19c8de466ec366d39847e3 + +ASoC TWL4030 codec driver + +Basic audio support for the TWL4030 + +Signed-off-by: Steve Sakoman <steve@sakoman.com> +--- + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 3903ab7..468536d 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -44,3 +44,7 @@ config SND_SOC_CS4270_VD33_ERRATA + config SND_SOC_TLV320AIC3X + tristate + depends on SND_SOC && I2C ++ ++config SND_SOC_TWL4030 ++ tristate ++ depends on SND_SOC && I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index 4e1314c..d2c0b12 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -6,6 +6,7 @@ snd-soc-wm9712-objs := wm9712.o + snd-soc-wm9713-objs := wm9713.o + snd-soc-cs4270-objs := cs4270.o + snd-soc-tlv320aic3x-objs := tlv320aic3x.o ++snd-soc-twl4030-objs := twl4030.o + + obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o + obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o +@@ -15,3 +16,4 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o + obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o + obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o + obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o ++obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o +diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c +new file mode 100644 +index 0000000..25a154c +--- /dev/null ++++ b/sound/soc/codecs/twl4030.c +@@ -0,0 +1,626 @@ ++/* ++ * ALSA SoC TWL4030 codec driver ++ * ++ * Author: Steve Sakoman, <steve@sakoman.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/pm.h> ++#include <linux/i2c.h> ++#include <linux/platform_device.h> ++#include <linux/i2c/twl4030.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++#include <sound/initval.h> ++ ++#include "twl4030.h" ++ ++/* ++ * twl4030 register cache & default register settings ++ */ ++static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { ++ 0x00, /* this register not used */ ++ 0x93, /* REG_CODEC_MODE (0x1) */ ++ 0xc3, /* REG_OPTION (0x2) */ ++ 0x00, /* REG_UNKNOWN (0x3) */ ++ 0x00, /* REG_MICBIAS_CTL (0x4) */ ++ 0x34, /* REG_ANAMICL (0x5) */ ++ 0x14, /* REG_ANAMICR (0x6) */ ++ 0x0a, /* REG_AVADC_CTL (0x7) */ ++ 0x00, /* REG_ADCMICSEL (0x8) */ ++ 0x00, /* REG_DIGMIXING (0x9) */ ++ 0x0c, /* REG_ATXL1PGA (0xA) */ ++ 0x0c, /* REG_ATXR1PGA (0xB) */ ++ 0x00, /* REG_AVTXL2PGA (0xC) */ ++ 0x00, /* REG_AVTXR2PGA (0xD) */ ++ 0x01, /* REG_AUDIO_IF (0xE) */ ++ 0x00, /* REG_VOICE_IF (0xF) */ ++ 0x00, /* REG_ARXR1PGA (0x10) */ ++ 0x00, /* REG_ARXL1PGA (0x11) */ ++ 0x6c, /* REG_ARXR2PGA (0x12) */ ++ 0x6c, /* REG_ARXL2PGA (0x13) */ ++ 0x00, /* REG_VRXPGA (0x14) */ ++ 0x00, /* REG_VSTPGA (0x15) */ ++ 0x00, /* REG_VRX2ARXPGA (0x16) */ ++ 0x0c, /* REG_AVDAC_CTL (0x17) */ ++ 0x00, /* REG_ARX2VTXPGA (0x18) */ ++ 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ ++ 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ ++ 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ ++ 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ ++ 0x00, /* REG_ATX2ARXPGA (0x1D) */ ++ 0x00, /* REG_BT_IF (0x1E) */ ++ 0x00, /* REG_BTPGA (0x1F) */ ++ 0x00, /* REG_BTSTPGA (0x20) */ ++ 0x00, /* REG_EAR_CTL (0x21) */ ++ 0x24, /* REG_HS_SEL (0x22) */ ++ 0x0a, /* REG_HS_GAIN_SET (0x23) */ ++ 0x00, /* REG_HS_POPN_SET (0x24) */ ++ 0x00, /* REG_PREDL_CTL (0x25) */ ++ 0x00, /* REG_PREDR_CTL (0x26) */ ++ 0x00, /* REG_PRECKL_CTL (0x27) */ ++ 0x00, /* REG_PRECKR_CTL (0x28) */ ++ 0x00, /* REG_HFL_CTL (0x29) */ ++ 0x00, /* REG_HFR_CTL (0x2A) */ ++ 0x00, /* REG_ALC_CTL (0x2B) */ ++ 0x00, /* REG_ALC_SET1 (0x2C) */ ++ 0x00, /* REG_ALC_SET2 (0x2D) */ ++ 0x00, /* REG_BOOST_CTL (0x2E) */ ++ 0x01, /* REG_SOFTVOL_CTL (0x2F) */ ++ 0x00, /* REG_DTMF_FREQSEL (0x30) */ ++ 0x00, /* REG_DTMF_TONEXT1H (0x31) */ ++ 0x00, /* REG_DTMF_TONEXT1L (0x32) */ ++ 0x00, /* REG_DTMF_TONEXT2H (0x33) */ ++ 0x00, /* REG_DTMF_TONEXT2L (0x34) */ ++ 0x00, /* REG_DTMF_TONOFF (0x35) */ ++ 0x00, /* REG_DTMF_WANONOFF (0x36) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ ++ 0x16, /* REG_APLL_CTL (0x3A) */ ++ 0x00, /* REG_DTMF_CTL (0x3B) */ ++ 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ ++ 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ ++ 0x00, /* REG_MISC_SET_1 (0x3E) */ ++ 0x00, /* REG_PCMBTMUX (0x3F) */ ++ 0x00, /* not used (0x40) */ ++ 0x00, /* not used (0x41) */ ++ 0x00, /* not used (0x42) */ ++ 0x00, /* REG_RX_PATH_SEL (0x43) */ ++ 0x00, /* REG_VDL_APGA_CTL (0x44) */ ++ 0x00, /* REG_VIBRA_CTL (0x45) */ ++ 0x00, /* REG_VIBRA_SET (0x46) */ ++ 0x00, /* REG_VIBRA_PWM_SET (0x47) */ ++ 0x00, /* REG_ANAMIC_GAIN (0x48) */ ++ 0x00, /* REG_MISC_SET_2 (0x49) */ ++}; ++ ++static void twl4030_dump_registers(void) ++{ ++ int i = 0; ++ u8 data; ++ ++ printk(KERN_INFO "TWL 4030 Register dump for Audio Module\n"); ++ ++ for (i = REG_CODEC_MODE; i <= REG_MISC_SET_2; i++) { ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &data, i); ++ printk(KERN_INFO "Register[0x%02x]=0x%02x\n", i, data); ++ } ++} ++ ++struct twl4030_priv { ++ unsigned int dummy; ++}; ++ ++/* ++ * read twl4030 register cache ++ */ ++static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, ++ unsigned int reg) ++{ ++ u8 *cache = codec->reg_cache; ++ ++ return cache[reg]; ++} ++ ++/* ++ * write twl4030 register cache ++ */ ++static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec, ++ u8 reg, u8 value) ++{ ++ u8 *cache = codec->reg_cache; ++ ++ if (reg >= TWL4030_CACHEREGNUM) ++ return; ++ cache[reg] = value; ++} ++ ++/* ++ * write to the twl4030 register space ++ */ ++static int twl4030_write(struct snd_soc_codec *codec, ++ unsigned int reg, unsigned int value) ++{ ++ twl4030_write_reg_cache(codec, reg, value); ++ return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); ++} ++ ++static void twl4030_init_chip(void) ++{ ++ unsigned char byte; ++ int i; ++ ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, ++ twl4030_reg[REG_CODEC_MODE] & 0xfd, REG_CODEC_MODE); ++ ++ udelay(10); /* delay for power settling */ ++ ++ for (i = REG_OPTION; i <= REG_MISC_SET_2; i++) ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, ++ twl4030_reg[i], i); ++ ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, ++ twl4030_reg[REG_CODEC_MODE], REG_CODEC_MODE); ++ ++ udelay(10); /* delay for power settling */ ++ ++ /* initiate offset cancellation */ ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, ++ twl4030_reg[REG_ANAMICL] | 0x80, REG_ANAMICL); ++ ++ /* wait for offset cancellation to complete */ ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, REG_ANAMICL); ++ while ((byte & 0x80) == 0x80) ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, ++ &byte, REG_ANAMICL); ++ ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, ++ twl4030_reg[REG_MISC_SET_1] | 0x02, REG_MISC_SET_1); ++ ++} ++ ++static const struct snd_kcontrol_new twl4030_snd_controls[] = { ++ SOC_DOUBLE_R("Master Playback Volume", ++ REG_ARXL2PGA, REG_ARXR2PGA, ++ 0, 127, 0), ++ SOC_DOUBLE_R("Capture Volume", ++ REG_ATXL1PGA, REG_ATXR1PGA, ++ 0, 127, 0), ++}; ++ ++/* add non dapm controls */ ++static int twl4030_add_controls(struct snd_soc_codec *codec) ++{ ++ int err, i; ++ ++ for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) { ++ err = snd_ctl_add(codec->card, ++ snd_soc_cnew(&twl4030_snd_controls[i], ++ codec, NULL)); ++ if (err < 0) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { ++ SND_SOC_DAPM_INPUT("INL"), ++ SND_SOC_DAPM_INPUT("INR"), ++ ++ SND_SOC_DAPM_OUTPUT("OUTL"), ++ SND_SOC_DAPM_OUTPUT("OUTR"), ++ ++ SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0), ++ ++ SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), ++}; ++ ++static const char *intercon[][3] = { ++ /* outputs */ ++ {"OUTL", NULL, "DACL"}, ++ {"OUTR", NULL, "DACR"}, ++ ++ /* inputs */ ++ {"ADCL", NULL, "INL"}, ++ {"ADCR", NULL, "INR"}, ++ ++ /* terminator */ ++ {NULL, NULL, NULL}, ++}; ++ ++static int twl4030_add_widgets(struct snd_soc_codec *codec) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(twl4030_dapm_widgets); i++) ++ snd_soc_dapm_new_control(codec, &twl4030_dapm_widgets[i]); ++ ++ /* set up audio path interconnects */ ++ for (i = 0; intercon[i][0] != NULL; i++) ++ snd_soc_dapm_connect_input(codec, intercon[i][0], ++ intercon[i][1], intercon[i][2]); ++ ++ snd_soc_dapm_new_widgets(codec); ++ return 0; ++} ++ ++static int twl4030_dapm_event(struct snd_soc_codec *codec, int event) ++{ ++ ++ printk(KERN_INFO "TWL4030 Audio Codec dapm event\n"); ++ switch (event) { ++ case SNDRV_CTL_POWER_D0: /* full On */ ++ break; ++ case SNDRV_CTL_POWER_D1: /* partial On */ ++ case SNDRV_CTL_POWER_D2: /* partial On */ ++ break; ++ case SNDRV_CTL_POWER_D3hot: /* off, with power */ ++ break; ++ case SNDRV_CTL_POWER_D3cold: /* off, without power */ ++ break; ++ } ++ codec->dapm_state = event; ++ ++ return 0; ++} ++ ++static void twl4030_power_up(struct snd_soc_codec *codec, u8 mode) ++{ ++ u8 popn, hsgain; ++ ++ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ); ++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ); ++ udelay(10); ++ ++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET); ++ popn &= RAMP_DELAY; ++ popn |= VMID_EN | RAMP_DELAY_161MS; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ ++ hsgain = HSR_GAIN_0DB | HSL_GAIN_0DB; ++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain); ++ ++ popn |= RAMP_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++} ++ ++static void twl4030_power_down(struct snd_soc_codec *codec) ++{ ++ u8 popn, hsgain, mode; ++ ++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET); ++ popn &= ~RAMP_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ ++ hsgain = HSR_GAIN_PWR_DOWN | HSL_GAIN_PWR_DOWN; ++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain); ++ ++ popn &= ~VMID_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ ++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE); ++ mode &= ~CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ udelay(10); ++} ++ ++ ++static int twl4030_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_device *socdev = rtd->socdev; ++ struct snd_soc_codec *codec = socdev->codec; ++ struct twl4030_priv *twl4030 = codec->private_data; ++ u8 mode, old_mode, format, old_format; ++ ++ ++ /* bit rate */ ++ old_mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE) & ~CODECPDZ; ++ mode = old_mode; ++ mode &= ~APLL_RATE; ++ switch (params_rate(params)) { ++ case 44100: ++ mode |= APLL_RATE_44100; ++ break; ++ case 48000: ++ mode |= APLL_RATE_48000; ++ break; ++ default: ++ printk(KERN_INFO "TWL4030 hw params: unknown rate %d\n", ++ params_rate(params)); ++ return -EINVAL; ++ } ++ ++ if (mode != old_mode) { ++ /* change rate and turn codec back on */ ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ mode |= CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ } ++ ++ /* sample size */ ++ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF); ++ format = old_format; ++ format &= ~DATA_WIDTH; ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ format |= DATA_WIDTH_16S_16W; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ format |= DATA_WIDTH_32S_24W; ++ break; ++ default: ++ printk(KERN_INFO "TWL4030 hw params: unknown format %d\n", ++ params_format(params)); ++ return -EINVAL; ++ } ++ ++ if (format != old_format) { ++ ++ /* turn off codec before changing format */ ++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE); ++ mode &= ~CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ ++ /* change format */ ++ twl4030_write(codec, REG_AUDIO_IF, format); ++ ++ /* turn on codec */ ++ mode |= CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ } ++ return 0; ++} ++ ++static int twl4030_mute(struct snd_soc_codec_dai *dai, int mute) ++{ ++ struct snd_soc_codec *codec = dai->codec; ++ ++ u8 ldac_reg = twl4030_read_reg_cache(codec, REG_ARXL2PGA); ++ u8 rdac_reg = twl4030_read_reg_cache(codec, REG_ARXR2PGA); ++ ++ if (mute) { ++ twl4030_write(codec, REG_ARXL2PGA, 0x00); ++ twl4030_write(codec, REG_ARXR2PGA, 0x00); ++ twl4030_write_reg_cache(codec, REG_ARXL2PGA, ldac_reg); ++ twl4030_write_reg_cache(codec, REG_ARXR2PGA, rdac_reg); ++ } else { ++ twl4030_write(codec, REG_ARXL2PGA, ldac_reg); ++ twl4030_write(codec, REG_ARXR2PGA, rdac_reg); ++ } ++ ++ return 0; ++} ++ ++static int twl4030_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, ++ unsigned int fmt) ++{ ++ struct snd_soc_codec *codec = codec_dai->codec; ++ struct twl4030_priv *twl4030 = codec->private_data; ++ u8 mode, old_format, format; ++ ++ /* get format */ ++ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF); ++ format = old_format; ++ ++ /* set master/slave audio interface */ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBM_CFM: ++ format &= ~(AIF_SLAVE_EN); ++ format |= CLK256FS_EN; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFS: ++ format &= ~(CLK256FS_EN); ++ format |= AIF_SLAVE_EN; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* interface format */ ++ format &= ~AIF_FORMAT; ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ /* printk(KERN_INFO "TWL4030 set dai fmt: i2s\n"); */ ++ format |= AIF_FORMAT_CODEC; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (format != old_format) { ++ ++ /* turn off codec before changing format */ ++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE); ++ mode &= ~CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ ++ /* change format */ ++ twl4030_write(codec, REG_AUDIO_IF, format); ++ ++ mode |= CODECPDZ; ++ twl4030_write(codec, REG_CODEC_MODE, mode); ++ } ++ ++ return 0; ++} ++ ++#define TWL4030_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) ++#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) ++ ++struct snd_soc_codec_dai twl4030_dai = { ++ .name = "twl4030", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = TWL4030_RATES, ++ .formats = TWL4030_FORMATS,}, ++ .capture = { ++ .stream_name = "Capture", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = TWL4030_RATES, ++ .formats = TWL4030_FORMATS,}, ++ .ops = { ++ .hw_params = twl4030_hw_params, ++ }, ++ .dai_ops = { ++ .digital_mute = twl4030_mute, ++ .set_fmt = twl4030_set_dai_fmt, ++ } ++}; ++EXPORT_SYMBOL_GPL(twl4030_dai); ++ ++static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ struct snd_soc_codec *codec = socdev->codec; ++ ++ printk(KERN_INFO "TWL4030 Audio Codec suspend\n"); ++ twl4030_dapm_event(codec, SNDRV_CTL_POWER_D3cold); ++ ++ return 0; ++} ++ ++static int twl4030_resume(struct platform_device *pdev) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ struct snd_soc_codec *codec = socdev->codec; ++ int i; ++ u16 *cache = codec->reg_cache; ++ ++ printk(KERN_INFO "TWL4030 Audio Codec resume\n"); ++ /* Sync reg_cache with the hardware */ ++ for (i = REG_CODEC_MODE; i <= REG_MISC_SET_2; i++) ++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, cache[i], i); ++ ++ twl4030_dapm_event(codec, SNDRV_CTL_POWER_D3hot); ++ twl4030_dapm_event(codec, codec->suspend_dapm_state); ++ return 0; ++} ++ ++/* ++ * initialize the driver ++ * register the mixer and dsp interfaces with the kernel ++ */ ++ ++static int twl4030_init(struct snd_soc_device *socdev) ++{ ++ struct snd_soc_codec *codec = socdev->codec; ++ int ret = 0; ++ ++ printk(KERN_INFO "TWL4030 Audio Codec init \n"); ++ ++ codec->name = "twl4030"; ++ codec->owner = THIS_MODULE; ++ codec->read = twl4030_read_reg_cache; ++ codec->write = twl4030_write; ++ codec->dapm_event = twl4030_dapm_event; ++ codec->dai = &twl4030_dai; ++ codec->num_dai = 1; ++ codec->reg_cache_size = sizeof(twl4030_reg); ++ codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), ++ GFP_KERNEL); ++ if (codec->reg_cache == NULL) ++ return -ENOMEM; ++ ++ /* register pcms */ ++ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); ++ if (ret < 0) { ++ printk(KERN_ERR "twl4030: failed to create pcms\n"); ++ goto pcm_err; ++ } ++ ++ twl4030_add_controls(codec); ++ twl4030_add_widgets(codec); ++ ++ ret = snd_soc_register_card(socdev); ++ if (ret < 0) { ++ printk(KERN_ERR "twl4030: failed to register card\n"); ++ goto card_err; ++ } ++ ++ twl4030_init_chip(); ++ twl4030_power_up(codec, APLL_RATE_44100 | OPT_MODE); ++ ++ return ret; ++ ++card_err: ++ printk(KERN_INFO "TWL4030 Audio Codec init card error\n"); ++ snd_soc_free_pcms(socdev); ++ snd_soc_dapm_free(socdev); ++pcm_err: ++ printk(KERN_INFO "TWL4030 Audio Codec init pcm error\n"); ++ kfree(codec->reg_cache); ++ return ret; ++} ++ ++static struct snd_soc_device *twl4030_socdev; ++ ++static int twl4030_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ struct snd_soc_codec *codec; ++ struct twl4030_priv *twl4030; ++ ++ codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); ++ if (codec == NULL) ++ return -ENOMEM; ++ ++ twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); ++ if (twl4030 == NULL) { ++ kfree(codec); ++ return -ENOMEM; ++ } ++ ++ codec->private_data = twl4030; ++ socdev->codec = codec; ++ mutex_init(&codec->mutex); ++ INIT_LIST_HEAD(&codec->dapm_widgets); ++ INIT_LIST_HEAD(&codec->dapm_paths); ++ ++ twl4030_socdev = socdev; ++ twl4030_init(socdev); ++ ++ return 0; ++} ++ ++static int twl4030_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ struct snd_soc_codec *codec = socdev->codec; ++ ++ printk(KERN_INFO "TWL4030 Audio Codec remove\n"); ++ kfree(codec->private_data); ++ kfree(codec); ++ ++ return 0; ++} ++ ++struct snd_soc_codec_device soc_codec_dev_twl4030 = { ++ .probe = twl4030_probe, ++ .remove = twl4030_remove, ++ .suspend = twl4030_suspend, ++ .resume = twl4030_resume, ++}; ++EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030); ++ ++MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); ++MODULE_AUTHOR("Steve Sakoman"); ++MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h +new file mode 100644 +index 0000000..6eecde1 +--- /dev/null ++++ b/sound/soc/codecs/twl4030.h +@@ -0,0 +1,152 @@ ++/* ++ * ALSA SoC TWL4030 codec driver ++ * ++ * Author: Steve Sakoman, <steve@sakoman.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef __TWL4030_AUDIO_H__ ++#define __TWL4030_AUDIO_H__ ++ ++#define REG_CODEC_MODE 0x1 ++#define REG_OPTION 0x2 ++#define REG_UNKNOWN 0x3 ++#define REG_MICBIAS_CTL 0x4 ++#define REG_ANAMICL 0x5 ++#define REG_ANAMICR 0x6 ++#define REG_AVADC_CTL 0x7 ++#define REG_ADCMICSEL 0x8 ++#define REG_DIGMIXING 0x9 ++#define REG_ATXL1PGA 0xA ++#define REG_ATXR1PGA 0xB ++#define REG_AVTXL2PGA 0xC ++#define REG_AVTXR2PGA 0xD ++#define REG_AUDIO_IF 0xE ++#define REG_VOICE_IF 0xF ++#define REG_ARXR1PGA 0x10 ++#define REG_ARXL1PGA 0x11 ++#define REG_ARXR2PGA 0x12 ++#define REG_ARXL2PGA 0x13 ++#define REG_VRXPGA 0x14 ++#define REG_VSTPGA 0x15 ++#define REG_VRX2ARXPGA 0x16 ++#define REG_AVDAC_CTL 0x17 ++#define REG_ARX2VTXPGA 0x18 ++#define REG_ARXL1_APGA_CTL 0x19 ++#define REG_ARXR1_APGA_CTL 0x1A ++#define REG_ARXL2_APGA_CTL 0x1B ++#define REG_ARXR2_APGA_CTL 0x1C ++#define REG_ATX2ARXPGA 0x1D ++#define REG_BT_IF 0x1E ++#define REG_BTPGA 0x1F ++#define REG_BTSTPGA 0x20 ++#define REG_EAR_CTL 0x21 ++#define REG_HS_SEL 0x22 ++#define REG_HS_GAIN_SET 0x23 ++#define REG_HS_POPN_SET 0x24 ++#define REG_PREDL_CTL 0x25 ++#define REG_PREDR_CTL 0x26 ++#define REG_PRECKL_CTL 0x27 ++#define REG_PRECKR_CTL 0x28 ++#define REG_HFL_CTL 0x29 ++#define REG_HFR_CTL 0x2A ++#define REG_ALC_CTL 0x2B ++#define REG_ALC_SET1 0x2C ++#define REG_ALC_SET2 0x2D ++#define REG_BOOST_CTL 0x2E ++#define REG_SOFTVOL_CTL 0x2F ++#define REG_DTMF_FREQSEL 0x30 ++#define REG_DTMF_TONEXT1H 0x31 ++#define REG_DTMF_TONEXT1L 0x32 ++#define REG_DTMF_TONEXT2H 0x33 ++#define REG_DTMF_TONEXT2L 0x34 ++#define REG_DTMF_TONOFF 0x35 ++#define REG_DTMF_WANONOFF 0x36 ++#define REG_I2S_RX_SCRAMBLE_H 0x37 ++#define REG_I2S_RX_SCRAMBLE_M 0x38 ++#define REG_I2S_RX_SCRAMBLE_L 0x39 ++#define REG_APLL_CTL 0x3A ++#define REG_DTMF_CTL 0x3B ++#define REG_DTMF_PGA_CTL2 0x3C ++#define REG_DTMF_PGA_CTL1 0x3D ++#define REG_MISC_SET_1 0x3E ++#define REG_PCMBTMUX 0x3F ++#define REG_RX_PATH_SEL 0x43 ++#define REG_VDL_APGA_CTL 0x44 ++#define REG_VIBRA_CTL 0x45 ++#define REG_VIBRA_SET 0x46 ++#define REG_VIBRA_PWM_SET 0x47 ++#define REG_ANAMIC_GAIN 0x48 ++#define REG_MISC_SET_2 0x49 ++ ++#define TWL4030_CACHEREGNUM (REG_MISC_SET_2 + 1) ++ ++/* Bitfield Definitions */ ++ ++/* CODEC_MODE (0x01) Fields */ ++ ++#define APLL_RATE 0xF0 ++#define APLL_RATE_8000 0x00 ++#define APLL_RATE_11025 0x10 ++#define APLL_RATE_12000 0x20 ++#define APLL_RATE_16000 0x40 ++#define APLL_RATE_22050 0x50 ++#define APLL_RATE_24000 0x60 ++#define APLL_RATE_32000 0x80 ++#define APLL_RATE_44100 0x90 ++#define APLL_RATE_48000 0xa0 ++#define SEL_16K 0x04 ++#define CODECPDZ 0x02 ++#define OPT_MODE 0x01 ++ ++/* AUDIO_IF (0x0E) Fields */ ++ ++#define AIF_SLAVE_EN 0x80 ++#define DATA_WIDTH 0x60 ++#define DATA_WIDTH_16S_16W 0x00 ++#define DATA_WIDTH_32S_16W 0x40 ++#define DATA_WIDTH_32S_24W 0x60 ++#define AIF_FORMAT 0x18 ++#define AIF_FORMAT_CODEC 0x00 ++#define AIF_FORMAT_LEFT 0x08 ++#define AIF_FORMAT_RIGHT 0x10 ++#define AIF_FORMAT_TDM 0x18 ++#define AIF_TRI_EN 0x04 ++#define CLK256FS_EN 0x02 ++#define AIF_EN 0x01 ++ ++/* HS_GAIN_SET (0x23) Fields */ ++ ++#define HSR_GAIN 0x0c ++#define HSR_GAIN_PWR_DOWN 0x00 ++#define HSR_GAIN_PLUS_6DB 0x04 ++#define HSR_GAIN_0DB 0x08 ++#define HSR_GAIN_MINUS_6DB 0x0c ++#define HSL_GAIN 0x0c ++#define HSL_GAIN_PWR_DOWN 0x00 ++#define HSL_GAIN_PLUS_6DB 0x01 ++#define HSL_GAIN_0DB 0x02 ++#define HSL_GAIN_MINUS_6DB 0x03 ++ ++/* HS_POPN_SET (0x24) Fields */ ++ ++#define VMID_EN 0x40 ++#define EXTMUTE 0x20 ++#define RAMP_DELAY 0x1C ++#define RAMP_DELAY_20MS 0x00 ++#define RAMP_DELAY_40MS 0x04 ++#define RAMP_DELAY_81MS 0x08 ++#define RAMP_DELAY_161MS 0x0c ++#define RAMP_DELAY_323MS 0x10 ++#define RAMP_DELAY_645MS 0x14 ++#define RAMP_DELAY_1291MS 0x18 ++#define RAMP_DELAY_2581MS 0x1c ++#define RAMP_EN 0x02 ++ ++extern struct snd_soc_codec_dai twl4030_dai; ++extern struct snd_soc_codec_device soc_codec_dev_twl4030; ++ ++#endif /* End of __TWL4030_AUDIO_H__ */ diff --git a/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for-OMAP3-EVM.patch b/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for-OMAP3-EVM.patch new file mode 100644 index 0000000000..ea8108e090 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for-OMAP3-EVM.patch @@ -0,0 +1,278 @@ +From: Steve Sakoman <steve@sakoman.com> +Date: Fri, 18 Jul 2008 16:41:37 +0000 (-0700) +Subject: ASoC machine driver for OMAP3 EVM +X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=2e6af042b4af677e62e32d048e770f6755e67a7f + +ASoC machine driver for OMAP3 EVM + +Add basic audio support for OMAP3 EVM + +Signed-off-by: Steve Sakoman <steve@sakoman.com> +--- + +diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig +index cce83e5..a48780a 100644 +--- a/arch/arm/configs/omap3_beagle_defconfig ++++ b/arch/arm/configs/omap3_beagle_defconfig +@@ -735,7 +735,82 @@ CONFIG_FONT_8x16=y + # + # Sound + # +-# CONFIG_SOUND is not set ++CONFIG_SOUND=y ++ ++# ++# Advanced Linux Sound Architecture ++# ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++CONFIG_SND_HWDEP=y ++CONFIG_SND_RAWMIDI=y ++# CONFIG_SND_SEQUENCER is not set ++CONFIG_SND_OSSEMUL=y ++CONFIG_SND_MIXER_OSS=y ++CONFIG_SND_PCM_OSS=y ++CONFIG_SND_PCM_OSS_PLUGINS=y ++# CONFIG_SND_DYNAMIC_MINORS is not set ++CONFIG_SND_SUPPORT_OLD_API=y ++CONFIG_SND_VERBOSE_PROCFS=y ++CONFIG_SND_VERBOSE_PRINTK=y ++CONFIG_SND_DEBUG=y ++CONFIG_SND_DEBUG_DETECT=y ++CONFIG_SND_PCM_XRUN_DEBUG=y ++ ++# ++# Generic devices ++# ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_MPU401 is not set ++ ++# ++# ALSA ARM devices ++# ++# CONFIG_SND_OMAP_AIC23 is not set ++# CONFIG_SND_OMAP_TSC2101 is not set ++# CONFIG_SND_SX1 is not set ++# CONFIG_SND_OMAP_TSC2102 is not set ++# CONFIG_SND_OMAP24XX_EAC is not set ++ ++# ++# SPI devices ++# ++ ++# ++# USB devices ++# ++CONFIG_SND_USB_AUDIO=y ++# CONFIG_SND_USB_CAIAQ is not set ++ ++# ++# System on Chip audio support ++# ++CONFIG_SND_SOC=y ++ ++# ++# ALSA SoC audio for Freescale SOCs ++# ++ ++# ++# SoC Audio for the Texas Instruments OMAP ++# ++CONFIG_SND_OMAP_SOC=y ++CONFIG_SND_OMAP_SOC_MCBSP=y ++CONFIG_SND_OMAP_SOC_OMAP3BEAGLE=y ++CONFIG_SND_SOC_TWL4030=y ++ ++# ++# Open Sound System ++# ++CONFIG_SOUND_PRIME=y ++CONFIG_HID_SUPPORT=y ++CONFIG_HID=y ++# CONFIG_HID_DEBUG is not set ++# CONFIG_HIDRAW is not set ++ + # CONFIG_HID_SUPPORT is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y +diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig +index 0230d83..0def5ba 100644 +--- a/sound/soc/omap/Kconfig ++++ b/sound/soc/omap/Kconfig +@@ -16,4 +16,12 @@ config SND_OMAP_SOC_N810 + help + Say Y if you want to add support for SoC audio on Nokia N810. + ++config SND_OMAP_SOC_OMAP3EVM ++ tristate "SoC Audio support for OMAP3 EVM" ++ depends on SND_OMAP_SOC && MACH_OMAP3EVM ++ select SND_OMAP_SOC_MCBSP ++ select SND_SOC_TWL4030 ++ help ++ Say Y if you want to add support for SoC audio on the OMAP3 EVM. ++ + endmenu +diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile +index d8d8d58..985eddc 100644 +--- a/sound/soc/omap/Makefile ++++ b/sound/soc/omap/Makefile +@@ -7,5 +7,8 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o + + # OMAP Machine Support + snd-soc-n810-objs := n810.o ++snd-soc-omap3evm-objs := omap3evm.o + + obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o ++obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o ++ +diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c +new file mode 100644 +index 0000000..d436bb4 +--- /dev/null ++++ b/sound/soc/omap/omap3evm.c +@@ -0,0 +1,142 @@ ++/* ++ * omap3evm.c -- SoC audio for OMAP3 EVM ++ * ++ * Author: Steve Sakoman <steve@sakoman.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ */ ++ ++#include <linux/clk.h> ++#include <linux/platform_device.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/mcbsp.h> ++ ++#include "omap-mcbsp.h" ++#include "omap-pcm.h" ++#include "../codecs/twl4030.h" ++ ++static int omap3evm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; ++ int ret; ++ ++ /* Set codec DAI configuration */ ++ ret = codec_dai->dai_ops.set_fmt(codec_dai, ++ SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) { ++ printk(KERN_INFO "can't set codec DAI configuration\n"); ++ return ret; ++ } ++ ++ /* Set cpu DAI configuration */ ++ ret = cpu_dai->dai_ops.set_fmt(cpu_dai, ++ SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) { ++ printk(KERN_INFO "can't set cpu DAI configuration\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static struct snd_soc_ops omap3evm_ops = { ++ .hw_params = omap3evm_hw_params, ++}; ++ ++/* Digital audio interface glue - connects codec <--> CPU */ ++static struct snd_soc_dai_link omap3evm_dai = { ++ .name = "TWL4030", ++ .stream_name = "TWL4030", ++ .cpu_dai = &omap_mcbsp_dai[0], ++ .codec_dai = &twl4030_dai, ++ .ops = &omap3evm_ops, ++}; ++ ++/* Audio machine driver */ ++static struct snd_soc_machine snd_soc_machine_omap3evm = { ++ .name = "omap3evm", ++ .dai_link = &omap3evm_dai, ++ .num_links = 1, ++}; ++ ++/* Audio subsystem */ ++static struct snd_soc_device omap3evm_snd_devdata = { ++ .machine = &snd_soc_machine_omap3evm, ++ .platform = &omap_soc_platform, ++ .codec_dev = &soc_codec_dev_twl4030, ++}; ++ ++static struct platform_device *omap3evm_snd_device; ++ ++static int __init omap3evm_soc_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "OMAP3 EVM SoC init\n"); ++ if (!machine_is_omap3evm()) { ++ printk(KERN_INFO "Not OMAP3 EVM!\n"); ++ return -ENODEV; ++ } ++ ++ omap3evm_snd_device = platform_device_alloc("soc-audio", -1); ++ if (!omap3evm_snd_device) { ++ printk(KERN_INFO "Platform device allocation failed\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata); ++ omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev; ++ *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1; /* McBSP2 */ ++ ++ ret = platform_device_add(omap3evm_snd_device); ++ if (ret) ++ goto err1; ++ ++ return 0; ++ ++err1: ++ printk(KERN_INFO "Unable to add platform device\n"); ++ platform_device_put(omap3evm_snd_device); ++ ++ return ret; ++} ++ ++static void __exit omap3evm_soc_exit(void) ++{ ++ printk(KERN_INFO "OMAP3 EVM SoC exit\n"); ++ platform_device_unregister(omap3evm_snd_device); ++} ++ ++module_init(omap3evm_soc_init); ++module_exit(omap3evm_soc_exit); ++ ++MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>"); ++MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); ++MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for_OMAP3-Beagle.patch b/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for_OMAP3-Beagle.patch new file mode 100644 index 0000000000..9343a9c59a --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/ASoC-machine-driver-for_OMAP3-Beagle.patch @@ -0,0 +1,279 @@ +From: Steve Sakoman <steve@sakoman.com> +Date: Fri, 18 Jul 2008 16:41:49 +0000 (-0700) +Subject: ASoC machine driver for OMAP3 Beagle +X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=543a3a0cd4c6f68be6f084ccfe63ec5a514eba59 + +ASoC machine driver for OMAP3 Beagle + +Add basic audio support for OMAP3 Beagle + +Signed-off-by: Steve Sakoman <steve@sakoman.com> +--- + +diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig +index 718c914..4ac730c 100644 +--- a/arch/arm/configs/omap3_evm_defconfig ++++ b/arch/arm/configs/omap3_evm_defconfig +@@ -835,7 +835,82 @@ CONFIG_DUMMY_CONSOLE=y + # + # Sound + # +-# CONFIG_SOUND is not set ++CONFIG_SOUND=y ++ ++# ++# Advanced Linux Sound Architecture ++# ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++CONFIG_SND_HWDEP=y ++CONFIG_SND_RAWMIDI=y ++# CONFIG_SND_SEQUENCER is not set ++CONFIG_SND_OSSEMUL=y ++CONFIG_SND_MIXER_OSS=y ++CONFIG_SND_PCM_OSS=y ++CONFIG_SND_PCM_OSS_PLUGINS=y ++# CONFIG_SND_DYNAMIC_MINORS is not set ++CONFIG_SND_SUPPORT_OLD_API=y ++CONFIG_SND_VERBOSE_PROCFS=y ++CONFIG_SND_VERBOSE_PRINTK=y ++CONFIG_SND_DEBUG=y ++CONFIG_SND_DEBUG_DETECT=y ++CONFIG_SND_PCM_XRUN_DEBUG=y ++ ++# ++# Generic devices ++# ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_MPU401 is not set ++ ++# ++# ALSA ARM devices ++# ++# CONFIG_SND_OMAP_AIC23 is not set ++# CONFIG_SND_OMAP_TSC2101 is not set ++# CONFIG_SND_SX1 is not set ++# CONFIG_SND_OMAP_TSC2102 is not set ++# CONFIG_SND_OMAP24XX_EAC is not set ++ ++# ++# SPI devices ++# ++ ++# ++# USB devices ++# ++CONFIG_SND_USB_AUDIO=y ++# CONFIG_SND_USB_CAIAQ is not set ++ ++# ++# System on Chip audio support ++# ++CONFIG_SND_SOC=y ++ ++# ++# ALSA SoC audio for Freescale SOCs ++# ++ ++# ++# SoC Audio for the Texas Instruments OMAP ++# ++CONFIG_SND_OMAP_SOC=y ++CONFIG_SND_OMAP_SOC_MCBSP=y ++CONFIG_SND_OMAP_SOC_OMAP3EVM=y ++CONFIG_SND_SOC_TWL4030=y ++ ++# ++# Open Sound System ++# ++CONFIG_SOUND_PRIME=y ++CONFIG_HID_SUPPORT=y ++CONFIG_HID=y ++# CONFIG_HID_DEBUG is not set ++# CONFIG_HIDRAW is not set ++ + # CONFIG_HID_SUPPORT is not set + # CONFIG_USB_SUPPORT is not set + # CONFIG_MMC is not set +diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig +index 0def5ba..8703cea 100644 +--- a/sound/soc/omap/Kconfig ++++ b/sound/soc/omap/Kconfig +@@ -24,4 +24,12 @@ config SND_OMAP_SOC_OMAP3EVM + help + Say Y if you want to add support for SoC audio on the OMAP3 EVM. + ++config SND_OMAP_SOC_OMAP3BEAGLE ++ tristate "SoC Audio support for OMAP3 Beagle" ++ depends on SND_OMAP_SOC && MACH_OMAP3_BEAGLE ++ select SND_OMAP_SOC_MCBSP ++ select SND_SOC_TWL4030 ++ help ++ Say Y if you want to add support for SoC audio on the OMAP3 Beagle. ++ + endmenu +diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile +index 985eddc..638a240 100644 +--- a/sound/soc/omap/Makefile ++++ b/sound/soc/omap/Makefile +@@ -8,7 +8,9 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o + # OMAP Machine Support + snd-soc-n810-objs := n810.o + snd-soc-omap3evm-objs := omap3evm.o ++snd-soc-omap3beagle-objs := omap3beagle.o + + obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o + obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o ++obj-$(CONFIG_SND_OMAP_SOC_OMAP3BEAGLE) += snd-soc-omap3beagle.o + +diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c +new file mode 100644 +index 0000000..336d50a +--- /dev/null ++++ b/sound/soc/omap/omap3beagle.c +@@ -0,0 +1,142 @@ ++/* ++ * omap3beagle.c -- SoC audio for OMAP3 Beagle ++ * ++ * Author: Steve Sakoman <steve@sakoman.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ */ ++ ++#include <linux/clk.h> ++#include <linux/platform_device.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/mcbsp.h> ++ ++#include "omap-mcbsp.h" ++#include "omap-pcm.h" ++#include "../codecs/twl4030.h" ++ ++static int omap3beagle_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; ++ int ret; ++ ++ /* Set codec DAI configuration */ ++ ret = codec_dai->dai_ops.set_fmt(codec_dai, ++ SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) { ++ printk(KERN_INFO "can't set codec DAI configuration\n"); ++ return ret; ++ } ++ ++ /* Set cpu DAI configuration */ ++ ret = cpu_dai->dai_ops.set_fmt(cpu_dai, ++ SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) { ++ printk(KERN_INFO "can't set cpu DAI configuration\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static struct snd_soc_ops omap3beagle_ops = { ++ .hw_params = omap3beagle_hw_params, ++}; ++ ++/* Digital audio interface glue - connects codec <--> CPU */ ++static struct snd_soc_dai_link omap3beagle_dai = { ++ .name = "TWL4030", ++ .stream_name = "TWL4030", ++ .cpu_dai = &omap_mcbsp_dai[0], ++ .codec_dai = &twl4030_dai, ++ .ops = &omap3beagle_ops, ++}; ++ ++/* Audio machine driver */ ++static struct snd_soc_machine snd_soc_machine_omap3beagle = { ++ .name = "omap3beagle", ++ .dai_link = &omap3beagle_dai, ++ .num_links = 1, ++}; ++ ++/* Audio subsystem */ ++static struct snd_soc_device omap3beagle_snd_devdata = { ++ .machine = &snd_soc_machine_omap3beagle, ++ .platform = &omap_soc_platform, ++ .codec_dev = &soc_codec_dev_twl4030, ++}; ++ ++static struct platform_device *omap3beagle_snd_device; ++ ++static int __init omap3beagle_soc_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "OMAP3 Beagle SoC init\n"); ++ if (!machine_is_omap3_beagle()) { ++ printk(KERN_INFO "Not OMAP3 Beagle!\n"); ++ return -ENODEV; ++ } ++ ++ omap3beagle_snd_device = platform_device_alloc("soc-audio", -1); ++ if (!omap3beagle_snd_device) { ++ printk(KERN_INFO "Platform device allocation failed\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata); ++ omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev; ++ *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */ ++ ++ ret = platform_device_add(omap3beagle_snd_device); ++ if (ret) ++ goto err1; ++ ++ return 0; ++ ++err1: ++ printk(KERN_INFO "Unable to add platform device\n"); ++ platform_device_put(omap3beagle_snd_device); ++ ++ return ret; ++} ++ ++static void __exit omap3beagle_soc_exit(void) ++{ ++ printk(KERN_INFO "OMAP3 Beagle SoC exit\n"); ++ platform_device_unregister(omap3beagle_snd_device); ++} ++ ++module_init(omap3beagle_soc_init); ++module_exit(omap3beagle_soc_exit); ++ ++MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>"); ++MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle"); ++MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch b/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch new file mode 100644 index 0000000000..3f6c930cc1 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch @@ -0,0 +1,23 @@ +OMAP2/3 TAP: enable debug messages + +From: Paul Walmsley <paul@pwsan.com> + +This patch causes the OMAP2/3 chip ID code to display the full DIE_ID registers at boot. + +--- + + arch/arm/mach-omap2/id.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c +index c7f9ab7..a154b5e 100644 +--- a/arch/arm/mach-omap2/id.c ++++ b/arch/arm/mach-omap2/id.c +@@ -10,6 +10,7 @@ + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ ++#define DEBUG + + #include <linux/module.h> + #include <linux/kernel.h> diff --git a/packages/linux/linux-omap2-git/beagleboard/serialfix.diff b/packages/linux/linux-omap2-git/beagleboard/serialfix.diff deleted file mode 100644 index 74c2ebaa69..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/serialfix.diff +++ /dev/null @@ -1,18 +0,0 @@ ---- /tmp/pm34xx.c 2008-07-14 18:09:08.000000000 +0200 -+++ git/arch/arm/mach-omap2/pm34xx.c 2008-07-14 18:09:42.453198000 +0200 -@@ -398,13 +398,13 @@ - INT_34XX_PRCM_MPU_IRQ); - goto err1; - } -- -+/* - ret = pwrdm_for_each(pwrdms_setup); - if (ret) { - printk(KERN_ERR "Failed to setup powerdomains\n"); - goto err2; - } -- -+*/ - mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); - if (mpu_pwrdm == NULL) { - printk(KERN_ERR "Failed to get mpu_pwrdm\n"); diff --git a/packages/linux/linux-omap2_git.bb b/packages/linux/linux-omap2_git.bb index 589f1d1458..670cd0f073 100644 --- a/packages/linux/linux-omap2_git.bb +++ b/packages/linux/linux-omap2_git.bb @@ -6,7 +6,7 @@ SRCREV = "d3b3ae0fe6c71641da19c8de466ec366d39847e3" PV = "2.6.26" #PV = "2.6.26+2.6.27-rc1+${PR}+git${SRCREV}" -PR = "r50" +PR = "r54" SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \ file://defconfig" @@ -17,7 +17,9 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \ file://0001-omap3-cpuidle.patch;patch=1 \ file://0002-omap3-cpuidle.patch;patch=1 \ file://timer-suppression.patch;patch=1 \ - file://soc.patch;patch=1 \ + file://ASoC-TWL4030-codec-driver.patch;patch=1 \ + file://ASoC-machine-driver-for-OMAP3-EVM.patch;patch=1 \ + file://ASoC-machine-driver-for_OMAP3-Beagle.patch;patch=1 \ file://16bpp.patch;patch=1 \ file://no-empty-flash-warnings.patch;patch=1 \ file://logo_linux_clut224.ppm \ @@ -29,7 +31,6 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \ file://06-ensure-fclk.diff;patch=1 \ file://07-set-burst-size.diff;patch=1 \ file://cache-display-fix.patch;patch=1 \ - file://serialfix.diff;patch=1 \ file://i2c-omap-race-fix.diff;patch=1 \ file://TWL4030-01.patch;patch=1 \ file://TWL4030-02.patch;patch=1 \ @@ -46,6 +47,11 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \ file://4bitmmc.diff;patch=1 \ file://400khz-i2c.diff;patch=1 \ file://no-cortex-deadlock.patch;patch=1 \ + file://01-gptimer_clear_isrs_on_init;patch=1 \ + file://02-gptimer_use_match_for_tick;patch=1 \ + file://03-gptimer_match_plus_ovf;patch=1 \ + file://04-gptimer_add_debug_to_sysrq_q;patch=1 \ + file://read_die_ids.patch;patch=1 \ " SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \ diff --git a/packages/linux/linux-rp-2.6.26/zaurus-i2c-init.patch b/packages/linux/linux-rp-2.6.26/zaurus-i2c-init.patch index 40214e42b0..e0db0746cd 100644 --- a/packages/linux/linux-rp-2.6.26/zaurus-i2c-init.patch +++ b/packages/linux/linux-rp-2.6.26/zaurus-i2c-init.patch @@ -14,15 +14,42 @@ Stanislav. Reported-by: Stanislav Brabec <utx@penguin.cz> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- + arch/arm/mach-pxa/corgi.c | 2 ++ arch/arm/mach-pxa/poodle.c | 2 ++ arch/arm/mach-pxa/spitz.c | 2 ++ - 2 files changed, 4 insertions(+), 0 deletions(-) + 3 files changed, 6 insertions(+) -diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c -index 39612cf..510018b 100644 ---- a/arch/arm/mach-pxa/poodle.c -+++ b/arch/arm/mach-pxa/poodle.c -@@ -36,6 +36,7 @@ +--- linux-2.6.26.orig/arch/arm/mach-pxa/corgi.c ++++ linux-2.6.26/arch/arm/mach-pxa/corgi.c +@@ -38,10 +38,11 @@ + #include <asm/arch/pxa-regs.h> + #include <asm/arch/pxa2xx-gpio.h> + #include <asm/arch/irda.h> + #include <asm/arch/mmc.h> + #include <asm/arch/udc.h> ++#include <asm/arch/i2c.h> + #include <asm/arch/corgi.h> + #include <asm/arch/sharpsl.h> + + #include <asm/mach/sharpsl_param.h> + #include <asm/hardware/scoop.h> +@@ -529,10 +530,11 @@ static void __init corgi_init(void) + pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN); + + pxa_set_udc_info(&udc_info); + pxa_set_mci_info(&corgi_mci_platform_data); + pxa_set_ficp_info(&corgi_ficp_platform_data); ++ pxa_set_i2c_info(NULL); + + platform_scoop_config = &corgi_pcmcia_config; + + platform_add_devices(devices, ARRAY_SIZE(devices)); + } +--- linux-2.6.26.orig/arch/arm/mach-pxa/poodle.c ++++ linux-2.6.26/arch/arm/mach-pxa/poodle.c +@@ -33,10 +33,11 @@ + + #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/udc.h> @@ -30,7 +57,11 @@ index 39612cf..510018b 100644 #include <asm/arch/irda.h> #include <asm/arch/poodle.h> #include <asm/arch/pxafb.h> -@@ -387,6 +388,7 @@ static void __init poodle_init(void) + #include <asm/arch/sharpsl.h> + #include <asm/arch/ssp.h> +@@ -386,10 +387,11 @@ static void __init poodle_init(void) + pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT); + pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); @@ -38,11 +69,13 @@ index 39612cf..510018b 100644 platform_scoop_config = &poodle_pcmcia_config; -diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c -index 35616a5..e2bde09 100644 ---- a/arch/arm/mach-pxa/spitz.c -+++ b/arch/arm/mach-pxa/spitz.c -@@ -38,6 +38,7 @@ + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if (ret) { +--- linux-2.6.26.orig/arch/arm/mach-pxa/spitz.c ++++ linux-2.6.26/arch/arm/mach-pxa/spitz.c +@@ -36,10 +36,11 @@ + #include <asm/mach/irq.h> + #include <asm/arch/pxa-regs.h> #include <asm/arch/pxa2xx-regs.h> #include <asm/arch/pxa2xx-gpio.h> @@ -50,7 +83,11 @@ index 35616a5..e2bde09 100644 #include <asm/arch/irda.h> #include <asm/arch/mmc.h> #include <asm/arch/ohci.h> -@@ -572,6 +573,7 @@ static void __init common_init(void) + #include <asm/arch/udc.h> + #include <asm/arch/pxafb.h> +@@ -579,10 +580,11 @@ static void __init common_init(void) + pxa_set_mci_info(&spitz_mci_platform_data); + pxa_set_ohci_info(&spitz_ohci_platform_data); pxa_set_ficp_info(&spitz_ficp_platform_data); set_pxa_fb_parent(&spitzssp_device.dev); set_pxa_fb_info(&spitz_pxafb_info); @@ -58,11 +95,5 @@ index 35616a5..e2bde09 100644 } #if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI) --- -1.5.6.2 - - -------------------------------------------------------------------- -List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel -FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php -Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php + static void spitz_bl_set_intensity(int intensity) + { diff --git a/packages/linux/linux-rp_2.6.26.bb b/packages/linux/linux-rp_2.6.26.bb index 012721fd5c..f871bedfee 100644 --- a/packages/linux/linux-rp_2.6.26.bb +++ b/packages/linux/linux-rp_2.6.26.bb @@ -1,6 +1,6 @@ require linux-rp.inc -PR = "r1" +PR = "r2" DEFAULT_PREFERENCE = "-1" DEFAULT_PREFERENCE_qemuarm = "-1" |