From 80278e45aa79cee66596c257c5d3870765233e00 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 10 May 2008 18:00:11 +0000 Subject: Bring Gigabeat S bootloader one step close to a release version. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17442 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx31/gigabeat-s/ata-target.h | 4 ++ .../target/arm/imx31/gigabeat-s/backlight-imx31.c | 4 ++ .../target/arm/imx31/gigabeat-s/backlight-target.h | 8 +++- .../target/arm/imx31/gigabeat-s/button-imx31.c | 38 ++++++++++++++--- .../target/arm/imx31/gigabeat-s/button-target.h | 7 ++++ .../target/arm/imx31/gigabeat-s/mc13783-imx31.c | 48 +++++++++++++++++++--- .../target/arm/imx31/gigabeat-s/system-imx31.c | 1 + firmware/target/arm/imx31/gigabeat-s/usb-target.h | 4 ++ 8 files changed, 102 insertions(+), 12 deletions(-) (limited to 'firmware/target/arm/imx31/gigabeat-s') diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-target.h b/firmware/target/arm/imx31/gigabeat-s/ata-target.h index 6428e9f41f..8f8083dc8d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/ata-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/ata-target.h @@ -19,6 +19,10 @@ #ifndef ATA_TARGET_H #define ATA_TARGET_H +#ifdef BOOTLOADER +#define ATA_DRIVER_CLOSE +#endif + /* Plain C read & write loops */ #define PREFER_C_READING #define PREFER_C_WRITING diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c index 4df9be843c..b35e3c1ad0 100644 --- a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c @@ -22,6 +22,7 @@ #include "mc13783.h" #include "backlight-target.h" +#ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Table that uses combinations of current level and pwm fraction to get * as many uniquely-visible brightness levels as possible. The lowest current * level for any average current is used even though many combinations give @@ -60,6 +61,7 @@ static const struct { 3, 12 }, /* 9 12 7.2 */ /* Anything higher is just too much */ }; +#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ bool _backlight_init(void) { @@ -85,6 +87,7 @@ void _backlight_off(void) mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN); } +#ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Assumes that the backlight has been initialized */ void _backlight_set_brightness(int brightness) { @@ -106,3 +109,4 @@ void _backlight_set_brightness(int brightness) mc13783_write(MC13783_LED_CONTROL2, data); } +#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-target.h b/firmware/target/arm/imx31/gigabeat-s/backlight-target.h index 7c4b2fa0fd..145df0d930 100644 --- a/firmware/target/arm/imx31/gigabeat-s/backlight-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/backlight-target.h @@ -19,11 +19,15 @@ #ifndef BACKLIGHT_TARGET_H #define BACKLIGHT_TARGET_H +#ifdef BOOTLOADER +#define BACKLIGHT_DRIVER_CLOSE +/* Force the whole driver to be built */ +#define BACKLIGHT_FULL_INIT +#endif + bool _backlight_init(void); void _backlight_on(void); void _backlight_off(void); void _backlight_set_brightness(int brightness); -/* true: backlight fades off - false: backlight fades on */ -void __backlight_dim(bool dim); #endif diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c index e80166bca7..746883d010 100644 --- a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c @@ -29,11 +29,16 @@ /* Most code in here is taken from the Linux BSP provided by Freescale * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ - +#ifdef HAVE_HEADPHONE_DETECTION static bool headphones_detect = false; +#endif static uint32_t int_btn = BUTTON_NONE; static bool hold_button = false; +#ifdef BOOTLOADER +static bool initialized = false; +#else static bool hold_button_old = false; +#endif #define _button_hold() (GPIO3_DR & 0x10) static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) @@ -116,6 +121,14 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void) void button_init_device(void) { +#ifdef BOOTLOADER + /* Can be called more than once in the bootloader */ + if (initialized) + return; + + initialized = true; +#endif + /* Enable keypad clock */ imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL); @@ -136,15 +149,26 @@ void button_init_device(void) KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f; /* 5. Clear the KPKD Status Flag and Synchronizer chain. - * 6. Set the KDIE control bit, and set the KRIE control - * bit (to force immediate scan). */ - KPP_KPSR = KPP_KPSR_KRIE | KPP_KPSR_KDIE | KPP_KPSR_KRSS | - KPP_KPSR_KDSC | KPP_KPSR_KPKR | KPP_KPSR_KPKD; + * 6. Set the KDIE control bit bit. */ + KPP_KPSR = KPP_KPSR_KDIE | KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD; /* KPP IRQ at priority 3 */ avic_enable_int(KPP, IRQ, 3, KPP_HANDLER); } +#ifdef BUTTON_DRIVER_CLOSE +void button_close_device(void) +{ + int oldlevel = disable_irq_save(); + + avic_disable_int(KPP); + KPP_KPSR &= ~(KPP_KPSR_KRIE | KPP_KPSR_KDIE); + int_btn = BUTTON_NONE; + + restore_irq(oldlevel); +} +#endif /* BUTTON_DRIVER_CLOSE */ + bool button_hold(void) { return _button_hold(); @@ -155,12 +179,14 @@ int button_read_device(void) /* Simple poll of GPIO status */ hold_button = _button_hold(); +#ifndef BOOTLOADER /* Backlight hold handling */ if (hold_button != hold_button_old) { hold_button_old = hold_button; backlight_hold_changed(hold_button); } +#endif /* Enable the keypad interrupt to cause it to fire if a key is down. * KPP_HANDLER will clear and disable it after the scan. If no key @@ -190,6 +216,7 @@ void button_power_set_state(bool pressed) restore_irq(oldlevel); } +#ifdef HAVE_HEADPHONE_DETECTION /* This is called from the mc13783 interrupt thread */ void set_headphones_inserted(bool inserted) { @@ -203,3 +230,4 @@ bool headphones_inserted(void) { return headphones_detect; } +#endif /* HAVE_HEADPHONE_DETECTION */ diff --git a/firmware/target/arm/imx31/gigabeat-s/button-target.h b/firmware/target/arm/imx31/gigabeat-s/button-target.h index e2f68162f7..61d33f8e70 100644 --- a/firmware/target/arm/imx31/gigabeat-s/button-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/button-target.h @@ -24,8 +24,13 @@ #define HAS_BUTTON_HOLD +#ifdef BOOTLOADER +#define BUTTON_DRIVER_CLOSE +#endif + bool button_hold(void); void button_init_device(void); +void button_close_device(void); int button_read_device(void); void button_power_set_state(bool pressed); void set_headphones_inserted(bool inserted); @@ -48,6 +53,8 @@ bool headphones_inserted(void); #define BUTTON_NEXT (1 << 11) #define BUTTON_POWER (1 << 12) /* Read from PMIC */ +#define BUTTON_MAIN (0x1fff) + #define BUTTON_REMOTE 0 #define POWEROFF_BUTTON BUTTON_POWER diff --git a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c index 3af4b48b66..ddf8d1360f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c @@ -29,6 +29,10 @@ #include "adc-target.h" #include "usb-target.h" +#ifdef BOOTLOADER +#define PMIC_DRIVER_CLOSE +#endif + /* This is all based on communicating with the MC13783 PMU which is on * CSPI2 with the chip select at 0. The LCD controller resides on * CSPI3 cs1, but we have no idea how to communicate to it */ @@ -48,10 +52,14 @@ static struct spi_node mc13783_spi = static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; static const char *mc13783_thread_name = "pmic"; static struct wakeup mc13783_wake; +#ifdef PMIC_DRIVER_CLOSE +static bool pmic_close = false; +static struct thread_entry *mc13783_thread_p = NULL; +#endif /* The next two functions are rather target-specific but they'll just be left * here for the moment */ -static __attribute__((noreturn)) void mc13783_interrupt_thread(void) +static void mc13783_interrupt_thread(void) { const unsigned char status_regs[2] = { @@ -76,7 +84,9 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) value = mc13783_read(MC13783_INTERRUPT_SENSE1); button_power_set_state((value & MC13783_ONOFD1) == 0); +#ifdef HAVE_HEADPHONE_DETECTION set_headphones_inserted((value & MC13783_ONOFD2) == 0); +#endif pending[0] = pending[1] = 0xffffff; mc13783_write_regset(status_regs, pending, 2); @@ -90,6 +100,14 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) { wakeup_wait(&mc13783_wake, TIMEOUT_BLOCK); +#ifdef PMIC_DRIVER_CLOSE + if (pmic_close) + { + gpio_disable_event(MC13783_GPIO_NUM, MC13783_EVENT_ID); + return; + } +#endif + mc13783_read_regset(status_regs, pending, 2); mc13783_write_regset(status_regs, pending, 2); @@ -130,9 +148,10 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) if (pending[1] & MC13783_ONOFD1) button_power_set_state((value & MC13783_ONOFD1) == 0); - +#ifdef HAVE_HEADPHONE_DETECTION if (pending[1] & MC13783_ONOFD2) set_headphones_inserted((value & MC13783_ONOFD2) == 0); +#endif } } } @@ -161,10 +180,29 @@ void mc13783_init(void) MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE); - create_thread(mc13783_interrupt_thread, mc13783_thread_stack, - sizeof(mc13783_thread_stack), 0, mc13783_thread_name - IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); +#ifdef PMIC_DRIVER_CLOSE + mc13783_thread_p = +#endif + create_thread(mc13783_interrupt_thread, + mc13783_thread_stack, sizeof(mc13783_thread_stack), 0, + mc13783_thread_name IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); +} + +#ifdef PMIC_DRIVER_CLOSE +void mc13783_close(void) +{ + struct thread_entry *thread = mc13783_thread_p; + + if (thread == NULL) + return; + + mc13783_thread_p = NULL; + + pmic_close = true; + wakeup_signal(&mc13783_wake); + thread_wait(thread); } +#endif uint32_t mc13783_set(unsigned address, uint32_t bits) { diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 3ec46bae67..1c3abc64fc 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c @@ -117,6 +117,7 @@ void system_prepare_fw_start(void) { disable_interrupt(IRQ_FIQ_STATUS); avic_disable_int(ALL); + mc13783_close(); tick_stop(); } #endif diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-target.h b/firmware/target/arm/imx31/gigabeat-s/usb-target.h index 8c9dcfc65f..7ecd9a7d49 100644 --- a/firmware/target/arm/imx31/gigabeat-s/usb-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/usb-target.h @@ -19,6 +19,10 @@ #ifndef USB_TARGET_H #define USB_TARGET_H +#ifdef BOOTLOADER +#define USB_DRIVER_CLOSE +#endif + void usb_set_status(bool plugged); bool usb_init_device(void); int usb_detect(void); -- cgit v1.2.3