forked from len0rd/rockbox
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
This commit is contained in:
parent
6e812b1d2e
commit
80278e45aa
18 changed files with 425 additions and 155 deletions
|
@ -21,11 +21,15 @@
|
||||||
#include <sprintf.h>
|
#include <sprintf.h>
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "adc.h"
|
||||||
|
#include "powermgmt.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "backlight.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "button.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "usb-target.h"
|
#include "usb-target.h"
|
||||||
|
@ -39,11 +43,15 @@ static const char basedir[] = "/Content/0b00/00/";
|
||||||
/* Can use memory after vector table up to 0x01f00000 */
|
/* Can use memory after vector table up to 0x01f00000 */
|
||||||
static char * const tarbuf = (char *)0x00000040;
|
static char * const tarbuf = (char *)0x00000040;
|
||||||
static const size_t tarbuf_size = 0x01f00000 - 0x00000040;
|
static const size_t tarbuf_size = 0x01f00000 - 0x00000040;
|
||||||
/* Queue to get notifications when in USB mode */
|
/* Firmware data */
|
||||||
static struct event_queue usb_wait_queue;
|
static void * const load_buf = 0x00000000;
|
||||||
|
static const size_t load_buf_size = 0x20000000 - 0x100000;
|
||||||
|
static const void * const start_addr = 0x00000000;
|
||||||
|
|
||||||
static void show_splash(int timeout, const char *msg)
|
static void show_splash(int timeout, const char *msg)
|
||||||
{
|
{
|
||||||
|
backlight_on();
|
||||||
|
reset_screen();
|
||||||
lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
|
lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
|
||||||
(LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
|
(LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
|
||||||
lcd_update();
|
lcd_update();
|
||||||
|
@ -51,6 +59,95 @@ static void show_splash(int timeout, const char *msg)
|
||||||
sleep(timeout);
|
sleep(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pause_if_button_pressed(bool pre_usb)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int button = button_read_device();
|
||||||
|
|
||||||
|
if (pre_usb && !usb_plugged())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Exit if no button or only the menu (settings reset) button */
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case BUTTON_MENU:
|
||||||
|
case BUTTON_NONE:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(HZ/5);
|
||||||
|
|
||||||
|
/* If the disk powers off, the firmware will lock at startup */
|
||||||
|
ata_spin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Handle charging while connected */
|
||||||
|
static void handle_usb(void)
|
||||||
|
{
|
||||||
|
int button;
|
||||||
|
|
||||||
|
/* Check if plugged and pause to look at messages. If the cable was pulled
|
||||||
|
* while waiting, proceed as if it never was plugged. */
|
||||||
|
if (!usb_plugged() || !pause_if_button_pressed(true))
|
||||||
|
{
|
||||||
|
/* Bang on the controller */
|
||||||
|
usb_init_device();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Enter USB mode **/
|
||||||
|
|
||||||
|
/* We need full button and backlight handling now */
|
||||||
|
backlight_init();
|
||||||
|
button_init();
|
||||||
|
|
||||||
|
/* Start the USB driver */
|
||||||
|
usb_init();
|
||||||
|
usb_start_monitoring();
|
||||||
|
|
||||||
|
/* Wait for threads to connect or cable is pulled */
|
||||||
|
show_splash(HZ/2, "Waiting for USB");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
button = button_get_w_tmo(HZ/2);
|
||||||
|
|
||||||
|
if (button == SYS_USB_CONNECTED)
|
||||||
|
break; /* Hit */
|
||||||
|
|
||||||
|
if (!usb_plugged())
|
||||||
|
break; /* Cable pulled */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button == SYS_USB_CONNECTED)
|
||||||
|
{
|
||||||
|
/* Got the message - wait for disconnect */
|
||||||
|
show_splash(0, "Bootloader USB mode");
|
||||||
|
|
||||||
|
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
button = button_get(true);
|
||||||
|
if (button == SYS_USB_DISCONNECTED)
|
||||||
|
{
|
||||||
|
usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put drivers initialized for USB connection into a known state */
|
||||||
|
backlight_on();
|
||||||
|
usb_close();
|
||||||
|
button_close();
|
||||||
|
backlight_close();
|
||||||
|
|
||||||
|
reset_screen();
|
||||||
|
}
|
||||||
|
|
||||||
static void untar(int tar_fd)
|
static void untar(int tar_fd)
|
||||||
{
|
{
|
||||||
char header[TAR_HEADER_SIZE];
|
char header[TAR_HEADER_SIZE];
|
||||||
|
@ -60,13 +157,15 @@ static void untar(int tar_fd)
|
||||||
int ret;
|
int ret;
|
||||||
size_t size = filesize(tar_fd);
|
size_t size = filesize(tar_fd);
|
||||||
|
|
||||||
if (size > tarbuf_size) {
|
if (size > tarbuf_size)
|
||||||
|
{
|
||||||
printf("tar file too large"); /* Paranoid but proper */
|
printf("tar file too large"); /* Paranoid but proper */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read(tar_fd, tarbuf, filesize(tar_fd));
|
ret = read(tar_fd, tarbuf, filesize(tar_fd));
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
|
{
|
||||||
printf("couldn't read tar file (%d)", ret);
|
printf("couldn't read tar file (%d)", ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -131,54 +230,30 @@ static void untar(int tar_fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void)
|
/* Look for a tar file or rockbox binary in the MTP directory */
|
||||||
|
static void handle_untar(void)
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
char tarstring[6];
|
char tarstring[6];
|
||||||
char model[5];
|
char model[5];
|
||||||
|
|
||||||
/* Flush and invalidate all caches (because vectors were written) */
|
|
||||||
invalidate_icache();
|
|
||||||
|
|
||||||
lcd_clear_display();
|
|
||||||
printf("Gigabeat S Rockbox Bootloader v.00000013");
|
|
||||||
system_init();
|
|
||||||
kernel_init();
|
|
||||||
printf("kernel init done");
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
enable_interrupt(IRQ_FIQ_STATUS);
|
|
||||||
|
|
||||||
rc = ata_init();
|
|
||||||
if(rc)
|
|
||||||
{
|
|
||||||
reset_screen();
|
|
||||||
error(EATA, rc);
|
|
||||||
}
|
|
||||||
printf("ata init done");
|
|
||||||
|
|
||||||
disk_init();
|
|
||||||
printf("disk init done");
|
|
||||||
|
|
||||||
rc = disk_mount_all();
|
|
||||||
if (rc<=0)
|
|
||||||
{
|
|
||||||
error(EDISK,rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a tar file */
|
|
||||||
struct dirent_uncached* entry;
|
struct dirent_uncached* entry;
|
||||||
DIR_UNCACHED* dir;
|
DIR_UNCACHED* dir;
|
||||||
int fd;
|
int fd;
|
||||||
|
int rc;
|
||||||
|
|
||||||
dir = opendir_uncached(basedir);
|
dir = opendir_uncached(basedir);
|
||||||
|
|
||||||
while ((entry = readdir_uncached(dir)))
|
while ((entry = readdir_uncached(dir)))
|
||||||
{
|
{
|
||||||
if (*entry->d_name != '.')
|
if (*entry->d_name == '.')
|
||||||
{
|
continue;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s%s", basedir, entry->d_name);
|
snprintf(buf, sizeof(buf), "%s%s", basedir, entry->d_name);
|
||||||
fd = open(buf, O_RDONLY);
|
fd = open(buf, O_RDONLY);
|
||||||
if (fd >= 0)
|
|
||||||
{
|
if (fd < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Check whether the file is a rockbox binary. */
|
/* Check whether the file is a rockbox binary. */
|
||||||
lseek(fd, 4, SEEK_SET);
|
lseek(fd, 4, SEEK_SET);
|
||||||
rc = read(fd, model, 4);
|
rc = read(fd, model, 4);
|
||||||
|
@ -214,70 +289,32 @@ void main(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (usb_plugged())
|
/* Try to load the firmware and run it */
|
||||||
|
static void __attribute__((noreturn)) handle_firmware_load(void)
|
||||||
{
|
{
|
||||||
/* Enter USB mode */
|
int rc = load_firmware(load_buf, "/.rockbox/rockbox.gigabeat",
|
||||||
struct queue_event ev;
|
load_buf_size);
|
||||||
queue_init(&usb_wait_queue, true);
|
|
||||||
|
|
||||||
/* Start the USB driver */
|
|
||||||
usb_init();
|
|
||||||
usb_start_monitoring();
|
|
||||||
|
|
||||||
/* Wait for threads to connect or cable is pulled */
|
|
||||||
reset_screen();
|
|
||||||
show_splash(0, "Waiting for USB");
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
queue_wait_w_tmo(&usb_wait_queue, &ev, HZ/2);
|
|
||||||
|
|
||||||
if (ev.id == SYS_USB_CONNECTED)
|
|
||||||
break; /* Hit */
|
|
||||||
|
|
||||||
if (!usb_plugged())
|
|
||||||
break; /* Cable pulled */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.id == SYS_USB_CONNECTED)
|
|
||||||
{
|
|
||||||
/* Got the message - wait for disconnect */
|
|
||||||
reset_screen();
|
|
||||||
show_splash(0, "Bootloader USB mode");
|
|
||||||
|
|
||||||
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
|
||||||
usb_wait_for_disconnect(&usb_wait_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No more monitoring */
|
|
||||||
usb_stop_monitoring();
|
|
||||||
|
|
||||||
reset_screen();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bang on the controller */
|
|
||||||
usb_init_device();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *loadbuffer = (unsigned char *)0x0;
|
|
||||||
int buffer_size = 31*1024*1024;
|
|
||||||
|
|
||||||
rc = load_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size);
|
|
||||||
if(rc < 0)
|
if(rc < 0)
|
||||||
error(EBOOTFILE, rc);
|
error(EBOOTFILE, rc);
|
||||||
|
|
||||||
|
/* Pause to look at messages */
|
||||||
|
pause_if_button_pressed(false);
|
||||||
|
|
||||||
|
/* Put drivers into a known state */
|
||||||
|
button_close_device();
|
||||||
|
ata_close();
|
||||||
system_prepare_fw_start();
|
system_prepare_fw_start();
|
||||||
|
|
||||||
if (rc == EOK)
|
if (rc == EOK)
|
||||||
{
|
{
|
||||||
invalidate_icache();
|
invalidate_icache();
|
||||||
asm volatile ("bx %0": : "r"(loadbuffer));
|
asm volatile ("bx %0": : "r"(start_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Halt */
|
/* Halt */
|
||||||
|
@ -285,3 +322,55 @@ void main(void)
|
||||||
core_idle();
|
core_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_battery(void)
|
||||||
|
{
|
||||||
|
int batt = battery_adc_voltage();
|
||||||
|
printf("Battery: %d.%03d V", batt / 1000, batt % 1000);
|
||||||
|
/* TODO: warn on low battery or shut down */
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Flush and invalidate all caches (because vectors were written) */
|
||||||
|
invalidate_icache();
|
||||||
|
|
||||||
|
lcd_clear_display();
|
||||||
|
printf("Gigabeat S Rockbox Bootloader");
|
||||||
|
printf("Version %s", version);
|
||||||
|
system_init();
|
||||||
|
kernel_init();
|
||||||
|
|
||||||
|
enable_interrupt(IRQ_FIQ_STATUS);
|
||||||
|
|
||||||
|
/* Initialize KPP so we can poll the button states */
|
||||||
|
button_init_device();
|
||||||
|
|
||||||
|
adc_init();
|
||||||
|
|
||||||
|
check_battery();
|
||||||
|
|
||||||
|
rc = ata_init();
|
||||||
|
if(rc)
|
||||||
|
{
|
||||||
|
reset_screen();
|
||||||
|
error(EATA, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_init();
|
||||||
|
|
||||||
|
rc = disk_mount_all();
|
||||||
|
if (rc<=0)
|
||||||
|
{
|
||||||
|
error(EDISK,rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Init complete");
|
||||||
|
|
||||||
|
/* Do USB first since a tar or binary could be added to the MTP directory
|
||||||
|
* at the time and we can untar or move after unplugging. */
|
||||||
|
handle_usb();
|
||||||
|
handle_untar();
|
||||||
|
handle_firmware_load(); /* No return */
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,11 @@
|
||||||
#include "backlight-target.h"
|
#include "backlight-target.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOTLOADER)
|
||||||
|
/* The whole driver should be built */
|
||||||
|
#define BACKLIGHT_FULL_INIT
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SIMULATOR
|
#ifdef SIMULATOR
|
||||||
/* TODO: find a better way to do it but we need a kernel thread somewhere to
|
/* TODO: find a better way to do it but we need a kernel thread somewhere to
|
||||||
handle this */
|
handle this */
|
||||||
|
@ -85,7 +90,7 @@ static inline void _remote_backlight_off(void)
|
||||||
|
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
|
|
||||||
#if defined(HAVE_BACKLIGHT) && !defined(BOOTLOADER)
|
#if defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BACKLIGHT_ON,
|
BACKLIGHT_ON,
|
||||||
|
@ -104,12 +109,18 @@ enum {
|
||||||
BUTTON_LIGHT_ON,
|
BUTTON_LIGHT_ON,
|
||||||
BUTTON_LIGHT_OFF,
|
BUTTON_LIGHT_OFF,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||||
|
BACKLIGHT_QUIT,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void backlight_thread(void);
|
static void backlight_thread(void);
|
||||||
static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
|
static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
|
||||||
static const char backlight_thread_name[] = "backlight";
|
static const char backlight_thread_name[] = "backlight";
|
||||||
static struct event_queue backlight_queue;
|
static struct event_queue backlight_queue;
|
||||||
|
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||||
|
static struct thread_entry *backlight_thread_p = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int backlight_timer SHAREDBSS_ATTR;
|
static int backlight_timer SHAREDBSS_ATTR;
|
||||||
static int backlight_timeout SHAREDBSS_ATTR;
|
static int backlight_timeout SHAREDBSS_ATTR;
|
||||||
|
@ -158,7 +169,7 @@ void buttonlight_set_timeout(int value)
|
||||||
buttonlight_update_state();
|
buttonlight_update_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* HAVE_BUTTON_LIGHT */
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_LCD
|
#ifdef HAVE_REMOTE_LCD
|
||||||
static int remote_backlight_timer;
|
static int remote_backlight_timer;
|
||||||
|
@ -170,7 +181,7 @@ static int remote_backlight_timeout_plugged = 5*HZ;
|
||||||
#ifdef HAS_REMOTE_BUTTON_HOLD
|
#ifdef HAS_REMOTE_BUTTON_HOLD
|
||||||
static int remote_backlight_on_button_hold = 0;
|
static int remote_backlight_on_button_hold = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif /* HAVE_REMOTE_LCD */
|
||||||
|
|
||||||
#ifdef HAVE_LCD_SLEEP
|
#ifdef HAVE_LCD_SLEEP
|
||||||
const signed char lcd_sleep_timeout_value[10] =
|
const signed char lcd_sleep_timeout_value[10] =
|
||||||
|
@ -494,6 +505,12 @@ void backlight_thread(void)
|
||||||
case SYS_USB_DISCONNECTED:
|
case SYS_USB_DISCONNECTED:
|
||||||
usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
|
usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||||
|
/* Get out of here */
|
||||||
|
case BACKLIGHT_QUIT:
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (locked)
|
if (locked)
|
||||||
continue;
|
continue;
|
||||||
|
@ -613,7 +630,9 @@ void backlight_init(void)
|
||||||
/* Leave all lights as set by the bootloader here. The settings load will
|
/* Leave all lights as set by the bootloader here. The settings load will
|
||||||
* call the appropriate backlight_set_*() functions, only changing light
|
* call the appropriate backlight_set_*() functions, only changing light
|
||||||
* status if necessary. */
|
* status if necessary. */
|
||||||
|
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||||
|
backlight_thread_p =
|
||||||
|
#endif
|
||||||
create_thread(backlight_thread, backlight_stack,
|
create_thread(backlight_thread, backlight_stack,
|
||||||
sizeof(backlight_stack), 0, backlight_thread_name
|
sizeof(backlight_stack), 0, backlight_thread_name
|
||||||
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||||
|
@ -621,6 +640,22 @@ void backlight_init(void)
|
||||||
tick_add_task(backlight_tick);
|
tick_add_task(backlight_tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||||
|
void backlight_close(void)
|
||||||
|
{
|
||||||
|
struct thread_entry *thread = backlight_thread_p;
|
||||||
|
|
||||||
|
/* Wait for thread to exit */
|
||||||
|
if (thread == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
backlight_thread_p = NULL;
|
||||||
|
|
||||||
|
queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
|
||||||
|
thread_wait(thread);
|
||||||
|
}
|
||||||
|
#endif /* BACKLIGHT_DRIVER_CLOSE */
|
||||||
|
|
||||||
void backlight_on(void)
|
void backlight_on(void)
|
||||||
{
|
{
|
||||||
queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
|
queue_remove_from_head(&backlight_queue, BACKLIGHT_ON);
|
||||||
|
@ -788,10 +823,10 @@ void buttonlight_set_brightness(int val)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
|
#endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
|
||||||
|
|
||||||
#else /* !defined(HAVE_BACKLIGHT) || defined(BOOTLOADER)
|
#else /* !defined(HAVE_BACKLIGHT) || !defined(BACKLIGHT_FULL_INIT)
|
||||||
-- no backlight, empty dummy functions */
|
-- no backlight, empty dummy functions */
|
||||||
|
|
||||||
#if defined(BOOTLOADER) && defined(HAVE_BACKLIGHT)
|
#if defined(HAVE_BACKLIGHT) && !defined(BACKLIGHT_FULL_INIT)
|
||||||
void backlight_init(void)
|
void backlight_init(void)
|
||||||
{
|
{
|
||||||
(void)_backlight_init();
|
(void)_backlight_init();
|
||||||
|
@ -826,4 +861,4 @@ void backlight_set_brightness(int val) { (void)val; }
|
||||||
#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
|
#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
|
||||||
void buttonlight_set_brightness(int val) { (void)val; }
|
void buttonlight_set_brightness(int val) { (void)val; }
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(HAVE_BACKLIGHT) && !defined(BOOTLOADER) */
|
#endif /* defined(HAVE_BACKLIGHT) && defined(BACKLIGHT_FULL_INIT) */
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#define CMD_SECURITY_FREEZE_LOCK 0xF5
|
#define CMD_SECURITY_FREEZE_LOCK 0xF5
|
||||||
|
|
||||||
#define Q_SLEEP 0
|
#define Q_SLEEP 0
|
||||||
|
#define Q_CLOSE 1
|
||||||
|
|
||||||
#define READ_TIMEOUT 5*HZ
|
#define READ_TIMEOUT 5*HZ
|
||||||
|
|
||||||
|
@ -66,6 +67,10 @@
|
||||||
#define ATA_POWER_OFF_TIMEOUT 2*HZ
|
#define ATA_POWER_OFF_TIMEOUT 2*HZ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ATA_DRIVER_CLOSE
|
||||||
|
static struct thread_entry *ata_thread_p = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64
|
#if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64
|
||||||
/* Hack - what's the deal with 5g? */
|
/* Hack - what's the deal with 5g? */
|
||||||
struct ata_lock
|
struct ata_lock
|
||||||
|
@ -941,6 +946,11 @@ static void ata_thread(void)
|
||||||
call_ata_idle_notifys(false);
|
call_ata_idle_notifys(false);
|
||||||
last_disk_activity = current_tick - sleep_timeout + (HZ/2);
|
last_disk_activity = current_tick - sleep_timeout + (HZ/2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef ATA_DRIVER_CLOSE
|
||||||
|
case Q_CLOSE:
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1307,6 +1317,9 @@ int ata_init(void)
|
||||||
mutex_lock(&ata_mtx); /* Balance unlock below */
|
mutex_lock(&ata_mtx); /* Balance unlock below */
|
||||||
|
|
||||||
last_disk_activity = current_tick;
|
last_disk_activity = current_tick;
|
||||||
|
#ifdef ATA_DRIVER_CLOSE
|
||||||
|
ata_thread_p =
|
||||||
|
#endif
|
||||||
create_thread(ata_thread, ata_stack,
|
create_thread(ata_thread, ata_stack,
|
||||||
sizeof(ata_stack), 0, ata_thread_name
|
sizeof(ata_stack), 0, ata_thread_name
|
||||||
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||||
|
@ -1322,6 +1335,21 @@ int ata_init(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ATA_DRIVER_CLOSE
|
||||||
|
void ata_close(void)
|
||||||
|
{
|
||||||
|
struct thread_entry *thread = ata_thread_p;
|
||||||
|
|
||||||
|
if (thread == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ata_thread_p = NULL;
|
||||||
|
|
||||||
|
queue_post(&ata_queue, Q_CLOSE, 0);
|
||||||
|
thread_wait(thread);
|
||||||
|
}
|
||||||
|
#endif /* ATA_DRIVER_CLOSE */
|
||||||
|
|
||||||
#if (CONFIG_LED == LED_REAL)
|
#if (CONFIG_LED == LED_REAL)
|
||||||
void ata_set_led_enabled(bool enabled)
|
void ata_set_led_enabled(bool enabled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -410,6 +410,13 @@ void button_init(void)
|
||||||
tick_add_task(button_tick);
|
tick_add_task(button_tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUTTON_DRIVER_CLOSE
|
||||||
|
void button_close(void)
|
||||||
|
{
|
||||||
|
tick_remove_task(button_tick);
|
||||||
|
}
|
||||||
|
#endif /* BUTTON_DRIVER_CLOSE */
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */
|
#ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */
|
||||||
/*
|
/*
|
||||||
* helper function to swap LEFT/RIGHT, UP/DOWN (if present), and F1/F3 (Recorder)
|
* helper function to swap LEFT/RIGHT, UP/DOWN (if present), and F1/F3 (Recorder)
|
||||||
|
|
|
@ -48,6 +48,7 @@ extern bool ata_disk_is_active(void);
|
||||||
extern int ata_hard_reset(void);
|
extern int ata_hard_reset(void);
|
||||||
extern int ata_soft_reset(void);
|
extern int ata_soft_reset(void);
|
||||||
extern int ata_init(void);
|
extern int ata_init(void);
|
||||||
|
extern void ata_close(void);
|
||||||
extern int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf);
|
extern int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf);
|
||||||
extern int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf);
|
extern int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf);
|
||||||
extern void ata_spin(void);
|
extern void ata_spin(void);
|
||||||
|
|
|
@ -28,6 +28,7 @@ void backlight_set_timeout(int value);
|
||||||
|
|
||||||
#ifdef HAVE_BACKLIGHT
|
#ifdef HAVE_BACKLIGHT
|
||||||
void backlight_init(void);
|
void backlight_init(void);
|
||||||
|
void backlight_close(void);
|
||||||
|
|
||||||
int backlight_get_current_timeout(void);
|
int backlight_get_current_timeout(void);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
extern struct event_queue button_queue;
|
extern struct event_queue button_queue;
|
||||||
|
|
||||||
void button_init (void);
|
void button_init (void);
|
||||||
|
void button_close(void);
|
||||||
int button_queue_count(void);
|
int button_queue_count(void);
|
||||||
long button_get (bool block);
|
long button_get (bool block);
|
||||||
long button_get_w_tmo(int ticks);
|
long button_get_w_tmo(int ticks);
|
||||||
|
|
|
@ -54,15 +54,6 @@
|
||||||
/* Define this for LCD backlight available */
|
/* Define this for LCD backlight available */
|
||||||
#define HAVE_BACKLIGHT
|
#define HAVE_BACKLIGHT
|
||||||
|
|
||||||
#define HAVE_LCD_ENABLE
|
|
||||||
|
|
||||||
#define HAVE_BACKLIGHT_BRIGHTNESS
|
|
||||||
|
|
||||||
/* Main LCD backlight brightness range and defaults */
|
|
||||||
#define MIN_BRIGHTNESS_SETTING 0
|
|
||||||
#define MAX_BRIGHTNESS_SETTING 24
|
|
||||||
#define DEFAULT_BRIGHTNESS_SETTING 12
|
|
||||||
|
|
||||||
/* Define this if you have a software controlled poweroff */
|
/* Define this if you have a software controlled poweroff */
|
||||||
#define HAVE_SW_POWEROFF
|
#define HAVE_SW_POWEROFF
|
||||||
|
|
||||||
|
@ -78,7 +69,20 @@
|
||||||
#define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | \
|
#define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | \
|
||||||
SAMPR_CAP_11)
|
SAMPR_CAP_11)
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
|
/* Not for bootloader */
|
||||||
|
#define HAVE_LCD_ENABLE
|
||||||
|
|
||||||
|
#define HAVE_BACKLIGHT_BRIGHTNESS
|
||||||
|
|
||||||
|
/* Main LCD backlight brightness range and defaults */
|
||||||
|
#define MIN_BRIGHTNESS_SETTING 0
|
||||||
|
#define MAX_BRIGHTNESS_SETTING 24
|
||||||
|
#define DEFAULT_BRIGHTNESS_SETTING 12
|
||||||
|
|
||||||
|
|
||||||
#define HAVE_HEADPHONE_DETECTION
|
#define HAVE_HEADPHONE_DETECTION
|
||||||
|
#endif /* BOOTLOADER */
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ enum {
|
||||||
USB_TRANSFER_COMPLETION,
|
USB_TRANSFER_COMPLETION,
|
||||||
USB_REQUEST_DISK,
|
USB_REQUEST_DISK,
|
||||||
USB_RELEASE_DISK,
|
USB_RELEASE_DISK,
|
||||||
USB_REQUEST_REBOOT
|
USB_REQUEST_REBOOT,
|
||||||
|
USB_QUIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ struct usb_transfer_completion_event_data
|
||||||
void usb_init(void);
|
void usb_init(void);
|
||||||
void usb_enable(bool on);
|
void usb_enable(bool on);
|
||||||
void usb_start_monitoring(void);
|
void usb_start_monitoring(void);
|
||||||
void usb_stop_monitoring(void);
|
void usb_close(void);
|
||||||
void usb_acknowledge(long id);
|
void usb_acknowledge(long id);
|
||||||
void usb_wait_for_disconnect(struct event_queue *q);
|
void usb_wait_for_disconnect(struct event_queue *q);
|
||||||
int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks);
|
int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks);
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#ifndef ATA_TARGET_H
|
#ifndef ATA_TARGET_H
|
||||||
#define ATA_TARGET_H
|
#define ATA_TARGET_H
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
#define ATA_DRIVER_CLOSE
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Plain C read & write loops */
|
/* Plain C read & write loops */
|
||||||
#define PREFER_C_READING
|
#define PREFER_C_READING
|
||||||
#define PREFER_C_WRITING
|
#define PREFER_C_WRITING
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "mc13783.h"
|
#include "mc13783.h"
|
||||||
#include "backlight-target.h"
|
#include "backlight-target.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
|
||||||
/* Table that uses combinations of current level and pwm fraction to get
|
/* Table that uses combinations of current level and pwm fraction to get
|
||||||
* as many uniquely-visible brightness levels as possible. The lowest current
|
* as many uniquely-visible brightness levels as possible. The lowest current
|
||||||
* level for any average current is used even though many combinations give
|
* 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 */
|
{ 3, 12 }, /* 9 12 7.2 */
|
||||||
/* Anything higher is just too much */
|
/* Anything higher is just too much */
|
||||||
};
|
};
|
||||||
|
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
|
||||||
|
|
||||||
bool _backlight_init(void)
|
bool _backlight_init(void)
|
||||||
{
|
{
|
||||||
|
@ -85,6 +87,7 @@ void _backlight_off(void)
|
||||||
mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN);
|
mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
|
||||||
/* Assumes that the backlight has been initialized */
|
/* Assumes that the backlight has been initialized */
|
||||||
void _backlight_set_brightness(int brightness)
|
void _backlight_set_brightness(int brightness)
|
||||||
{
|
{
|
||||||
|
@ -106,3 +109,4 @@ void _backlight_set_brightness(int brightness)
|
||||||
|
|
||||||
mc13783_write(MC13783_LED_CONTROL2, data);
|
mc13783_write(MC13783_LED_CONTROL2, data);
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
|
||||||
|
|
|
@ -19,11 +19,15 @@
|
||||||
#ifndef BACKLIGHT_TARGET_H
|
#ifndef BACKLIGHT_TARGET_H
|
||||||
#define 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);
|
bool _backlight_init(void);
|
||||||
void _backlight_on(void);
|
void _backlight_on(void);
|
||||||
void _backlight_off(void);
|
void _backlight_off(void);
|
||||||
void _backlight_set_brightness(int brightness);
|
void _backlight_set_brightness(int brightness);
|
||||||
|
|
||||||
/* true: backlight fades off - false: backlight fades on */
|
|
||||||
void __backlight_dim(bool dim);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,11 +29,16 @@
|
||||||
|
|
||||||
/* Most code in here is taken from the Linux BSP provided by Freescale
|
/* Most code in here is taken from the Linux BSP provided by Freescale
|
||||||
* Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */
|
* Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */
|
||||||
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
static bool headphones_detect = false;
|
static bool headphones_detect = false;
|
||||||
|
#endif
|
||||||
static uint32_t int_btn = BUTTON_NONE;
|
static uint32_t int_btn = BUTTON_NONE;
|
||||||
static bool hold_button = false;
|
static bool hold_button = false;
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
static bool initialized = false;
|
||||||
|
#else
|
||||||
static bool hold_button_old = false;
|
static bool hold_button_old = false;
|
||||||
|
#endif
|
||||||
#define _button_hold() (GPIO3_DR & 0x10)
|
#define _button_hold() (GPIO3_DR & 0x10)
|
||||||
|
|
||||||
static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
|
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)
|
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 */
|
/* Enable keypad clock */
|
||||||
imx31_clkctl_module_clock_gating(CG_KPP, CGM_ON_ALL);
|
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;
|
KPP_KDDR = (KPP_KDDR | (0x7 << 8)) & ~0x1f;
|
||||||
|
|
||||||
/* 5. Clear the KPKD Status Flag and Synchronizer chain.
|
/* 5. Clear the KPKD Status Flag and Synchronizer chain.
|
||||||
* 6. Set the KDIE control bit, and set the KRIE control
|
* 6. Set the KDIE control bit bit. */
|
||||||
* bit (to force immediate scan). */
|
KPP_KPSR = KPP_KPSR_KDIE | KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKD;
|
||||||
KPP_KPSR = KPP_KPSR_KRIE | KPP_KPSR_KDIE | KPP_KPSR_KRSS |
|
|
||||||
KPP_KPSR_KDSC | KPP_KPSR_KPKR | KPP_KPSR_KPKD;
|
|
||||||
|
|
||||||
/* KPP IRQ at priority 3 */
|
/* KPP IRQ at priority 3 */
|
||||||
avic_enable_int(KPP, IRQ, 3, KPP_HANDLER);
|
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)
|
bool button_hold(void)
|
||||||
{
|
{
|
||||||
return _button_hold();
|
return _button_hold();
|
||||||
|
@ -155,12 +179,14 @@ int button_read_device(void)
|
||||||
/* Simple poll of GPIO status */
|
/* Simple poll of GPIO status */
|
||||||
hold_button = _button_hold();
|
hold_button = _button_hold();
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
/* Backlight hold handling */
|
/* Backlight hold handling */
|
||||||
if (hold_button != hold_button_old)
|
if (hold_button != hold_button_old)
|
||||||
{
|
{
|
||||||
hold_button_old = hold_button;
|
hold_button_old = hold_button;
|
||||||
backlight_hold_changed(hold_button);
|
backlight_hold_changed(hold_button);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable the keypad interrupt to cause it to fire if a key is down.
|
/* 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
|
* 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);
|
restore_irq(oldlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
/* This is called from the mc13783 interrupt thread */
|
/* This is called from the mc13783 interrupt thread */
|
||||||
void set_headphones_inserted(bool inserted)
|
void set_headphones_inserted(bool inserted)
|
||||||
{
|
{
|
||||||
|
@ -203,3 +230,4 @@ bool headphones_inserted(void)
|
||||||
{
|
{
|
||||||
return headphones_detect;
|
return headphones_detect;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_HEADPHONE_DETECTION */
|
||||||
|
|
|
@ -24,8 +24,13 @@
|
||||||
|
|
||||||
#define HAS_BUTTON_HOLD
|
#define HAS_BUTTON_HOLD
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
#define BUTTON_DRIVER_CLOSE
|
||||||
|
#endif
|
||||||
|
|
||||||
bool button_hold(void);
|
bool button_hold(void);
|
||||||
void button_init_device(void);
|
void button_init_device(void);
|
||||||
|
void button_close_device(void);
|
||||||
int button_read_device(void);
|
int button_read_device(void);
|
||||||
void button_power_set_state(bool pressed);
|
void button_power_set_state(bool pressed);
|
||||||
void set_headphones_inserted(bool inserted);
|
void set_headphones_inserted(bool inserted);
|
||||||
|
@ -48,6 +53,8 @@ bool headphones_inserted(void);
|
||||||
#define BUTTON_NEXT (1 << 11)
|
#define BUTTON_NEXT (1 << 11)
|
||||||
#define BUTTON_POWER (1 << 12) /* Read from PMIC */
|
#define BUTTON_POWER (1 << 12) /* Read from PMIC */
|
||||||
|
|
||||||
|
#define BUTTON_MAIN (0x1fff)
|
||||||
|
|
||||||
#define BUTTON_REMOTE 0
|
#define BUTTON_REMOTE 0
|
||||||
|
|
||||||
#define POWEROFF_BUTTON BUTTON_POWER
|
#define POWEROFF_BUTTON BUTTON_POWER
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "adc-target.h"
|
#include "adc-target.h"
|
||||||
#include "usb-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
|
/* 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
|
* CSPI2 with the chip select at 0. The LCD controller resides on
|
||||||
* CSPI3 cs1, but we have no idea how to communicate to it */
|
* 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 int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)];
|
||||||
static const char *mc13783_thread_name = "pmic";
|
static const char *mc13783_thread_name = "pmic";
|
||||||
static struct wakeup mc13783_wake;
|
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
|
/* The next two functions are rather target-specific but they'll just be left
|
||||||
* here for the moment */
|
* here for the moment */
|
||||||
static __attribute__((noreturn)) void mc13783_interrupt_thread(void)
|
static void mc13783_interrupt_thread(void)
|
||||||
{
|
{
|
||||||
const unsigned char status_regs[2] =
|
const unsigned char status_regs[2] =
|
||||||
{
|
{
|
||||||
|
@ -76,7 +84,9 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void)
|
||||||
|
|
||||||
value = mc13783_read(MC13783_INTERRUPT_SENSE1);
|
value = mc13783_read(MC13783_INTERRUPT_SENSE1);
|
||||||
button_power_set_state((value & MC13783_ONOFD1) == 0);
|
button_power_set_state((value & MC13783_ONOFD1) == 0);
|
||||||
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
set_headphones_inserted((value & MC13783_ONOFD2) == 0);
|
set_headphones_inserted((value & MC13783_ONOFD2) == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
pending[0] = pending[1] = 0xffffff;
|
pending[0] = pending[1] = 0xffffff;
|
||||||
mc13783_write_regset(status_regs, pending, 2);
|
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);
|
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_read_regset(status_regs, pending, 2);
|
||||||
mc13783_write_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)
|
if (pending[1] & MC13783_ONOFD1)
|
||||||
button_power_set_state((value & MC13783_ONOFD1) == 0);
|
button_power_set_state((value & MC13783_ONOFD1) == 0);
|
||||||
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
if (pending[1] & MC13783_ONOFD2)
|
if (pending[1] & MC13783_ONOFD2)
|
||||||
set_headphones_inserted((value & MC13783_ONOFD2) == 0);
|
set_headphones_inserted((value & MC13783_ONOFD2) == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,11 +180,30 @@ void mc13783_init(void)
|
||||||
|
|
||||||
MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
|
MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
|
||||||
|
|
||||||
create_thread(mc13783_interrupt_thread, mc13783_thread_stack,
|
#ifdef PMIC_DRIVER_CLOSE
|
||||||
sizeof(mc13783_thread_stack), 0, mc13783_thread_name
|
mc13783_thread_p =
|
||||||
IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU));
|
#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)
|
uint32_t mc13783_set(unsigned address, uint32_t bits)
|
||||||
{
|
{
|
||||||
spi_lock(&mc13783_spi);
|
spi_lock(&mc13783_spi);
|
||||||
|
|
|
@ -117,6 +117,7 @@ void system_prepare_fw_start(void)
|
||||||
{
|
{
|
||||||
disable_interrupt(IRQ_FIQ_STATUS);
|
disable_interrupt(IRQ_FIQ_STATUS);
|
||||||
avic_disable_int(ALL);
|
avic_disable_int(ALL);
|
||||||
|
mc13783_close();
|
||||||
tick_stop();
|
tick_stop();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#ifndef USB_TARGET_H
|
#ifndef USB_TARGET_H
|
||||||
#define USB_TARGET_H
|
#define USB_TARGET_H
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
#define USB_DRIVER_CLOSE
|
||||||
|
#endif
|
||||||
|
|
||||||
void usb_set_status(bool plugged);
|
void usb_set_status(bool plugged);
|
||||||
bool usb_init_device(void);
|
bool usb_init_device(void);
|
||||||
int usb_detect(void);
|
int usb_detect(void);
|
||||||
|
|
|
@ -172,6 +172,10 @@ static void usb_thread(void)
|
||||||
queue_wait(&usb_queue, &ev);
|
queue_wait(&usb_queue, &ev);
|
||||||
switch(ev.id)
|
switch(ev.id)
|
||||||
{
|
{
|
||||||
|
#ifdef USB_DRIVER_CLOSE
|
||||||
|
case USB_QUIT:
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_USBSTACK
|
#ifdef HAVE_USBSTACK
|
||||||
case USB_TRANSFER_COMPLETION:
|
case USB_TRANSFER_COMPLETION:
|
||||||
usb_core_handle_transfer_completion((struct usb_transfer_completion_event_data*)ev.data);
|
usb_core_handle_transfer_completion((struct usb_transfer_completion_event_data*)ev.data);
|
||||||
|
@ -531,13 +535,22 @@ void usb_start_monitoring(void)
|
||||||
usb_monitor_enabled = true;
|
usb_monitor_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOSHIBA_GIGABEAT_S
|
#ifdef USB_DRIVER_CLOSE
|
||||||
void usb_stop_monitoring(void)
|
void usb_close(void)
|
||||||
{
|
{
|
||||||
|
struct thread_entry *thread = usb_thread_entry;
|
||||||
|
usb_thread_entry = NULL;
|
||||||
|
|
||||||
|
if (thread == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
tick_remove_task(usb_tick);
|
tick_remove_task(usb_tick);
|
||||||
usb_monitor_enabled = false;
|
usb_monitor_enabled = false;
|
||||||
|
|
||||||
|
queue_post(&usb_queue, USB_QUIT, 0);
|
||||||
|
thread_wait(thread);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* USB_DRIVER_CLOSE */
|
||||||
|
|
||||||
bool usb_inserted(void)
|
bool usb_inserted(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue