From b2e50906a4af3176d03dff98af4a260709bdad96 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Tue, 23 Jan 2007 13:40:44 +0000 Subject: Settings are now stored in /.rockbox/config.cfg instead of the hidden sector. (FS #6557) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12093 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 1 + apps/filetree.c | 2 +- apps/main.c | 3 - apps/recorder/radio.h | 1 - apps/settings.c | 1716 ++++++++------------------------------------ apps/settings.h | 6 +- apps/settings_list.c | 608 ++++++++++++++++ apps/settings_list.h | 100 +++ apps/settings_menu.c | 1 + firmware/drivers/ata.c | 2 +- firmware/drivers/ata_mmc.c | 4 +- 11 files changed, 1028 insertions(+), 1416 deletions(-) create mode 100644 apps/settings_list.c create mode 100644 apps/settings_list.h diff --git a/apps/SOURCES b/apps/SOURCES index 20707323f2..2304ee7031 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -20,6 +20,7 @@ playlist_viewer.c plugin.c screens.c settings.c +settings_list.c settings_menu.c sound_menu.c status.c diff --git a/apps/filetree.c b/apps/filetree.c index f10c02b449..cd020d0a51 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -486,7 +486,7 @@ int ft_enter(struct tree_context* c) case TREE_ATTR_CFG: gui_syncsplash(0, true, str(LANG_WAIT)); - if (!settings_load_config(buf)) + if (!settings_load_config(buf,true)) break; gui_syncsplash(HZ, true, str(LANG_SETTINGS_LOADED)); break; diff --git a/apps/main.c b/apps/main.c index 1361b81744..5137ff9fa6 100644 --- a/apps/main.c +++ b/apps/main.c @@ -247,7 +247,6 @@ static void init(void) screen_access_init(); gui_syncstatusbar_init(&statusbars); settings_reset(); - settings_calc_config_sector(); settings_load(SETTINGS_ALL); gui_sync_wps_init(); settings_apply(); @@ -447,8 +446,6 @@ static void init(void) } } - settings_calc_config_sector(); - #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IRIVER_H10_PAD) || (CONFIG_KEYPAD == GIGABEAT_PAD) #ifdef SETTINGS_RESET diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index 439061e579..a4f9f1a978 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -18,7 +18,6 @@ ****************************************************************************/ #ifndef RADIO_H #define RADIO_H -#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets" #ifndef FMRADIO_H #include "fmradio.h" diff --git a/apps/settings.c b/apps/settings.c index 4ef2f1486e..01ede41b3e 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -25,6 +25,7 @@ #include "kernel.h" #include "thread.h" #include "action.h" +#include "crc32.h" #include "settings.h" #include "disk.h" #include "panic.h" @@ -72,6 +73,7 @@ #include "statusbar.h" #include "splash.h" #include "list.h" +#include "settings_list.h" #if LCD_DEPTH > 1 #include "backdrop.h" #endif @@ -100,9 +102,7 @@ const char rec_base_directory[] = REC_BASE_DIR; #include "eq_menu.h" #endif -#define CONFIG_BLOCK_VERSION 59 -#define CONFIG_BLOCK_SIZE 512 -#define RTC_BLOCK_SIZE 44 +#define NVRAM_BLOCK_SIZE 44 #ifdef HAVE_LCD_BITMAP #define MAX_LINES 10 @@ -115,644 +115,115 @@ const char rec_base_directory[] = REC_BASE_DIR; #endif long lasttime = 0; -static long config_sector = 0; /* mark uninitialized */ -static unsigned char config_block[CONFIG_BLOCK_SIZE]; - -/* descriptor for a configuration value */ -/* (watch the struct packing and member sizes to keep this small) */ -struct bit_entry -{ - /* how many bits within the bitfield (1-32), MSB set if value is signed */ - unsigned char bit_size; /* min 6+1 bit */ - /* how many bytes in the global_settings struct (1,2,4) */ - unsigned char byte_size; /* min 3 bits */ - /* store position in global_settings struct */ - short settings_offset; /* min 9 bit, better 10 */ - /* default value */ - int default_val; /* min 15 bit */ - /* variable name in a .cfg file, NULL if not to be saved */ - const char* cfg_name; - /* set of values, "rgb" for a color, or NULL for a numerical value */ - const char* cfg_val; -}; - -/******************************************** - -Config block as saved on the battery-packed RTC user RAM memory block -of 44 bytes, starting at offset 0x14 of the RTC memory space. - -offset abs -0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63 -0x03 0x17 -0x04 0x18 start of bit-table -... -0x28,0x29 unused, not reachable by set_bits() without disturbing the next 2 -0x2A,0x2B - -Config memory is reset to 0xff and initialized with 'factory defaults' if -a valid header & checksum is not found. Config version number is only -increased when information is _relocated_ or space is _reused_ so that old -versions can read and modify configuration changed by new versions. -Memory locations not used by a given version should not be -modified unless the header & checksum test fails. - -Rest of config block, only saved to disk: -0x2C start of 2nd bit-table -... -0xA4 (char[20]) FMR Preset file -0xB8 (char[20]) WPS file -0xCC (char[20]) Lang file -0xE0 (char[20]) Font file -... (char[20]) RWPS file (on targets supporting a Remote WPS) -... (char[20]) Main backdrop file (on color LCD targets) - -... to 0x200 - -*************************************/ - -/* The persistence of the global_settings members is now controlled by - the two tables below, rtc_bits and hd_bits. - New values can just be added to the end, it will be backwards - compatible. If you however change order, bitsize, etc. of existing - entries, you need to bump CONFIG_BLOCK_VERSION to break compatibility. +/* NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin */ +/* NVRAM is set out as +[0] 'R' +[1] 'b' +[2] version +[3] stored variable count +[4-7] crc32 checksum +[8-NVRAM_BLOCK_SIZE] data */ +#define NVRAM_DATA_START 8 +#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin" +static char nvram_buffer[NVRAM_BLOCK_SIZE]; - -/* convenience macro for both size and offset of global_settings member */ -#define S_O(val) sizeof(global_settings.val), offsetof(struct user_settings, val) -#define SIGNED 0x80 /* for bitsize value with signed attribute */ - -/* some sets of values which are used more than once, to save memory */ -static const char off_on[] = "off,on"; -static const char off_on_ask[] = "off,on,ask"; -static const char off_number_spell_hover[] = "off,number,spell,hover"; -#ifdef HAVE_LCD_BITMAP -static const char graphic_numeric[] = "graphic,numeric"; -#endif - -#ifdef HAVE_RECORDING -/* keep synchronous to trig_durations and - trigger_times in settings_apply_trigger */ -static const char trig_durations_conf [] = - "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min"; -#endif - -#if defined(CONFIG_BACKLIGHT) -static const char backlight_times_conf [] = - "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90"; -#endif - -/* the part of the settings which ends up in the RTC RAM, where available - (those we either need early, save frequently, or without spinup) */ -static const struct bit_entry rtc_bits[] = +static bool read_nvram_data(char* buf, int max_len) { - /* placeholder, containing the size information */ - {9, 0, 0, 0, NULL, NULL }, /* 9 bit to tell how far this is populated */ - - /* # of bits, offset+size, default, .cfg name, .cfg values */ - /* sound */ -#if CONFIG_CODEC == MAS3507D - {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */ -#else - {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */ -#endif - {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */ -#if CONFIG_CODEC != SWCODEC /* any MAS */ - {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -15..+15 / -12..+12 */ - {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -15..+15 / -12..+12 */ -#elif defined HAVE_UDA1380 - {5, S_O(bass), 0, "bass", NULL }, /* 0..+24 */ - {3, S_O(treble), 0, "treble", NULL }, /* 0..+6 */ -#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \ - || defined(HAVE_WM8731) || defined(HAVE_WM8721) \ - || defined(HAVE_WM8751) - {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -6..+9 */ - {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -6..+9 */ -#endif -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - {5, S_O(loudness), 0, "loudness", NULL }, /* 0...17 */ - {3, S_O(avc), 0, "auto volume", "off,20ms,2,4,8" }, - {1, S_O(superbass), false, "superbass", off_on }, -#endif - {3, S_O(channel_config), 0, "channels", - "stereo,mono,custom,mono left,mono right,karaoke" }, - {8, S_O(stereo_width), 100, "stereo width", NULL}, - /* playback */ - {1, S_O(resume), false, "resume", off_on }, - {1, S_O(playlist_shuffle), false, "shuffle", off_on }, - {16 | SIGNED, S_O(resume_index), -1, NULL, NULL }, - {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, - {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, - {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL }, - {3, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle,ab" }, - /* LCD */ -#ifdef HAVE_LCD_CONTRAST - {6, S_O(contrast), DEFAULT_CONTRAST_SETTING, "contrast", NULL }, -#endif -#ifdef CONFIG_BACKLIGHT - {5, S_O(backlight_timeout), 6, "backlight timeout", backlight_times_conf }, -#ifdef CONFIG_CHARGING - {5, S_O(backlight_timeout_plugged), 11, "backlight timeout plugged", - backlight_times_conf }, -#endif -#endif /* CONFIG_BACKLIGHT */ -#ifdef HAVE_LCD_BITMAP - {1, S_O(invert), false, "invert", off_on }, - {1, S_O(flip_display), false, "flip display", off_on }, - /* display */ - {1, S_O(invert_cursor), true, "invert cursor", off_on }, - {1, S_O(statusbar), true, "statusbar", off_on }, - {1, S_O(scrollbar), true, "scrollbar", off_on }, -#if CONFIG_KEYPAD == RECORDER_PAD - {1, S_O(buttonbar), true, "buttonbar", off_on }, -#endif - {1, S_O(volume_type), 0, "volume display", graphic_numeric }, - {1, S_O(battery_display), 0, "battery display", graphic_numeric }, - {1, S_O(timeformat), 0, "time format", "24hour,12hour" }, -#endif /* HAVE_LCD_BITMAP */ - {1, S_O(show_icons), true, "show icons", off_on }, - /* system */ - {4, S_O(poweroff), 10, - "idle poweroff", "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60" }, - {18, S_O(runtime), 0, NULL, NULL }, - {18, S_O(topruntime), 0, NULL, NULL }, -#if MEM > 1 - {15, S_O(max_files_in_playlist), 10000, - "max files in playlist", NULL }, /* 1000...20000 */ - {14, S_O(max_files_in_dir), 400, - "max files in dir", NULL }, /* 50...10000 */ + unsigned crc32 = 0xffffffff; + int var_count = 0, i = 0, buf_pos = 0; +#ifndef HAVE_RTC_RAM + int fd = open(NVRAM_FILE,O_RDONLY); + if (fd < 0) + return false; + memset(buf,0,max_len); + if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */ + return false; + close(fd); #else - {15, S_O(max_files_in_playlist), 1000, - "max files in playlist", NULL }, /* 1000...20000 */ - {14, S_O(max_files_in_dir), 200, - "max files in dir", NULL }, /* 50...10000 */ -#endif - /* battery */ - {12, S_O(battery_capacity), BATTERY_CAPACITY_DEFAULT, "battery capacity", - NULL }, /* 1500...3200 for NiMH, 2200...3200 for LiIon, - 500...1500 for Alkaline */ -#ifdef CONFIG_CHARGING - {1, S_O(car_adapter_mode), false, "car adapter mode", off_on }, -#endif - /* tuner */ -#ifdef CONFIG_TUNER - {1, S_O(fm_force_mono), false, "force fm mono", off_on }, - {9, S_O(last_frequency), 0, NULL, NULL }, /* Default: MIN_FREQ */ -#endif - -#if BATTERY_TYPES_COUNT > 1 - {1, S_O(battery_type), 0, "battery type", "alkaline,nimh" }, -#endif - -#ifdef HAVE_REMOTE_LCD - /* remote lcd */ - {6, S_O(remote_contrast), DEFAULT_REMOTE_CONTRAST_SETTING, - "remote contrast", NULL }, - {1, S_O(remote_invert), false, "remote invert", off_on }, - {1, S_O(remote_flip_display), false, "remote flip display", off_on }, - {5, S_O(remote_backlight_timeout), 6, "remote backlight timeout", - backlight_times_conf }, -#ifdef CONFIG_CHARGING - {5, S_O(remote_backlight_timeout_plugged), 11, - "remote backlight timeout plugged", backlight_times_conf }, -#endif -#ifdef HAVE_REMOTE_LCD_TICKING - {1, S_O(remote_reduce_ticking), false, "remote reduce ticking", off_on }, -#endif -#endif - -#ifdef CONFIG_BACKLIGHT - {1, S_O(bl_filter_first_keypress), false, - "backlight filters first keypress", off_on }, -#ifdef HAVE_REMOTE_LCD - {1, S_O(remote_bl_filter_first_keypress), false, - "backlight filters first remote keypress", off_on }, -#endif -#endif /* CONFIG_BACKLIGHT */ - - /* new stuff to be added here */ - /* If values are just added to the end, no need to bump the version. */ - - /* Current sum of bits: 277 (worst case, but w/o remote lcd) */ - /* Sum of all bit sizes must not grow beyond 288! */ -}; - - -/* the part of the settings which ends up in HD sector only */ -static const struct bit_entry hd_bits[] = + memset(buf,0,max_len); + /* read rtc block */ + for (i=0; i < max_len; i++ ) + buf[i] = rtc_read(0x14+i); +#endif + /* check magic, version */ + if ((buf[0] != 'R') || (buf[1] != 'b') + || (buf[2] != NVRAM_CONFIG_VERSION)) + return false; + /* check crc32 */ + crc32 = crc_32(&buf[NVRAM_DATA_START], + max_len-NVRAM_DATA_START-1,0xffffffff); + if (memcmp(&crc32,&buf[4],4)) + return false; + /* all good, so read in the settings */ + var_count = buf[3]; + buf_pos = NVRAM_DATA_START; + for(i=0; (i0) && (buf_pos>F_NVRAM_MASK_SHIFT; + if (nvram_bytes) + { + memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes); + buf_pos += nvram_bytes; + var_count--; + } + } + return true; +} +static bool write_nvram_data(char* buf, int max_len) { - /* This table starts after the 44 RTC bytes = 352 bits. */ - /* Here we need 11 bits to tell how far this is populated. */ - - /* placeholder, containing the size information */ - {11, 0, 0, 0, NULL, NULL }, /* 11 bit to tell how far this is populated */ - - /* # of bits, offset+size, default, .cfg name, .cfg values */ - /* more display */ -#ifdef CONFIG_BACKLIGHT - {1, S_O(caption_backlight), false, "caption backlight", off_on }, -#endif -#ifdef HAVE_REMOTE_LCD - {1, S_O(remote_caption_backlight), false, - "remote caption backlight", off_on }, -#endif -#ifdef HAVE_BACKLIGHT_BRIGHTNESS - {6, S_O(brightness), DEFAULT_BRIGHTNESS_SETTING, "brightness", NULL }, -#endif -#ifdef HAVE_BACKLIGHT_PWM_FADING - /* backlight fading */ - {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"}, - {3, S_O(backlight_fade_out), 3, "backlight fade out", - "off,500ms,1s,2s,3s,4s,5s,10s"}, -#endif - - {4, S_O(scroll_speed), 9, "scroll speed", NULL }, /* 0...15 */ - {8, S_O(scroll_delay), 100, "scroll delay", NULL }, /* 0...250 */ - {8, S_O(bidir_limit), 50, "bidir limit", NULL }, /* 0...200 */ - -#ifdef HAVE_REMOTE_LCD - {4, S_O(remote_scroll_speed), 9, "remote scroll speed", NULL }, /* 0...15 */ - {8, S_O(remote_scroll_step), 6, "remote scroll step", NULL }, /* 1...160 */ - {8, S_O(remote_scroll_delay), 100, "remote scroll delay", NULL }, /* 0...250 */ - {8, S_O(remote_bidir_limit), 50, "remote bidir limit", NULL }, /* 0...200 */ -#endif - -#ifdef HAVE_LCD_BITMAP - {1, S_O(offset_out_of_view), false, "Screen Scrolls Out Of View", off_on }, -#if LCD_WIDTH > 255 - {9, S_O(scroll_step), 6, "scroll step", NULL }, - {9, S_O(screen_scroll_step), 16, "screen scroll step", NULL }, -#elif LCD_WIDTH > 127 - {8, S_O(scroll_step), 6, "scroll step", NULL }, - {8, S_O(screen_scroll_step), 16, "screen scroll step", NULL }, -#else - {7, S_O(scroll_step), 6, "scroll step", NULL }, - {7, S_O(screen_scroll_step), 16, "screen scroll step", NULL }, -#endif -#endif /* HAVE_LCD_BITMAP */ -#ifdef HAVE_LCD_CHARCELLS - {3, S_O(jump_scroll), 0, "jump scroll", NULL }, /* 0...5 */ - {8, S_O(jump_scroll_delay), 50, "jump scroll delay", NULL }, /* 0...250 */ -#endif - {1, S_O(scroll_paginated), false, "scroll paginated", off_on }, - -#ifdef HAVE_LCD_COLOR - {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"}, - {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"}, -#endif - - /* more playback */ - {1, S_O(play_selected), true, "play selected", off_on }, - {1, S_O(fade_on_stop), true, "volume fade", off_on }, - {4, S_O(ff_rewind_min_step), FF_REWIND_1000, - "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60" }, - {4, S_O(ff_rewind_accel), 3, "scan accel", NULL }, -#if CONFIG_CODEC == SWCODEC - {3, S_O(buffer_margin), 0, "antiskip", - "5s,15s,30s,1min,2min,3min,5min,10min" }, -#else - {3, S_O(buffer_margin), 0, "antiskip", NULL }, -#endif - /* disk */ -#ifndef HAVE_MMC -#ifdef HAVE_ATA_POWER_OFF - {1, S_O(disk_poweroff), false, "disk poweroff", off_on }, -#endif - {8, S_O(disk_spindown), 5, "disk spindown", NULL }, -#endif /* HAVE_MMC */ - - /* browser */ - {3, S_O(dirfilter), SHOW_SUPPORTED, - "show files", "all,supported,music,playlists" -#ifdef HAVE_TAGCACHE - ",id3 database" -#endif - }, - {1, S_O(sort_case), false, "sort case", off_on }, - {1, S_O(browse_current), false, "follow playlist", off_on }, - /* playlist */ - {1, S_O(playlist_viewer_icons), true, "playlist viewer icons", off_on }, - {1, S_O(playlist_viewer_indices), true, - "playlist viewer indices", off_on }, - {1, S_O(playlist_viewer_track_display), 0, - "playlist viewer track display", "track name,full path" }, - {2, S_O(recursive_dir_insert), RECURSE_OFF, - "recursive directory insert", off_on_ask }, - /* bookmarks */ - {3, S_O(autocreatebookmark), BOOKMARK_NO, "autocreate bookmarks", - "off,on,ask,recent only - on,recent only - ask" }, - {2, S_O(autoloadbookmark), BOOKMARK_NO, - "autoload bookmarks", off_on_ask }, - {2, S_O(usemrb), BOOKMARK_NO, - "use most-recent-bookmarks", "off,on,unique only" }, -#ifdef HAVE_LCD_BITMAP - /* peak meter */ - {5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */ - "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min,3min,5min,10min,20min,45min,90min" }, - {5, S_O(peak_meter_hold), 3, "peak meter hold", - "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" }, - {7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */ - {1, S_O(peak_meter_dbfs), true, "peak meter dbfs", off_on }, - {7, S_O(peak_meter_min), 60, "peak meter min", NULL }, /* 0...100 */ - {7, S_O(peak_meter_max), 0, "peak meter max", NULL }, /* 0...100 */ -#endif -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - {7, S_O(mdb_strength), 0, "mdb strength", NULL}, - {7, S_O(mdb_harmonics), 0, "mdb harmonics", NULL}, - {9, S_O(mdb_center), 0, "mdb center", NULL}, - {9, S_O(mdb_shape), 0, "mdb shape", NULL}, - {1, S_O(mdb_enable), 0, "mdb enable", off_on}, -#endif -#if CONFIG_CODEC == MAS3507D - {1, S_O(line_in), false, "line in", off_on }, + unsigned crc32 = 0xffffffff; + int i = 0, buf_pos = 0; + char var_count = 0; +#ifndef HAVE_RTC_RAM + int fd; #endif - /* voice */ - {2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover }, - {2, S_O(talk_file), 0, "talk file", off_number_spell_hover }, - {1, S_O(talk_menu), true, "talk menu", off_on }, - - {2, S_O(sort_file), 0, "sort files", "alpha,oldest,newest,type" }, - {2, S_O(sort_dir), 0, "sort dirs", "alpha,oldest,newest" }, - {1, S_O(id3_v1_first), 0, "id3 tag priority", "v2-v1,v1-v2"}, - -#ifdef HAVE_RECORDING - /* recording */ - {1, S_O(recscreen_on), false, "recscreen on", off_on }, - {1, S_O(rec_startup), false, "rec screen on startup", off_on }, - {4, S_O(rec_timesplit), 0, "rec timesplit", /* 0...15 */ - "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" }, - {4, S_O(rec_sizesplit), 0, "rec sizesplit", /* 0...15 */ - "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB" }, - {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" }, - {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" }, - {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" }, - + memset(buf,0,max_len); + /* magic, version */ + buf[0] = 'R'; buf[1] = 'b'; + buf[2] = NVRAM_CONFIG_VERSION; + buf_pos = NVRAM_DATA_START; + for(i=0; (i>F_NVRAM_MASK_SHIFT; + if (nvram_bytes) + { + memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes); + buf_pos += nvram_bytes; + var_count++; + } + } + /* count and crc32 */ + buf[3] = var_count; + crc32 = crc_32(&buf[NVRAM_DATA_START], + max_len-NVRAM_DATA_START-1,0xffffffff); + memcpy(&buf[4],&crc32,4); +#ifndef HAVE_RTC_RAM + fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY); + if (fd >= 0) + { + int len = write(fd,buf,max_len); + close(fd); + if (len < 8) + return false; + } #else - 1, -#endif - S_O(rec_source), 0 /* 0=mic */, "rec source", - "mic,line" -#ifdef HAVE_SPDIF_IN - ",spdif" -#endif -#ifdef HAVE_FMRADIO_IN - ",fmradio" -#endif - }, - {5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */ - {1, S_O(rec_directory), 0, /* rec_base_directory */ - "rec directory", REC_BASE_DIR ",current" }, -#ifdef CONFIG_BACKLIGHT - {2, S_O(cliplight), 0, "cliplight", "off,main,both,remote" }, -#endif -#if CONFIG_CODEC == MAS3587F - {4, S_O(rec_mic_gain), 8, "rec mic gain", NULL }, - {4, S_O(rec_left_gain), 2 /* 0dB */, "rec left gain", NULL }, /* 0...15 */ - {4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */ - {3, S_O(rec_frequency), 0, /* 0=44.1kHz */ - "rec frequency", "44,48,32,22,24,16" }, - {3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL }, - {1, S_O(rec_editable), false, "editable recordings", off_on }, -#endif /* CONFIG_CODEC == MAS3587F */ - -#if CONFIG_CODEC == SWCODEC -#ifdef HAVE_UDA1380 - {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */ - {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */ - {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */ -#elif defined(HAVE_TLV320) - /* TLV320 only has no mic boost or 20db mic boost */ - {1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */ - {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */ - {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */ -#elif defined(HAVE_WM8975) - {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */ - {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */ - {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */ -#elif defined(HAVE_WM8758) - {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */ - {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */ - {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */ -#elif defined(HAVE_WM8731) - {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */ - {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */ - {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */ -#endif - {REC_FREQ_CFG_NUM_BITS, S_O(rec_frequency), REC_FREQ_DEFAULT, - "rec frequency", REC_FREQ_CFG_VAL_LIST }, - {REC_FORMAT_CFG_NUM_BITS ,S_O(rec_format), REC_FORMAT_DEFAULT, - "rec format", REC_FORMAT_CFG_VAL_LIST }, - /** Encoder settings start - keep these together **/ - /* aiff_enc */ - /* (no settings yet) */ - /* mp3_enc */ - {5,S_O(mp3_enc_config.bitrate), MP3_ENC_BITRATE_CFG_DEFAULT, - "mp3_enc bitrate", MP3_ENC_BITRATE_CFG_VALUE_LIST }, - /* wav_enc */ - /* (no settings yet) */ - /* wavpack_enc */ - /* (no settings yet) */ - /** Encoder settings end **/ -#endif /* CONFIG_CODEC == SWCODEC */ - - /* values for the trigger */ - {8 | SIGNED, S_O(rec_start_thres), -35, "trigger start threshold", NULL}, - {8 | SIGNED, S_O(rec_stop_thres), -45, "trigger stop threshold", NULL}, - {4, S_O(rec_start_duration), 0, "trigger start duration", trig_durations_conf}, - {4, S_O(rec_stop_postrec), 2, "trigger stop postrec", trig_durations_conf}, - {4, S_O(rec_stop_gap), 1, "trigger min gap", trig_durations_conf}, - {4, S_O(rec_trigger_mode ), 0, "trigger mode", "off,once,repeat"}, -#endif /* HAVE_RECORDING */ - -#ifdef HAVE_SPDIF_POWER - {1, S_O(spdif_enable), false, "spdif enable", off_on}, -#endif - - {2, S_O(next_folder), false, "folder navigation", "off,on,random" }, - {1, S_O(runtimedb), false, "gather runtime data", off_on }, - -#if CONFIG_CODEC == SWCODEC - {1, S_O(replaygain), false, "replaygain", off_on }, - {2, S_O(replaygain_type), REPLAYGAIN_ALBUM, "replaygain type", - "track,album,track shuffle" }, - {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on }, - {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL }, - {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" }, - {3, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,shuffle and track skip,always"}, - {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL}, - {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL}, - {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL}, - {4, S_O(crossfade_fade_out_duration), 0, "crossfade fade out duration", NULL}, - {1, S_O(crossfade_fade_out_mixmode), 0, "crossfade fade out mode", "crossfade,mix"}, - {1, S_O(crossfeed), false, "crossfeed", off_on }, - {6, S_O(crossfeed_direct_gain), 15, "crossfeed direct gain", NULL }, - {7, S_O(crossfeed_cross_gain), 60, "crossfeed cross gain", NULL }, - {8, S_O(crossfeed_hf_attenuation), 160, "crossfeed hf attenuation", NULL }, - {11, S_O(crossfeed_hf_cutoff), 700, "crossfeed hf cutoff", NULL }, - - /* equalizer */ - {1, S_O(eq_enabled), false, "eq enabled", off_on }, - {8, S_O(eq_precut), 0, "eq precut", NULL }, - /* 0..32768 Hz */ - {15, S_O(eq_band0_cutoff), 60, "eq band 0 cutoff", NULL }, - {15, S_O(eq_band1_cutoff), 200, "eq band 1 cutoff", NULL }, - {15, S_O(eq_band2_cutoff), 800, "eq band 2 cutoff", NULL }, - {15, S_O(eq_band3_cutoff), 4000, "eq band 3 cutoff", NULL }, - {15, S_O(eq_band4_cutoff), 12000, "eq band 4 cutoff", NULL }, - /* 0..64 (or 0.0 to 6.4) */ - {6, S_O(eq_band0_q), 7, "eq band 0 q", NULL }, - {6, S_O(eq_band1_q), 10, "eq band 1 q", NULL }, - {6, S_O(eq_band2_q), 10, "eq band 2 q", NULL }, - {6, S_O(eq_band3_q), 10, "eq band 3 q", NULL }, - {6, S_O(eq_band4_q), 7, "eq band 4 q", NULL }, - /* -240..240 (or -24db to +24db) */ - {9|SIGNED, S_O(eq_band0_gain), 0, "eq band 0 gain", NULL }, - {9|SIGNED, S_O(eq_band1_gain), 0, "eq band 1 gain", NULL }, - {9|SIGNED, S_O(eq_band2_gain), 0, "eq band 2 gain", NULL }, - {9|SIGNED, S_O(eq_band3_gain), 0, "eq band 3 gain", NULL }, - {9|SIGNED, S_O(eq_band4_gain), 0, "eq band 4 gain", NULL }, - - /* dithering */ - {1, S_O(dithering_enabled), false, "dithering enabled", off_on }, -#endif - -#ifdef HAVE_DIRCACHE - {1, S_O(dircache), false, "dircache", off_on }, - {22, S_O(dircache_size), 0, NULL, NULL }, -#endif - -#ifdef HAVE_TAGCACHE -#ifdef HAVE_TC_RAMCACHE - {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on }, -#endif - {1, S_O(tagcache_autoupdate), 0, "tagcache_autoupdate", off_on }, -#endif - - {4, S_O(default_codepage), 0, "default codepage", - "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" }, - - {1, S_O(warnon_erase_dynplaylist), false, - "warn when erasing dynamic playlist", off_on }, - -#ifdef CONFIG_BACKLIGHT -#ifdef HAS_BUTTON_HOLD - {2, S_O(backlight_on_button_hold), 0, "backlight on button hold", - "normal,off,on" }, -#endif - -#ifdef HAVE_LCD_SLEEP - {4, S_O(lcd_sleep_after_backlight_off), 3, - "lcd sleep after backlight off", - "always,never,5,10,15,20,30,45,60,90" }, -#endif -#endif /* CONFIG_BACKLIGHT */ - -#ifdef HAVE_WM8758 - {1, S_O(eq_hw_enabled), false, "eq hardware enabled", off_on }, - - {2, S_O(eq_hw_band0_cutoff), 1, "eq hardware band 0 cutoff", "80Hz,105Hz,135Hz,175Hz" }, - {5|SIGNED, S_O(eq_hw_band0_gain), 0, "eq hardware band 0 gain", NULL }, - - {2, S_O(eq_hw_band1_center), 1, "eq hardware band 1 center", "230Hz,300Hz,385Hz,500Hz" }, - {1, S_O(eq_hw_band1_bandwidth), 0, "eq hardware band 1 bandwidth", "narrow,wide" }, - {5|SIGNED, S_O(eq_hw_band1_gain), 0, "eq hardware band 1 gain", NULL }, - - {2, S_O(eq_hw_band2_center), 1, "eq hardware band 2 center", "650Hz,850Hz,1.1kHz,1.4kHz" }, - {1, S_O(eq_hw_band2_bandwidth), 0, "eq hardware band 2 bandwidth", "narrow,wide" }, - {5|SIGNED, S_O(eq_hw_band2_gain), 0, "eq hardware band 2 gain", NULL }, - - {2, S_O(eq_hw_band3_center), 1, "eq hardware band 3 center", "1.8kHz,2.4kHz,3.2kHz,4.1kHz" }, - {1, S_O(eq_hw_band3_bandwidth), 0, "eq hardware band 3 bandwidth", "narrow,wide" }, - {5|SIGNED, S_O(eq_hw_band3_gain), 0, "eq hardware band 3 gain", NULL }, - - {2, S_O(eq_hw_band4_cutoff), 1, "eq hardware band 4 cutoff", "5.3kHz,6.9kHz,9kHz,11.7kHz" }, - {5|SIGNED, S_O(eq_hw_band4_gain), 0, "eq hardware band 4 gain", NULL }, -#endif - {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on }, - - {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" }, -#ifdef HAVE_AGC - {4, S_O(rec_agc_preset_mic), 1, "agc mic preset", NULL}, /* 0...5 */ - {4, S_O(rec_agc_preset_line), 1, "agc line preset", NULL}, /* 0...5 */ - {8|SIGNED, S_O(rec_agc_maxgain_mic), 104, "agc maximum mic gain", NULL}, - {8|SIGNED, S_O(rec_agc_maxgain_line), 96, "agc maximum line gain", NULL}, - {3, S_O(rec_agc_cliptime), 1, "agc cliptime", "0.2s,0.4s,0.6s,0.8,1s"}, -#endif - -#ifdef HAVE_REMOTE_LCD -#ifdef HAS_REMOTE_BUTTON_HOLD - {2, S_O(remote_backlight_on_button_hold), 0, "remote backlight on button hold", - "normal,off,on" }, -#endif -#endif - -#ifdef HAVE_HEADPHONE_DETECTION - {2, S_O(unplug_mode), 0, "pause on headphone unplug", NULL}, - {4, S_O(unplug_rw), 0, "rewind duration on pause", NULL}, - {1, S_O(unplug_autoresume), 0, "disable autoresume if phones not present", off_on }, -#endif -#ifdef CONFIG_TUNER - {2, S_O(fm_region), 0, "fm_region", "eu,us,jp,kr" }, -#endif - - {1, S_O(audioscrobbler), false, "Last.fm Logging", off_on}, - - /* If values are just added to the end, no need to bump the version. */ - /* new stuff to be added at the end */ -#ifdef HAVE_RECORDING - {2, S_O(rec_trigger_type), 0, "trigger type", "stop,pause,nf stp"}, + /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so + that it would write a number of bytes at a time since the RTC chip + supports that, but this will have to do for now 8-) */ + for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) { + int r = rtc_write(0x14+i, buf[i]); + if (r) { + DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", + 14+i, r ); + return false; + } + } #endif - - /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */ -}; - -/* helper function to extract n (<=32) bits from an arbitrary position - * counting from LSB to MSB */ -static uint32_t get_bits( - const uint32_t *p, /* the start of the bitfield array */ - unsigned int from, /* bit no. to start reading from */ - unsigned int size) /* how many bits to read */ -{ - unsigned int long_index = from / 32; - unsigned int bit_index = from % 32; - uint32_t result; - - result = p[long_index] >> bit_index; - - if (bit_index + size > 32) /* crossing longword boundary */ - result |= p[long_index+1] << (32 - bit_index); - - result &= 0xFFFFFFFF >> (32 - size); - - return result; -} - -/* helper function to set n (<=32) bits to an arbitrary position, - * counting from LSB to MSB */ -static void set_bits( - uint32_t *p, /* the start of the bitfield array */ - unsigned int from, /* bit no. to start writing into */ - unsigned int size, /* how many bits to change */ - uint32_t value) /* content (LSBs will be taken) */ -{ - unsigned int long_index = from / 32; - unsigned int bit_index = from % 32; - uint32_t mask; - - mask = 0xFFFFFFFF >> (32 - size); - value &= mask; - mask <<= bit_index; - - if (bit_index + size > 32) - p[long_index+1] = - (p[long_index+1] & (0xFFFFFFFF << (bit_index + size - 32))) - | (value >> (32 - bit_index)); - - p[long_index] = (p[long_index] & ~mask) | (value << bit_index); + return true; } #ifdef HAVE_LCD_COLOR @@ -787,223 +258,89 @@ static int hex_to_rgb(const char* hex) return 0; } #endif - -/* - * Calculates the checksum for the config block and returns it - */ - -static unsigned short calculate_config_checksum(const unsigned char* buf) -{ - unsigned int i; - unsigned char cksum[2]; - cksum[0] = cksum[1] = 0; - - for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) { - cksum[0] ^= buf[i]; - cksum[1] ^= buf[i+1]; - } - - return (cksum[0] << 8) | cksum[1]; -} - -/* - * initialize the config block buffer - */ -static void init_config_buffer( void ) -{ - DEBUGF( "init_config_buffer()\n" ); - - /* reset to 0 - all unused */ - memset(config_block, 0, CONFIG_BLOCK_SIZE); - /* insert header */ - config_block[0] = 'R'; - config_block[1] = 'o'; - config_block[2] = 'c'; - config_block[3] = CONFIG_BLOCK_VERSION; -} - -static bool flush_config_block_callback(void) -{ - ata_write_sectors(IF_MV2(0,) config_sector, 1, config_block); - return true; -} -/* - * save the config block buffer to disk or RTC RAM - */ -static int save_config_buffer( void ) -{ - unsigned short chksum; -#ifdef HAVE_RTC_RAM - unsigned int i; -#endif - - /* update the checksum in the end of the block before saving */ - chksum = calculate_config_checksum(config_block); - config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8; - config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff; - -#ifdef HAVE_RTC_RAM - /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so - that it would write a number of bytes at a time since the RTC chip - supports that, but this will have to do for now 8-) */ - for (i=0; i < RTC_BLOCK_SIZE; i++ ) { - int r = rtc_write(0x14+i, config_block[i]); - if (r) { - DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", - 14+i, r ); - return r; - } - } - -#endif - - if (config_sector != 0) - register_ata_idle_func(flush_config_block_callback); - else - return -1; - - return 0; -} - -/* - * load the config block buffer from disk or RTC RAM - */ -static int load_config_buffer(int which) -{ - unsigned short chksum; - bool correct = false; - - - DEBUGF( "load_config_buffer()\n" ); - - if (which & SETTINGS_HD) - { - if (config_sector != 0) { - ata_read_sectors(IF_MV2(0,) config_sector, 1, config_block); - /* calculate the checksum, check it and the header */ - chksum = calculate_config_checksum(config_block); - - if (config_block[0] == 'R' && - config_block[1] == 'o' && - config_block[2] == 'c' && - config_block[3] == CONFIG_BLOCK_VERSION && - (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] && - (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1]) - { - DEBUGF( "load_config_buffer: header & checksum test ok\n" ); - correct = true; - } - } - } - -#ifdef HAVE_RTC_RAM - if(!correct) - { - /* If the disk sector was incorrect, reinit the buffer */ - memset(config_block, 0, CONFIG_BLOCK_SIZE); - } - - if (which & SETTINGS_RTC) - { - unsigned int i; - unsigned char rtc_block[RTC_BLOCK_SIZE]; - - /* read rtc block */ - for (i=0; i < RTC_BLOCK_SIZE; i++ ) - rtc_block[i] = rtc_read(0x14+i); - - chksum = calculate_config_checksum(rtc_block); - - /* if rtc block is ok, use that */ - if (rtc_block[0] == 'R' && - rtc_block[1] == 'o' && - rtc_block[2] == 'c' && - rtc_block[3] == CONFIG_BLOCK_VERSION && - (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] && - (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1]) - { - memcpy(config_block, rtc_block, RTC_BLOCK_SIZE); - correct = true; - } - } -#endif - - if ( !correct ) { - /* if checksum is not valid, clear the config buffer */ - DEBUGF( "load_config_buffer: header & checksum test failed\n" ); - init_config_buffer(); - return -1; - } - - return 0; -} - - -/* helper to save content of global_settings into a bitfield, - as described per table */ -static void save_bit_table(const struct bit_entry* p_table, int count, int bitstart) +bool settings_write_config(char* filename) { - uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */ - uint32_t value; /* 32 bit content */ int i; - const struct bit_entry* p_run = p_table; /* start after the size info */ - int curr_bit = bitstart + p_table->bit_size; - count--; /* first is excluded from loop */ - - for (i=0; ibyte_size) - { - case 1: - value = ((uint8_t *)&global_settings)[p_run->settings_offset]; - break; - case 2: - value = ((uint16_t *)&global_settings)[p_run->settings_offset/2]; - break; - case 4: - value = ((uint32_t *)&global_settings)[p_run->settings_offset/4]; - break; - default: - DEBUGF( "save_bit_table: illegal size!\n" ); - continue; - } - set_bits(p_bitfield, curr_bit, p_run->bit_size & 0x3F, value); - curr_bit += p_run->bit_size & 0x3F; - } - set_bits(p_bitfield, bitstart, p_table->bit_size, /* write size */ - curr_bit); /* = position after last element */ -} - -/* - * figure out the config sector from the partition table and the - * mounted file system - */ -void settings_calc_config_sector(void) -{ -#ifdef SIMULATOR - config_sector = 61; -#else - int i; - long partition_start; - long sector = 0; - - if (fat_startsector(IF_MV(0)) != 0) /* There is a partition table */ + int fd; + char value[MAX_PATH]; + fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY); + if (fd < 0) + return false; + fdprintf(fd, "# .cfg file created by rockbox %s - " + "http://www.rockbox.org\r\n\r\n", appsversion); + for(i=0; istart; - if (partition_start != 0 && (partition_start - 2) < sector) - sector = partition_start - 2; - } - if (sector < 0) - sector = 0; - } - - config_sector = sector; + case F_T_INT: + case F_T_UINT: +#ifdef HAVE_LCD_COLOR + if (settings[i].flags&F_RGB) + { + int colour = *(int*)settings[i].setting; + snprintf(value,MAX_PATH,"%02x%02x%02x", + (int)RGB_UNPACK_RED(colour), + (int)RGB_UNPACK_GREEN(colour), + (int)RGB_UNPACK_BLUE(colour)); + } + else #endif + if (settings[i].cfg_vals == NULL) + { + snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting); + } + else + { + char *s,*end; + char vals[MAX_PATH]; + int val = 0; + strncpy(vals,settings[i].cfg_vals,MAX_PATH); + s = strtok_r(vals,",",&end); + while (s) + { + if (val == *(int*)settings[i].setting) + { + strncpy(value,s,MAX_PATH); + break; + } + val++; + s = strtok_r(NULL,",",&end); + } + } + break; + case F_T_BOOL: + strcpy(value,*(bool*)settings[i].setting == true?"on":"off"); + break; + case F_T_CHARPTR: + case F_T_UCHARPTR: + if (((char*)settings[i].setting)[0] == '\0') + break; + if (settings[i].filename_setting->prefix) + { + snprintf(value,MAX_PATH,"%s%s%s", + settings[i].filename_setting->prefix, + (char*)settings[i].setting, + settings[i].filename_setting->suffix); + } + else strncpy(value,(char*)settings[i].setting, + settings[i].filename_setting->max_len); + break; + } /* switch () */ + if (value[0]) + fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value); + value[0] = '\0'; + } /* for(...) */ + close(fd); + return true; +} +static bool flush_config_block_callback(void) +{ + bool r1, r2; + r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); + r2 = settings_write_config(CONFIGFILE); + return r1 || r2; } /* @@ -1011,75 +348,34 @@ void settings_calc_config_sector(void) */ int settings_save( void ) { - int i; - - { - int elapsed_secs; - - elapsed_secs = (current_tick - lasttime) / HZ; - global_settings.runtime += elapsed_secs; - lasttime += (elapsed_secs * HZ); - - if ( global_settings.runtime > global_settings.topruntime ) - global_settings.topruntime = global_settings.runtime; - } + int elapsed_secs; - /* serialize scalar values into RTC and HD sector, specified via table */ - save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8); - save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8); - - i = 0xb8; - strncpy((char *)&config_block[i], (char *)global_settings.wps_file, - MAX_FILENAME); - i+= MAX_FILENAME; - strncpy((char *)&config_block[i], (char *)global_settings.lang_file, - MAX_FILENAME); - i+= MAX_FILENAME; - strncpy((char *)&config_block[i], (char *)global_settings.font_file, - MAX_FILENAME); - i+= MAX_FILENAME; -#ifdef HAVE_REMOTE_LCD - strncpy((char *)&config_block[i], (char *)global_settings.rwps_file, - MAX_FILENAME); - i+= MAX_FILENAME; -#endif - -#ifdef CONFIG_TUNER - strncpy((char *)&config_block[i], (char *)global_settings.fmr_file, - MAX_FILENAME); - i+= MAX_FILENAME; -#endif + elapsed_secs = (current_tick - lasttime) / HZ; + global_settings.runtime += elapsed_secs; + lasttime += (elapsed_secs * HZ); -#if LCD_DEPTH > 1 - strncpy((char *)&config_block[i], (char *)global_settings.backdrop_file, - MAX_FILENAME); - i+= MAX_FILENAME; -#endif -#ifdef HAVE_LCD_BITMAP - strncpy((char *)&config_block[i], (char *)global_settings.kbd_file, - MAX_FILENAME); - i+= MAX_FILENAME; + if ( global_settings.runtime > global_settings.topruntime ) + global_settings.topruntime = global_settings.runtime; +#ifdef HAVE_RTC_RAM + /* this will be done in the ata_callback if + target doesnt have rtc ram */ + write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); #endif - - if(save_config_buffer()) + if(!register_ata_idle_func(flush_config_block_callback)) { - lcd_clear_display(); -#ifdef HAVE_REMOTE_LCD - lcd_remote_clear_display(); -#endif + int i; + FOR_NB_SCREENS(i) + { + screens[i].clear_display(); #ifdef HAVE_LCD_CHARCELLS - lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER)); - lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER)); + screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER)); + screens[i].puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER)); #else - lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); - lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); - lcd_update(); -#ifdef HAVE_REMOTE_LCD - lcd_remote_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); - lcd_remote_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); - lcd_remote_update(); -#endif + screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); + screens[i].puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); + screens[i].update(); #endif + } sleep(HZ*2); return -1; } @@ -1147,6 +443,7 @@ void settings_apply(void) int i; #endif + DEBUGF( "settings_apply()\n" ); sound_settings_apply(); audio_set_buffer_margin(global_settings.buffer_margin); @@ -1207,8 +504,7 @@ void settings_apply(void) lcd_set_invert_display(global_settings.invert); lcd_set_flip(global_settings.flip_display); button_set_flip(global_settings.flip_display); - if(global_settings.invert || global_settings.flip_display) - lcd_update(); /* refresh after flipping the screen */ + lcd_update(); /* refresh after flipping the screen */ settings_apply_pm_range(); peak_meter_init_times( global_settings.peak_meter_release, global_settings.peak_meter_hold, @@ -1239,7 +535,6 @@ void settings_apply(void) unload_main_backdrop(); } show_main_backdrop(); - #endif #ifdef HAVE_LCD_COLOR @@ -1344,131 +639,16 @@ void settings_apply(void) #endif } - -/* helper to load global_settings from a bitfield, as described per table */ -static void load_bit_table(const struct bit_entry* p_table, int count, int bitstart) -{ - uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */ - uint32_t value; /* 32 bit content */ - int i; - int maxbit; /* how many bits are valid in the saved part */ - const struct bit_entry* p_run = p_table; /* start after the size info */ - count--; /* first is excluded from loop */ - maxbit = get_bits(p_bitfield, bitstart, p_table->bit_size); - bitstart += p_table->bit_size; - - for (i=0; ibit_size & 0x3F; /* mask off abused bits */ - if (bitstart + size > maxbit) - break; /* exit if this is not valid any more in bitfield */ - - value = get_bits(p_bitfield, bitstart, size); - bitstart += size; - if (p_run->bit_size & SIGNED) - { // sign extend the read value - unsigned long mask = 0xFFFFFFFF << (size - 1); - if (value & mask) /* true if MSB of value is set */ - value |= mask; - } - - /* could do a memcpy, but that would be endian-dependent */ - switch(p_run->byte_size) - { - case 1: - ((uint8_t *)&global_settings)[p_run->settings_offset] = - (unsigned char)value; - break; - case 2: - ((uint16_t *)&global_settings)[p_run->settings_offset/2] = - (unsigned short)value; - break; - case 4: - ((uint32_t *)&global_settings)[p_run->settings_offset/4] = - (unsigned int)value; - break; - default: - DEBUGF( "load_bit_table: illegal size!\n" ); - continue; - } - } -} - - /* * load settings from disk or RTC RAM */ void settings_load(int which) { - int i; DEBUGF( "reload_all_settings()\n" ); - - /* load the buffer from the RTC (resets it to all-unused if the block - is invalid) and decode the settings which are set in the block */ - if (!load_config_buffer(which)) - { - /* load scalar values from RTC and HD sector, specified via table */ - if (which & SETTINGS_RTC) - { - load_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8); - } - if (which & SETTINGS_HD) - { - load_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), - RTC_BLOCK_SIZE*8); - } - -#ifdef HAVE_RECORDING - global_settings.recscreen_on = false; -#endif - -#ifdef HAVE_LCD_CONTRAST - if ( global_settings.contrast < MIN_CONTRAST_SETTING || - global_settings.contrast > MAX_CONTRAST_SETTING ) - global_settings.contrast = lcd_default_contrast(); -#endif - -#ifdef HAVE_LCD_REMOTE - if (global_settings.remote_contrast < MIN_REMOTE_CONTRAST_SETTING || - global_settings.remote_contrast > MAX_REMOTE_CONTRAST_SETTING ) - global_settings.remote_contrast = lcd_remote_default_contrast(); -#endif - i = 0xb8; - strncpy((char *)global_settings.wps_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; - strncpy((char *)global_settings.lang_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; - strncpy((char *)global_settings.font_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; -#ifdef HAVE_REMOTE_LCD - strncpy((char *)global_settings.rwps_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; -#endif - -#ifdef CONFIG_TUNER - strncpy((char *)global_settings.fmr_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; -#endif - -#if LCD_DEPTH > 1 - strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; -#endif -#ifdef HAVE_LCD_BITMAP - strncpy((char *)global_settings.kbd_file, (char *)&config_block[i], - MAX_FILENAME); - i+= MAX_FILENAME; -#endif - } + if (which&SETTINGS_RTC) + read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); + if (which&SETTINGS_HD) + settings_load_config(CONFIGFILE,false); } void set_file(char* filename, char* setting, int maxlen) @@ -1502,94 +682,13 @@ void set_file(char* filename, char* setting, int maxlen) settings_save(); } -/* helper to sort a .cfg file entry into a global_settings member, - as described per table. Returns the position if found, else 0. */ -static int load_cfg_table( - const struct bit_entry* p_table, /* the table which describes the entries */ - int count, /* number of entries in the table, including the first */ - const char* name, /* the item to be searched */ - const char* value, /* the value which got loaded for that item */ - int hint) /* position to start looking */ -{ - int i = hint; - - do - { - if (p_table[i].cfg_name != NULL && !strcasecmp(name, p_table[i].cfg_name)) - { /* found */ - int val = 0; - if (p_table[i].cfg_val == NULL) - { /* numerical value, just convert the string */ - val = atoi(value); - } -#if HAVE_LCD_COLOR - else if (!strncasecmp(p_table[i].cfg_val,"rgb",4)) - { - val = hex_to_rgb(value); - } -#endif - else - { /* set of string values, find the index */ - const char* item; - const char* run; - int len = strlen(value); - - item = run = p_table[i].cfg_val; - - while(1) - { - /* count the length of the field */ - while (*run != ',' && *run != '\0') - run++; - - if (!strncasecmp(value, item, MAX(run-item, len))) - break; /* match, exit the search */ - - if (*run == '\0') /* reached the end of the choices */ - return i; /* return the position, but don't update */ - - val++; /* count the item up */ - run++; /* behind the ',' */ - item = run; - } - } - - /* could do a memcpy, but that would be endian-dependent */ - switch(p_table[i].byte_size) - { - case 1: - ((unsigned char*)&global_settings)[p_table[i].settings_offset] = - (unsigned char)val; - break; - case 2: - ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] = - (unsigned short)val; - break; - case 4: - ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] = - (unsigned int)val; - break; - default: - DEBUGF( "illegal size!" ); - continue; - } - - return i; /* return the position */ - } - - i++; - if (i==count) - i=1; /* wraparound */ - } while (i != hint); /* back where we started, all searched */ - - return 0; /* indicate not found */ -} - - -bool settings_load_config(const char* file) +bool settings_load_config(const char* file, bool apply) { int fd; char line[128]; + char* name; + char* value; + int i; fd = open(file, O_RDONLY); if (fd < 0) @@ -1597,180 +696,91 @@ bool settings_load_config(const char* file) while (read_line(fd, line, sizeof line) > 0) { - char* name; - char* value; - const struct bit_entry* table[2] = { rtc_bits, hd_bits }; - const int ta_size[2] = { - sizeof(rtc_bits)/sizeof(rtc_bits[0]), - sizeof(hd_bits)/sizeof(hd_bits[0]) - }; - int last_table = 0; /* which table was used last round */ - int last_pos = 1; /* at which position did we succeed */ - int pos; /* currently returned position */ - if (!settings_parseline(line, &name, &value)) continue; - /* check for the string values */ - if (!strcasecmp(name, "wps")) { -#if LCD_DEPTH > 1 - unload_wps_backdrop(); -#endif - int fd2; - if ((fd2 = open(value, O_RDONLY)) >= 0) { - close(fd2); - set_file(value, (char *)global_settings.wps_file, MAX_FILENAME); - } - } -#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) - else if (!strcasecmp(name, "rwps")) { - int fd2; - if ((fd2 = open(value, O_RDONLY)) >= 0) { - close(fd2); - set_file(value, (char *)global_settings.rwps_file, MAX_FILENAME); - } - } -#endif - else if (!strcasecmp(name, "lang")) { - if (!lang_load(value)) - { - set_file(value, (char *)global_settings.lang_file, MAX_FILENAME); - talk_init(); /* use voice of same language */ - } - } -#ifdef CONFIG_TUNER - else if (!strcasecmp(name, "fmr")) { - set_file(value, global_settings.fmr_file, MAX_FILENAME); - } -#endif -#ifdef HAVE_LCD_BITMAP - else if (!strcasecmp(name, "font")) { - if (font_load(value)) - set_file(value, (char *)global_settings.font_file, MAX_FILENAME); - } -#endif -#if LCD_DEPTH > 1 - else if (!strcasecmp(name, "backdrop")) { - if (load_main_backdrop(value)) { - set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME); - show_main_backdrop(); - } - } -#endif -#ifdef HAVE_LCD_BITMAP - else if (!strcasecmp(name, "keyboard")) { - if (!load_kbd(value)) - set_file(value, (char *)global_settings.kbd_file, MAX_FILENAME); - } -#endif - - - /* check for scalar values, using the two tables */ - pos = load_cfg_table(table[last_table], ta_size[last_table], - name, value, last_pos); - if (pos) /* success */ - { - last_pos = pos; /* remember as a position hint for next round */ - continue; - } - - last_table = 1-last_table; /* try other table */ - last_pos = 1; /* search from start */ - pos = load_cfg_table(table[last_table], ta_size[last_table], - name, value, last_pos); - if (pos) /* success */ + for(i=0; iprefix) + { + int len = strlen(settings[i].filename_setting->prefix); + if (!strncmp(value,settings[i].filename_setting->prefix,len)) + { + strncpy(storage,&value[len],MAX_PATH); + } + else strncpy(storage,value,MAX_PATH); + } + else strncpy(storage,value,MAX_PATH); + if (settings[i].filename_setting->suffix) + { + char *s = strcasestr(storage,settings[i].filename_setting->suffix); + if (s) *s = '\0'; + } + strncpy((char*)settings[i].setting,storage, + settings[i].filename_setting->max_len); + ((char*)settings[i].setting) + [settings[i].filename_setting->max_len-1] = '\0'; + break; + } + } + break; + } /* if (!strcmp(name,settings[i].cfg_name)) */ + } /* for(...) */ + } /* while(...) */ close(fd); - settings_apply(); settings_save(); + if (apply) + settings_apply(); return true; } - -/* helper to save content of global_settings into a file, - as described per table */ -static void save_cfg_table(const struct bit_entry* p_table, int count, int fd) -{ - long value; /* 32 bit content */ - int i; - const struct bit_entry* p_run = p_table; /* start after the size info */ - count--; /* first is excluded from loop */ - - for (i=0; icfg_name == NULL) - continue; /* this value is not to be saved */ - - /* could do a memcpy, but that would be endian-dependent */ - switch(p_run->byte_size) - { - case 1: - if (p_run->bit_size & SIGNED) /* signed? */ - value = ((char*)&global_settings)[p_run->settings_offset]; - else - value = ((unsigned char*)&global_settings)[p_run->settings_offset]; - break; - case 2: - if (p_run->bit_size & SIGNED) /* signed? */ - value = ((short*)&global_settings)[p_run->settings_offset/2]; - else - value = ((unsigned short*)&global_settings)[p_run->settings_offset/2]; - break; - case 4: - value = ((unsigned int*)&global_settings)[p_run->settings_offset/4]; - break; - default: - DEBUGF( "illegal size!" ); - continue; - } - - if (p_run->cfg_val == NULL) /* write as number */ - { - fdprintf(fd, "%s: %ld\r\n", p_run->cfg_name, value); - } -#ifdef HAVE_LCD_COLOR - else if (!strcasecmp(p_run->cfg_val, "rgb")) - { - fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name, - (int)RGB_UNPACK_RED(value), - (int)RGB_UNPACK_GREEN(value), - (int)RGB_UNPACK_BLUE(value)); - } -#endif - else /* write as item */ - { - const char* p = p_run->cfg_val; - - fdprintf(fd, "%s: ", p_run->cfg_name); - - while(value >= 0) - { - char c = *p++; /* currently processed char */ - if (c == ',') /* separator */ - value--; - else if (c == '\0') /* end of string */ - break; /* not found */ - else if (value == 0) /* the right place */ - write(fd, &c, 1); /* char by char, this is lame, OK */ - } - - fdprintf(fd, "\r\n"); - if (p_run->cfg_val != off_on) /* explaination for non-bool */ - fdprintf(fd, "# (possible values: %s)\r\n", p_run->cfg_val); - } - } -} - bool settings_save_config(void) { - int fd; char filename[MAX_PATH]; create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2 @@ -1779,11 +789,7 @@ bool settings_save_config(void) /* allow user to modify filename */ while (true) { if (!kbd_input(filename, sizeof filename)) { - fd = creat(filename, O_WRONLY); - if (fd < 0) - gui_syncsplash(HZ, true, str(LANG_FAILED)); - else - break; + break; } else { gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL)); @@ -1791,145 +797,43 @@ bool settings_save_config(void) } } - fdprintf(fd, "# .cfg file created by rockbox %s - " - "http://www.rockbox.org\r\n#\r\n#\r\n# wps / rwps / language" - " / font / fmpreset / backdrop \r\n#\r\n", appsversion); - - if (global_settings.wps_file[0] != 0) - fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR, - global_settings.wps_file); - -#ifdef HAVE_REMOTE_LCD - if (global_settings.rwps_file[0] != 0) - fdprintf(fd, "rwps: %s/%s.rwps\r\n", WPS_DIR, - global_settings.rwps_file); -#endif - - if (global_settings.lang_file[0] != 0) - fdprintf(fd, "lang: %s/%s.lng\r\n", LANG_DIR, - global_settings.lang_file); - -#ifdef HAVE_LCD_BITMAP - if (global_settings.font_file[0] != 0) - fdprintf(fd, "font: %s/%s.fnt\r\n", FONT_DIR, - global_settings.font_file); -#endif - -#if LCD_DEPTH > 1 - if (global_settings.backdrop_file[0] != 0) - fdprintf(fd, "backdrop: %s/%s.bmp\r\n", BACKDROP_DIR, - global_settings.backdrop_file); -#endif - -#ifdef CONFIG_TUNER - if (global_settings.fmr_file[0] != 0) - fdprintf(fd, "fmr: %s/%s.fmr\r\n", FMPRESET_PATH, - global_settings.fmr_file); -#endif - -#ifdef HAVE_LCD_BITMAP - if (global_settings.kbd_file[0] != 0) - fdprintf(fd, "keyboard: %s/%s.kbd\r\n", ROCKBOX_DIR, - global_settings.kbd_file); -#endif - - /* here's the action: write values to file, specified via table */ - save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd); - save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd); - - close(fd); - - gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED)); + if (settings_write_config(filename)) + gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED)); + else gui_syncsplash(HZ, true, str(LANG_FAILED)); return true; } -/* helper to load defaults from table into global_settings members */ -static void default_table(const struct bit_entry* p_table, int count) -{ - int i; - - for (i=1; i 1 - global_settings.backdrop_file[0] = '\0'; -#endif -#ifdef HAVE_LCD_COLOR - global_settings.fg_color = LCD_DEFAULT_FG; - global_settings.bg_color = LCD_DEFAULT_BG; -#endif -#ifdef HAVE_LCD_BITMAP - global_settings.kbd_file[0] = '\0'; -#endif - global_settings.hold_lr_for_scroll_in_list = true; - + for(i=0; isetting); + else *(int*)settings[i].setting = settings[i].default_val.int_; + break; + case F_T_BOOL: + *(bool*)settings[i].setting = settings[i].default_val.bool_; + break; + case F_T_CHARPTR: + case F_T_UCHARPTR: + strncpy((char*)settings[i].setting, + settings[i].default_val.charptr,MAX_FILENAME); + break; + } + } /* for(...) */ #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC enc_global_settings_reset(); #endif diff --git a/apps/settings.h b/apps/settings.h index b5c673faa0..eee24f187b 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -54,6 +54,9 @@ #define REC_BASE_DIR "/recordings" #define EQS_DIR ROCKBOX_DIR "/eqs" #define CODECS_DIR ROCKBOX_DIR"/codecs" +#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets" + +#define CONFIGFILE ROCKBOX_DIR "/config.cfg" #define MAX_FILENAME 20 @@ -547,7 +550,6 @@ struct opt_items { /* prototypes */ -void settings_calc_config_sector(void); int settings_save(void); void settings_load(int which); void settings_reset(void); @@ -556,7 +558,7 @@ void settings_apply(void); void settings_apply_pm_range(void); void settings_display(void); -bool settings_load_config(const char* file); +bool settings_load_config(const char* file, bool apply); bool settings_save_config(void); bool set_bool_options(const char* string, bool* variable, const char* yes_str, int yes_voice, diff --git a/apps/settings_list.c b/apps/settings_list.c new file mode 100644 index 0000000000..313524ba81 --- /dev/null +++ b/apps/settings_list.c @@ -0,0 +1,608 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2007 Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include + +#include "lang.h" +#include "lcd.h" +#include "settings.h" +#include "settings_list.h" +#include "sound.h" + +/* some sets of values which are used more than once, to save memory */ +static const char off_on[] = "off,on"; +static const char off_on_ask[] = "off,on,ask"; +static const char off_number_spell_hover[] = "off,number,spell,hover"; +#ifdef HAVE_LCD_BITMAP +static const char graphic_numeric[] = "graphic,numeric"; +#endif + +#ifdef HAVE_RECORDING +/* keep synchronous to trig_durations and + trigger_times in settings_apply_trigger */ +static const char trig_durations_conf [] = + "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min"; +/* these should be in the config.h files */ +#if CONFIG_CODEC == MAS3587F +# define DEFAULT_REC_MIC_GAIN 8 +# define DEFAULT_REC_LEFT_GAIN 2 +# define DEFAULT_REC_RIGHT_GAIN 2 +#elif CONFIG_CODEC == SWCODEC +# ifdef HAVE_UDA1380 +# define DEFAULT_REC_MIC_GAIN 16 +# define DEFAULT_REC_LEFT_GAIN 0 +# define DEFAULT_REC_RIGHT_GAIN 0 +# elif defined(HAVE_TLV320) +# define DEFAULT_REC_MIC_GAIN 0 +# define DEFAULT_REC_LEFT_GAIN 0 +# define DEFAULT_REC_RIGHT_GAIN 0 +# elif defined(HAVE_WM8975) +# define DEFAULT_REC_MIC_GAIN 16 +# define DEFAULT_REC_LEFT_GAIN 0 +# define DEFAULT_REC_RIGHT_GAIN 0 +# elif defined(HAVE_WM8758) +# define DEFAULT_REC_MIC_GAIN 16 +# define DEFAULT_REC_LEFT_GAIN 0 +# define DEFAULT_REC_RIGHT_GAIN 0 +# elif defined(HAVE_WM8731) +# define DEFAULT_REC_MIC_GAIN 16 +# define DEFAULT_REC_LEFT_GAIN 0 +# define DEFAULT_REC_RIGHT_GAIN 0 +# endif +#endif + +#endif /* HAVE_RECORDING */ + +#if defined(CONFIG_BACKLIGHT) +static const char backlight_times_conf [] = + "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90"; +#endif + + +#define GS(a) &global_settings.a + +#define NVRAM(bytes) (bytes< 1 + {F_T_INT,GS(max_files_in_playlist),INT(10000), + "max files in playlist",NULL,UNUSED}, + {F_T_INT,GS(max_files_in_dir),INT(400), + "max files in dir",NULL,UNUSED}, +#else + {F_T_INT,GS(max_files_in_playlist),INT(1000), + "max files in playlist",NULL,UNUSED}, + {F_T_INT,GS(max_files_in_dir),INT(200), + "max files in dir",NULL,UNUSED}, +#endif + {F_T_INT,GS(battery_capacity),INT(BATTERY_CAPACITY_DEFAULT), + "battery capacity",NULL,UNUSED}, +#ifdef CONFIG_CHARGING + OFFON_SETTING(0,car_adapter_mode,false,"car adapter mode", NULL), +#endif + /* tuner */ +#ifdef CONFIG_TUNER + OFFON_SETTING(0,fm_force_mono,false,"force fm mono", NULL), + SYSTEM_SETTING(NVRAM(4),last_frequency,0), +#endif + +#if BATTERY_TYPES_COUNT > 1 + {F_T_INT,GS(battery_type),INT(0), + "battery type","alkaline,nimh",UNUSED}, +#endif +#ifdef HAVE_REMOTE_LCD + /* remote lcd */ + {F_T_INT,GS(remote_contrast),INT(DEFAULT_REMOTE_CONTRAST_SETTING), + "remote contrast",NULL,UNUSED}, + OFFON_SETTING(0,remote_invert,false,"remote invert", NULL), + OFFON_SETTING(0,remote_flip_display,false,"remote flip display", NULL), + {F_T_INT,GS(remote_backlight_timeout),INT(6), + "remote backlight timeout",backlight_times_conf,UNUSED}, +#ifdef CONFIG_CHARGING + {F_T_INT,GS(remote_backlight_timeout_plugged),INT(11), + "remote backlight timeout plugged",backlight_times_conf,UNUSED}, +#endif +#ifdef HAVE_REMOTE_LCD_TICKING + OFFON_SETTING(0,remote_reduce_ticking,false,"remote reduce ticking", NULL), +#endif +#endif + +#ifdef CONFIG_BACKLIGHT + OFFON_SETTING(0,bl_filter_first_keypress,false, + "backlight filters first keypress", NULL), +#ifdef HAVE_REMOTE_LCD + OFFON_SETTING(0,remote_bl_filter_first_keypress,false, + "backlight filters first remote keypress", NULL), +#endif +#endif /* CONFIG_BACKLIGHT */ + +/** End of old RTC config block **/ + +#ifdef CONFIG_BACKLIGHT + OFFON_SETTING(0,caption_backlight,false,"caption backlight",NULL), +#ifdef HAVE_REMOTE_LCD + OFFON_SETTING(0,remote_caption_backlight,false,"remote caption backlight",NULL), +#endif +#endif /* CONFIG_BACKLIGHT */ +#ifdef HAVE_BACKLIGHT_BRIGHTNESS + {F_T_INT,GS(brightness), INT(DEFAULT_BRIGHTNESS_SETTING), "brightness", NULL ,UNUSED}, +#endif +#ifdef HAVE_BACKLIGHT_PWM_FADING + /* backlight fading */ + {F_T_INT,GS(backlight_fade_in),INT(1), + "backlight fade in","off,500ms,1s,2s",UNUSED}, + {F_T_INT,GS(backlight_fade_out),INT(1), + "backlight fade out","off,500ms,1s,2s,3s,4s,5s,10s",UNUSED}, +#endif + {F_T_INT,GS(scroll_speed),INT(9),"scroll speed",NULL,UNUSED}, + {F_T_INT,GS(scroll_delay),INT(100),"scroll delay",NULL,UNUSED}, + {F_T_INT,GS(bidir_limit),INT(50),"bidir limit",NULL,UNUSED}, +#ifdef HAVE_REMOTE_LCD + {F_T_INT,GS(remote_scroll_speed),INT(9),"remote scroll speed",NULL,UNUSED}, + {F_T_INT,GS(remote_scroll_step),INT(6),"remote scroll step",NULL,UNUSED}, + {F_T_INT,GS(remote_scroll_delay),INT(100),"remote scroll delay",NULL,UNUSED}, + {F_T_INT,GS(remote_bidir_limit),INT(50),"remote bidir limit",NULL,UNUSED}, +#endif +#ifdef HAVE_LCD_BITMAP + OFFON_SETTING(0,offset_out_of_view,false,"Screen Scrolls Out Of View",NULL), + {F_T_INT,GS(scroll_step),INT(6),"scroll step",NULL,UNUSED}, + {F_T_INT,GS(screen_scroll_step),INT(16),"screen scroll step",NULL,UNUSED}, +#endif /* HAVE_LCD_BITMAP */ + OFFON_SETTING(0,scroll_paginated,false,"scroll paginated",NULL), +#ifdef HAVE_LCD_COLOR + {F_T_INT|F_RGB,GS(fg_color),INT(LCD_DEFAULT_FG),"foreground color",NULL,UNUSED}, + {F_T_INT|F_RGB,GS(bg_color),INT(LCD_DEFAULT_BG),"background color",NULL,UNUSED}, +#endif + /* more playback */ + OFFON_SETTING(0,play_selected,true,"play selected",NULL), + OFFON_SETTING(0,fade_on_stop,true,"volume fade",NULL), + {F_T_INT,GS(ff_rewind_min_step),INT(FF_REWIND_1000), + "scan min step","1,2,3,4,5,6,8,10,15,20,25,30,45,60",UNUSED}, + {F_T_INT,GS(ff_rewind_accel),INT(3),"scan accel",NULL,UNUSED}, +#if CONFIG_CODEC == SWCODEC + {F_T_INT,GS(buffer_margin),INT(0),"antiskip", + "5s,15s,30s,1min,2min,3min,5min,10min",UNUSED}, +#else + {F_T_INT,GS(buffer_margin),INT(0),"antiskip",NULL,UNUSED}, +#endif + /* disk */ +#ifndef HAVE_MMC +#ifdef HAVE_ATA_POWER_OFF + OFFON_SETTING(0,disk_poweroff,false,"disk poweroff",NULL), +#endif + {F_T_INT,GS(disk_spindown),INT(5),"disk spindown",NULL,UNUSED}, +#endif /* HAVE_MMC */ + /* browser */ + {F_T_INT,GS(dirfilter),INT(SHOW_SUPPORTED),"show files", + "all,supported,music,playlists" +#ifdef HAVE_TAGCACHE + ",id3 database" +#endif + ,UNUSED}, + OFFON_SETTING(0,sort_case,false,"sort case",NULL), + OFFON_SETTING(0,browse_current,false,"follow playlist",NULL), + OFFON_SETTING(0,playlist_viewer_icons,true, + "playlist viewer icons",NULL), + OFFON_SETTING(0,playlist_viewer_indices,true, + "playlist viewer indices",NULL), + {F_T_INT,GS(recursive_dir_insert),INT(RECURSE_OFF), + "recursive directory insert",off_on_ask,UNUSED}, + /* bookmarks */ + {F_T_INT,GS(autocreatebookmark),INT(BOOKMARK_NO),"autocreate bookmarks", + "off,on,ask,recent only - on,recent only - ask",UNUSED}, + {F_T_INT,GS(autoloadbookmark),INT(BOOKMARK_NO), + "autoload bookmarks",off_on_ask,UNUSED}, + {F_T_INT,GS(usemrb),INT(BOOKMARK_NO), + "use most-recent-bookmarks","off,on,unique only",UNUSED}, +#ifdef HAVE_LCD_BITMAP + /* peak meter */ + {F_T_INT,GS(peak_meter_clip_hold),INT(16),"peak meter clip hold", + "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min" + ",3min,5min,10min,20min,45min,90min",UNUSED}, + {F_T_INT,GS(peak_meter_hold),INT(3),"peak meter hold", + "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min",UNUSED}, + {F_T_INT,GS(peak_meter_release),INT(8),"peak meter release",NULL,UNUSED}, + OFFON_SETTING(0,peak_meter_dbfs,true,"peak meter dbfs",NULL), + {F_T_INT,GS(peak_meter_min),INT(60),"peak meter min",NULL,UNUSED}, + {F_T_INT,GS(peak_meter_max),INT(0),"peak meter max",NULL,UNUSED}, +#endif +#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) + {F_T_INT,GS(mdb_strength),INT(0),"mdb strength",NULL,UNUSED}, + {F_T_INT,GS(mdb_harmonics),INT(0),"mdb harmonics",NULL,UNUSED}, + {F_T_INT,GS(mdb_center),INT(0),"mdb center",NULL,UNUSED}, + {F_T_INT,GS(mdb_shape),INT(0),"mdb shape",NULL,UNUSED}, + OFFON_SETTING(0,mdb_enable,false,"mdb enable",NULL), +#endif +#if CONFIG_CODEC == MAS3507D + OFFON_SETTING(0,line_in,false,"line in",NULL), +#endif + /* voice */ + {F_T_INT,GS(talk_dir),INT(0),"talk dir",off_number_spell_hover,UNUSED}, + {F_T_INT,GS(talk_file),INT(0),"talk file",off_number_spell_hover,UNUSED}, + OFFON_SETTING(0,talk_menu,true,"talk menu",NULL), + + {F_T_INT,GS(sort_file),INT(0),"sort files","alpha,oldest,newest,type",UNUSED}, + {F_T_INT,GS(sort_dir),INT(0),"sort dirs","alpha,oldest,newest",UNUSED}, + BOOL_SETTING(0,id3_v1_first,false,"id3 tag priority","v2-v1,v1-v2", + LANG_ID3_V2_FIRST,LANG_ID3_V1_FIRST,NULL), + +#ifdef HAVE_RECORDING + /* recording */ + OFFON_SETTING(0,recscreen_on,false,"recscreen on",NULL), + OFFON_SETTING(0,rec_startup,false,"rec screen on startup",NULL), + {F_T_INT,GS(rec_timesplit),INT(0),"rec timesplit", + "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00," + "04:00,06:00,08:00,10:00,12:00,18:00,24:00",UNUSED}, + {F_T_INT,GS(rec_sizesplit),INT(0),"rec sizesplit", + "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB," + "256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB",UNUSED}, + {F_T_INT,GS(rec_channels),INT(0),"rec channels","stereo,mono",UNUSED}, + {F_T_INT,GS(rec_split_type),INT(0),"rec split type","Split, Stop",UNUSED}, + {F_T_INT,GS(rec_split_method),INT(0),"rec split method","Time,Filesize",UNUSED}, + {F_T_INT,GS(rec_source),INT(0),"rec source","mic,line" +#ifdef HAVE_SPDIF_IN + ",spdif" +#endif +#ifdef HAVE_FMRADIO_IN + ",fmradio" +#endif + ,UNUSED}, + {F_T_INT,GS(rec_prerecord_time),INT(0),"prerecording time",NULL,UNUSED}, + {F_T_INT,GS(rec_directory),INT(0),"rec directory",REC_BASE_DIR ",current",UNUSED}, +#ifdef CONFIG_BACKLIGHT + {F_T_INT,GS(cliplight),INT(0),"cliplight","off,main,both,remote",UNUSED}, +#endif + {F_T_INT,GS(rec_mic_gain),INT(DEFAULT_REC_MIC_GAIN), + "rec mic gain",NULL,UNUSED}, + {F_T_INT,GS(rec_left_gain),INT(DEFAULT_REC_LEFT_GAIN), + "rec left gain",NULL,UNUSED}, + {F_T_INT,GS(rec_right_gain),INT(DEFAULT_REC_RIGHT_GAIN), + "rec right gain",NULL,UNUSED}, +#if CONFIG_CODEC == MAS3587F + {F_T_INT,GS(rec_frequency),INT(0),"rec frequency","44,48,32,22,24,16",UNUSED}, + {F_T_INT,GS(rec_quality),INT(5),"rec quality",NULL,UNUSED}, + OFFON_SETTING(0,rec_editable,false,"editable recordings",NULL), +#endif /* CONFIG_CODEC == MAS3587F */ +#if CONFIG_CODEC == SWCODEC + {F_T_INT,GS(rec_frequency),INT(REC_FREQ_DEFAULT), + "rec frequency",REC_FREQ_CFG_VAL_LIST,UNUSED}, + {F_T_INT,GS(rec_format),INT(REC_FORMAT_DEFAULT), + "rec format",REC_FORMAT_CFG_VAL_LIST,UNUSED}, + /** Encoder settings start - keep these together **/ + /* aiff_enc */ + /* (no settings yet) */ + /* mp3_enc */ + {F_T_INT,GS(mp3_enc_config.bitrate),INT(MP3_ENC_BITRATE_CFG_DEFAULT), + "mp3_enc bitrate",MP3_ENC_BITRATE_CFG_VALUE_LIST,UNUSED}, + /* wav_enc */ + /* (no settings yet) */ + /* wavpack_enc */ + /* (no settings yet) */ + /** Encoder settings end **/ +#endif /* CONFIG_CODEC == SWCODEC */ + /* values for the trigger */ + {F_T_INT,GS(rec_start_thres),INT(-35), + "trigger start threshold",NULL,UNUSED}, + {F_T_INT,GS(rec_stop_thres),INT(-45), + "trigger stop threshold",NULL,UNUSED}, + {F_T_INT,GS(rec_start_duration),INT(0), + "trigger start duration",trig_durations_conf,UNUSED}, + {F_T_INT,GS(rec_stop_postrec),INT(2), + "trigger stop postrec",trig_durations_conf,UNUSED}, + {F_T_INT,GS(rec_stop_gap),INT(1), + "trigger min gap",trig_durations_conf,UNUSED}, + {F_T_INT,GS(rec_trigger_mode),INT(0), + "trigger mode","off,once,repeat",UNUSED}, +#endif /* HAVE_RECORDING */ + +#ifdef HAVE_SPDIF_POWER + OFFON_SETTING(0,spdif_enable,false,"spdif enable",NULL), +#endif + {F_T_INT,GS(next_folder),INT(FOLDER_ADVANCE_OFF), + "folder navigation","off,on,random",UNUSED}, + OFFON_SETTING(0,runtimedb,false,"gather runtime data",NULL), + +#if CONFIG_CODEC == SWCODEC + OFFON_SETTING(0,replaygain,false,"replaygain",NULL), + {F_T_INT,GS(replaygain_type),INT(REPLAYGAIN_ALBUM), + "replaygain type","track,album,track shuffle",UNUSED}, + OFFON_SETTING(0,replaygain_noclip,false,"replaygain noclip",NULL), + {F_T_INT,GS(replaygain_preamp),INT(0),"replaygain preamp",NULL,UNUSED}, + {F_T_INT,GS(beep),INT(0),"beep","off,weak,moderate,strong",UNUSED}, + {F_T_INT,GS(crossfade),INT(0),"crossfade", + "off,shuffle,track skip,shuffle and track skip,always",UNUSED}, + {F_T_INT,GS(crossfade_fade_in_delay),INT(0), + "crossfade fade in delay",NULL,UNUSED}, + {F_T_INT,GS(crossfade_fade_out_delay),INT(0), + "crossfade fade out delay",NULL,UNUSED}, + {F_T_INT,GS(crossfade_fade_in_duration),INT(0), + "crossfade fade in duration",NULL,UNUSED}, + {F_T_INT,GS(crossfade_fade_out_duration),INT(0), + "crossfade fade out duration",NULL,UNUSED}, + {F_T_INT,GS(crossfade_fade_out_mixmode),INT(0), + "crossfade fade out mode","crossfade,mix",UNUSED}, + {F_T_INT,GS(crossfade),INT(0),"crossfade", + "off,shuffle,track skip,shuffle and track skip,always",UNUSED}, + OFFON_SETTING(0,crossfeed,false,"crossfeed",NULL), + {F_T_INT,GS(crossfeed_direct_gain),INT(15), + "crossfeed direct gain",NULL,UNUSED}, + {F_T_INT,GS(crossfeed_cross_gain),INT(60), + "crossfeed cross gain",NULL,UNUSED}, + {F_T_INT,GS(crossfeed_hf_attenuation),INT(160), + "crossfeed hf attenuation",NULL,UNUSED}, + {F_T_INT,GS(crossfeed_hf_cutoff),INT(700), + "crossfeed hf cutoff",NULL,UNUSED}, + + /* equalizer */ + OFFON_SETTING(0,eq_enabled,false,"eq enabled",NULL), + {F_T_INT,GS(eq_precut),INT(0), + "eq precut",NULL,UNUSED}, + /* 0..32768 Hz */ + {F_T_INT,GS(eq_band0_cutoff),INT(0), + "eq band 0 cutoff",NULL,UNUSED}, + {F_T_INT,GS(eq_band1_cutoff),INT(200), + "eq band 1 cutoff",NULL,UNUSED}, + {F_T_INT,GS(eq_band2_cutoff),INT(800), + "eq band 2 cutoff",NULL,UNUSED}, + {F_T_INT,GS(eq_band3_cutoff),INT(4000), + "eq band 3 cutoff",NULL,UNUSED}, + {F_T_INT,GS(eq_band4_cutoff),INT(12000), + "eq band 4 cutoff",NULL,UNUSED}, + /* 0..64 (or 0.0 to 6.4) */ + {F_T_INT,GS(eq_band0_q),INT(7), + "eq band 0 q",NULL,UNUSED}, + {F_T_INT,GS(eq_band1_q),INT(10), + "eq band 1 q",NULL,UNUSED}, + {F_T_INT,GS(eq_band2_q),INT(10), + "eq band 2 q",NULL,UNUSED}, + {F_T_INT,GS(eq_band3_q),INT(10), + "eq band 3 q",NULL,UNUSED}, + {F_T_INT,GS(eq_band4_q),INT(7), + "eq band 4 q",NULL,UNUSED}, + /* -240..240 (or -24db to +24db) */ + {F_T_INT,GS(eq_band0_gain),INT(0), + "eq band 0 gain",NULL,UNUSED}, + {F_T_INT,GS(eq_band1_gain),INT(0), + "eq band 1 gain",NULL,UNUSED}, + {F_T_INT,GS(eq_band2_gain),INT(0), + "eq band 2 gain",NULL,UNUSED}, + {F_T_INT,GS(eq_band3_gain),INT(0), + "eq band 3 gain",NULL,UNUSED}, + {F_T_INT,GS(eq_band4_gain),INT(0), + "eq band 4 gain",NULL,UNUSED}, + + /* dithering */ + OFFON_SETTING(0,dithering_enabled,false,"dithering enabled",NULL), +#endif +#ifdef HAVE_DIRCACHE + OFFON_SETTING(0,dircache,false,"dircache",NULL), + SYSTEM_SETTING(NVRAM(4),dircache_size,0), +#endif + +#ifdef HAVE_TAGCACHE +#ifdef HAVE_TC_RAMCACHE + OFFON_SETTING(0,tagcache_ram,false,"tagcache_ram",NULL), +#endif + OFFON_SETTING(0,tagcache_autoupdate,false,"tagcache_autoupdate",NULL), +#endif + + {F_T_INT,GS(default_codepage),INT(0),"default codepage", + "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256," + "iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256",UNUSED}, + + OFFON_SETTING(0,warnon_erase_dynplaylist,false, + "warn when erasing dynamic playlist",NULL), + +#ifdef CONFIG_BACKLIGHT +#ifdef HAS_BUTTON_HOLD + {F_T_INT,GS(backlight_on_button_hold),INT(0), + "backlight on button hold","normal,off,on",UNUSED}, +#endif + +#ifdef HAVE_LCD_SLEEP + {F_T_INT,GS(lcd_sleep_after_backlight_off),INT(3), + "lcd sleep after backlight off", + "always,never,5,10,15,20,30,45,60,90",UNUSED}, +#endif +#endif /* CONFIG_BACKLIGHT */ + +#ifdef HAVE_WM8758 + OFFON_SETTING(0,eq_hw_enabled,false, + "eq hardware enabled",NULL), + + {F_T_INT,GS(eq_hw_band0_cutoff),INT(1), + "eq hardware band 0 cutoff", + "80Hz,105Hz,135Hz,175Hz",UNUSED}, + {F_T_INT,GS(eq_hw_band0_gain),INT(0), + "eq hardware band 0 gain",NULL,UNUSED}, + + {F_T_INT,GS(eq_hw_band1_center),INT(1), + "eq hardware band 1 center", + "230Hz,300Hz,385Hz,500Hz",UNUSED}, + {F_T_INT,GS(eq_hw_band1_bandwidth),INT(0), + "eq hardware band 1 bandwidth","narrow,wide",UNUSED}, + {F_T_INT,GS(eq_hw_band1_gain),INT(0), + "eq hardware band 1 gain",NULL,UNUSED}, + + {F_T_INT,GS(eq_hw_band2_center),INT(1), + "eq hardware band 2 center", + "650Hz,850Hz,1.1kHz,1.4kHz",UNUSED}, + {F_T_INT,GS(eq_hw_band2_bandwidth),INT(0), + "eq hardware band 2 bandwidth","narrow,wide",UNUSED}, + {F_T_INT,GS(eq_hw_band2_gain),INT(0), + "eq hardware band 1 gain",NULL,UNUSED}, + + {F_T_INT,GS(eq_hw_band3_center),INT(1), + "eq hardware band 3 center", + "1.8kHz,2.4kHz,3.2kHz,4.1kHz",UNUSED}, + {F_T_INT,GS(eq_hw_band3_bandwidth),INT(0), + "eq hardware band 3 bandwidth","narrow,wide",UNUSED}, + {F_T_INT,GS(eq_hw_band3_gain),INT(0), + "eq hardware band 3 gain",NULL,UNUSED}, + + {F_T_INT,GS(eq_hw_band4_cutoff),INT(1), + "eq hardware band 4 cutoff", + "5.3kHz,6.9kHz,9kHz,11.7kHz",UNUSED}, + {F_T_INT,GS(eq_hw_band4_gain),INT(0), + "eq hardware band 0 gain",NULL,UNUSED}, +#endif + + OFFON_SETTING(0,hold_lr_for_scroll_in_list,true, + "hold_lr_for_scroll_in_list",NULL), + {F_T_INT,GS(show_path_in_browser),INT(SHOW_PATH_OFF), + "show path in browser","off,current directory,full path",UNUSED}, + +#ifdef HAVE_AGC + {F_T_INT,GS(rec_agc_preset_mic),INT(1),"agc mic preset",NULL,UNUSED}, + {F_T_INT,GS(rec_agc_preset_line),INT(1),"agc line preset",NULL,UNUSED}, + {F_T_INT,GS(rec_agc_maxgain_mic),INT(104), + "agc maximum mic gain",NULL,UNUSED}, + {F_T_INT,GS(rec_agc_maxgain_line),INT(96), + "agc maximum line gain",NULL,UNUSED}, + {F_T_INT,GS(rec_agc_cliptime),INT(1), + "agc cliptime","0.2s,0.4s,0.6s,0.8,1s",UNUSED}, +#endif + +#ifdef HAVE_REMOTE_LCD +#ifdef HAS_REMOTE_BUTTON_HOLD + {F_T_INT,GS(remote_backlight_on_button_hold),INT(0), + "remote backlight on button hold","normal,off,on",UNUSED}, +#endif +#endif +#ifdef HAVE_HEADPHONE_DETECTION + {F_T_INT,GS(unplug_mode),INT(0),"pause on headphone unplug",NULL,UNUSED}, + {F_T_INT,GS(unplug_rw),INT(0),"rewind duration on pause",NULL,UNUSED}, + OFFON_SETTING(0,unplug_autoresume,false, + "disable autoresume if phones not present",NULL), +#endif +#ifdef CONFIG_TUNER + {F_T_INT,GS(fm_region),INT(0),"fm_region","eu,us,jp,kr",UNUSED}, +#endif + + OFFON_SETTING(0,audioscrobbler,false,"Last.fm Logging",NULL), + +#ifdef HAVE_RECORDING + {F_T_INT,GS(rec_trigger_type),INT(0),"trigger type","stop,pause,nf stp",UNUSED}, +#endif + + /** settings not in the old config blocks **/ +#ifdef CONFIG_TUNER + FILENAME_SETTING(0,fmr_file,"fmr","",FMPRESET_PATH "/",".fmr",MAX_FILENAME+1), +#endif + FILENAME_SETTING(0,font_file,"font","",FONT_DIR "/",".fnt",MAX_FILENAME+1), + FILENAME_SETTING(0,wps_file, "wps","",WPS_DIR "/",".wps",MAX_FILENAME+1), + FILENAME_SETTING(0,lang_file,"lang","",LANG_DIR "/",".lng",MAX_FILENAME+1), +#ifdef HAVE_REMOTE_LCD + FILENAME_SETTING(0,rwps_file,"rwps","",WPS_DIR "/",".rwps",MAX_FILENAME+1), +#endif +#if LCD_DEPTH > 1 + FILENAME_SETTING(0,backdrop_file,"backdrop","",BACKDROP_DIR "/",".bmp",MAX_FILENAME+1), +#endif +#ifdef HAVE_LCD_BITMAP + FILENAME_SETTING(0,lang_file,"kbd","",ROCKBOX_DIR "/",".kbd",MAX_FILENAME+1), +#endif + +}; + +const int nb_settings = sizeof(settings)/sizeof(*settings); diff --git a/apps/settings_list.h b/apps/settings_list.h new file mode 100644 index 0000000000..01e8cea1e7 --- /dev/null +++ b/apps/settings_list.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2007 Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __SETTINGSLIST_H +#define __SETTINGSLIST_H +#include +#include +#include +#include +#include "inttypes.h" + +union storage_type { + int int_; + unsigned int uint_; + bool bool_; + char *charptr; + unsigned char *ucharptr; +}; +/* the variable type for the setting */ +#define F_T_INT 1 +#define F_T_UINT 2 +#define F_T_BOOL 3 +#define F_T_CHARPTR 4 +#define F_T_UCHARPTR 5 +#define F_T_MASK 0x7 + +struct sound_setting { + int setting; /* from the enum in firmware/sound.h */ +}; +#define F_T_SOUND 0x8 /* this variable uses the set_sound stuff, \ + | with one of the above types (usually F_T_INT) \ + These settings get the default from sound_default(setting); */ +struct bool_setting { + void (*option_callback)(bool); + int lang_yes; + int lang_no; +}; +#define F_BOOL_SETTING F_T_BOOL|0x10 +#define F_RGB 0x20 + +struct int_setting { + void (*option_callback)(int); + int min; + int max; + int step; +}; +#define F_NVRAM_BYTES_MASK 0xE00 /*0-4 bytes can be stored */ +#define F_NVRAM_MASK_SHIFT 9 +#define NVRAM_CONFIG_VERSION 1 +/* Above define should be bumped if +- a new NVRAM setting is added between 2 other NVRAM settings +- number of bytes for a NVRAM setting is changed +- a NVRAM setting is removed +*/ + +struct filename_setting { + const char* prefix; + const char* suffix; + int max_len; +}; +#define F_FILENAME 0x40 +struct settings_list { + uint32_t flags; /* ____ ____ ____ ____ ____ NNN_ _FRB STTT */ + void *setting; + union storage_type default_val; + const char *cfg_name; /* this settings name in the cfg file */ + const char *cfg_vals; /*comma seperated legal values, or NULL */ + /* used with F_T_UCHARPTR this is the folder prefix */ + union { + void *RESERVED; /* to stop compile errors, will be removed */ + struct sound_setting *sound_setting; /* use F_T_SOUND for this */ + struct bool_setting *bool_setting; /* F_BOOL_SETTING */ + struct filename_setting *filename_setting; /* use F_FILENAME */ + }; +}; + +#ifndef PLUGIN +/* not needed for plugins and just causes compile error, + possibly fix proberly later */ +extern const struct settings_list settings[]; +extern const int nb_settings; + +#endif + +#endif diff --git a/apps/settings_menu.c b/apps/settings_menu.c index fef7592266..04fd64b1ca 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -1844,6 +1844,7 @@ static bool reset_settings(void) case YESNO_YES: settings_reset(); settings_apply(); + settings_save(); break; case YESNO_NO: break; diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 4e41ef2b1f..4dd0fdcc49 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -81,7 +81,7 @@ static int poweroff_timeout = 2*HZ; #ifdef HAVE_LBA48 static bool lba48 = false; /* set for 48 bit addressing */ #endif -static long ata_stack[DEFAULT_STACK_SIZE/sizeof(long)]; +static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)]; static const char ata_thread_name[] = "ata"; static struct event_queue ata_queue; static bool initialized = false; diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index 7382788b60..a549624b2c 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c @@ -92,9 +92,9 @@ static struct mutex mmc_mutex; #ifdef HAVE_HOTSWAP static bool mmc_monitor_enabled = true; -static long mmc_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; +static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)]; #else -static long mmc_stack[DEFAULT_STACK_SIZE/sizeof(long)]; +static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)]; #endif static const char mmc_thread_name[] = "mmc"; static struct event_queue mmc_queue; -- cgit v1.2.3