summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/SOURCES1
-rw-r--r--apps/filetree.c2
-rw-r--r--apps/main.c3
-rw-r--r--apps/recorder/radio.h1
-rw-r--r--apps/settings.c1714
-rw-r--r--apps/settings.h6
-rw-r--r--apps/settings_list.c608
-rw-r--r--apps/settings_list.h100
-rw-r--r--apps/settings_menu.c1
-rw-r--r--firmware/drivers/ata.c2
-rw-r--r--firmware/drivers/ata_mmc.c4
11 files changed, 1027 insertions, 1415 deletions
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
20plugin.c 20plugin.c
21screens.c 21screens.c
22settings.c 22settings.c
23settings_list.c
23settings_menu.c 24settings_menu.c
24sound_menu.c 25sound_menu.c
25status.c 26status.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)
486 486
487 case TREE_ATTR_CFG: 487 case TREE_ATTR_CFG:
488 gui_syncsplash(0, true, str(LANG_WAIT)); 488 gui_syncsplash(0, true, str(LANG_WAIT));
489 if (!settings_load_config(buf)) 489 if (!settings_load_config(buf,true))
490 break; 490 break;
491 gui_syncsplash(HZ, true, str(LANG_SETTINGS_LOADED)); 491 gui_syncsplash(HZ, true, str(LANG_SETTINGS_LOADED));
492 break; 492 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)
247 screen_access_init(); 247 screen_access_init();
248 gui_syncstatusbar_init(&statusbars); 248 gui_syncstatusbar_init(&statusbars);
249 settings_reset(); 249 settings_reset();
250 settings_calc_config_sector();
251 settings_load(SETTINGS_ALL); 250 settings_load(SETTINGS_ALL);
252 gui_sync_wps_init(); 251 gui_sync_wps_init();
253 settings_apply(); 252 settings_apply();
@@ -447,8 +446,6 @@ static void init(void)
447 } 446 }
448 } 447 }
449 448
450 settings_calc_config_sector();
451
452#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 449#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
453 (CONFIG_KEYPAD == IRIVER_H10_PAD) || (CONFIG_KEYPAD == GIGABEAT_PAD) 450 (CONFIG_KEYPAD == IRIVER_H10_PAD) || (CONFIG_KEYPAD == GIGABEAT_PAD)
454#ifdef SETTINGS_RESET 451#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 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifndef RADIO_H 19#ifndef RADIO_H
20#define RADIO_H 20#define RADIO_H
21#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
22 21
23#ifndef FMRADIO_H 22#ifndef FMRADIO_H
24#include "fmradio.h" 23#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 @@
25#include "kernel.h" 25#include "kernel.h"
26#include "thread.h" 26#include "thread.h"
27#include "action.h" 27#include "action.h"
28#include "crc32.h"
28#include "settings.h" 29#include "settings.h"
29#include "disk.h" 30#include "disk.h"
30#include "panic.h" 31#include "panic.h"
@@ -72,6 +73,7 @@
72#include "statusbar.h" 73#include "statusbar.h"
73#include "splash.h" 74#include "splash.h"
74#include "list.h" 75#include "list.h"
76#include "settings_list.h"
75#if LCD_DEPTH > 1 77#if LCD_DEPTH > 1
76#include "backdrop.h" 78#include "backdrop.h"
77#endif 79#endif
@@ -100,9 +102,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
100#include "eq_menu.h" 102#include "eq_menu.h"
101#endif 103#endif
102 104
103#define CONFIG_BLOCK_VERSION 59 105#define NVRAM_BLOCK_SIZE 44
104#define CONFIG_BLOCK_SIZE 512
105#define RTC_BLOCK_SIZE 44
106 106
107#ifdef HAVE_LCD_BITMAP 107#ifdef HAVE_LCD_BITMAP
108#define MAX_LINES 10 108#define MAX_LINES 10
@@ -115,644 +115,115 @@ const char rec_base_directory[] = REC_BASE_DIR;
115#endif 115#endif
116 116
117long lasttime = 0; 117long lasttime = 0;
118static long config_sector = 0; /* mark uninitialized */
119static unsigned char config_block[CONFIG_BLOCK_SIZE];
120 118
121 119/* NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin */
122/* descriptor for a configuration value */ 120/* NVRAM is set out as
123/* (watch the struct packing and member sizes to keep this small) */ 121[0] 'R'
124struct bit_entry 122[1] 'b'
125{ 123[2] version
126 /* how many bits within the bitfield (1-32), MSB set if value is signed */ 124[3] stored variable count
127 unsigned char bit_size; /* min 6+1 bit */ 125[4-7] crc32 checksum
128 /* how many bytes in the global_settings struct (1,2,4) */ 126[8-NVRAM_BLOCK_SIZE] data
129 unsigned char byte_size; /* min 3 bits */
130 /* store position in global_settings struct */
131 short settings_offset; /* min 9 bit, better 10 */
132 /* default value */
133 int default_val; /* min 15 bit */
134 /* variable name in a .cfg file, NULL if not to be saved */
135 const char* cfg_name;
136 /* set of values, "rgb" for a color, or NULL for a numerical value */
137 const char* cfg_val;
138};
139
140/********************************************
141
142Config block as saved on the battery-packed RTC user RAM memory block
143of 44 bytes, starting at offset 0x14 of the RTC memory space.
144
145offset abs
1460x00 0x14 "Roc" header signature: 0x52 0x6f 0x63
1470x03 0x17 <version byte: 0x0>
1480x04 0x18 start of bit-table
149...
1500x28,0x29 unused, not reachable by set_bits() without disturbing the next 2
1510x2A,0x2B <checksum 2 bytes: xor of 0x00-0x29>
152
153Config memory is reset to 0xff and initialized with 'factory defaults' if
154a valid header & checksum is not found. Config version number is only
155increased when information is _relocated_ or space is _reused_ so that old
156versions can read and modify configuration changed by new versions.
157Memory locations not used by a given version should not be
158modified unless the header & checksum test fails.
159
160Rest of config block, only saved to disk:
1610x2C start of 2nd bit-table
162...
1630xA4 (char[20]) FMR Preset file
1640xB8 (char[20]) WPS file
1650xCC (char[20]) Lang file
1660xE0 (char[20]) Font file
167... (char[20]) RWPS file (on targets supporting a Remote WPS)
168... (char[20]) Main backdrop file (on color LCD targets)
169
170... to 0x200 <unused>
171
172*************************************/
173
174/* The persistence of the global_settings members is now controlled by
175 the two tables below, rtc_bits and hd_bits.
176 New values can just be added to the end, it will be backwards
177 compatible. If you however change order, bitsize, etc. of existing
178 entries, you need to bump CONFIG_BLOCK_VERSION to break compatibility.
179*/ 127*/
128#define NVRAM_DATA_START 8
129#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
130static char nvram_buffer[NVRAM_BLOCK_SIZE];
180 131
181 132static bool read_nvram_data(char* buf, int max_len)
182/* convenience macro for both size and offset of global_settings member */
183#define S_O(val) sizeof(global_settings.val), offsetof(struct user_settings, val)
184#define SIGNED 0x80 /* for bitsize value with signed attribute */
185
186/* some sets of values which are used more than once, to save memory */
187static const char off_on[] = "off,on";
188static const char off_on_ask[] = "off,on,ask";
189static const char off_number_spell_hover[] = "off,number,spell,hover";
190#ifdef HAVE_LCD_BITMAP
191static const char graphic_numeric[] = "graphic,numeric";
192#endif
193
194#ifdef HAVE_RECORDING
195/* keep synchronous to trig_durations and
196 trigger_times in settings_apply_trigger */
197static const char trig_durations_conf [] =
198 "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min";
199#endif
200
201#if defined(CONFIG_BACKLIGHT)
202static const char backlight_times_conf [] =
203 "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
204#endif
205
206/* the part of the settings which ends up in the RTC RAM, where available
207 (those we either need early, save frequently, or without spinup) */
208static const struct bit_entry rtc_bits[] =
209{ 133{
210 /* placeholder, containing the size information */ 134 unsigned crc32 = 0xffffffff;
211 {9, 0, 0, 0, NULL, NULL }, /* 9 bit to tell how far this is populated */ 135 int var_count = 0, i = 0, buf_pos = 0;
212 136#ifndef HAVE_RTC_RAM
213 /* # of bits, offset+size, default, .cfg name, .cfg values */ 137 int fd = open(NVRAM_FILE,O_RDONLY);
214 /* sound */ 138 if (fd < 0)
215#if CONFIG_CODEC == MAS3507D 139 return false;
216 {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */ 140 memset(buf,0,max_len);
217#else 141 if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
218 {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */ 142 return false;
219#endif 143 close(fd);
220 {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */
221#if CONFIG_CODEC != SWCODEC /* any MAS */
222 {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -15..+15 / -12..+12 */
223 {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -15..+15 / -12..+12 */
224#elif defined HAVE_UDA1380
225 {5, S_O(bass), 0, "bass", NULL }, /* 0..+24 */
226 {3, S_O(treble), 0, "treble", NULL }, /* 0..+6 */
227#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
228 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
229 || defined(HAVE_WM8751)
230 {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -6..+9 */
231 {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -6..+9 */
232#endif
233#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
234 {5, S_O(loudness), 0, "loudness", NULL }, /* 0...17 */
235 {3, S_O(avc), 0, "auto volume", "off,20ms,2,4,8" },
236 {1, S_O(superbass), false, "superbass", off_on },
237#endif
238 {3, S_O(channel_config), 0, "channels",
239 "stereo,mono,custom,mono left,mono right,karaoke" },
240 {8, S_O(stereo_width), 100, "stereo width", NULL},
241 /* playback */
242 {1, S_O(resume), false, "resume", off_on },
243 {1, S_O(playlist_shuffle), false, "shuffle", off_on },
244 {16 | SIGNED, S_O(resume_index), -1, NULL, NULL },
245 {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL },
246 {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL },
247 {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL },
248 {3, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle,ab" },
249 /* LCD */
250#ifdef HAVE_LCD_CONTRAST
251 {6, S_O(contrast), DEFAULT_CONTRAST_SETTING, "contrast", NULL },
252#endif
253#ifdef CONFIG_BACKLIGHT
254 {5, S_O(backlight_timeout), 6, "backlight timeout", backlight_times_conf },
255#ifdef CONFIG_CHARGING
256 {5, S_O(backlight_timeout_plugged), 11, "backlight timeout plugged",
257 backlight_times_conf },
258#endif
259#endif /* CONFIG_BACKLIGHT */
260#ifdef HAVE_LCD_BITMAP
261 {1, S_O(invert), false, "invert", off_on },
262 {1, S_O(flip_display), false, "flip display", off_on },
263 /* display */
264 {1, S_O(invert_cursor), true, "invert cursor", off_on },
265 {1, S_O(statusbar), true, "statusbar", off_on },
266 {1, S_O(scrollbar), true, "scrollbar", off_on },
267#if CONFIG_KEYPAD == RECORDER_PAD
268 {1, S_O(buttonbar), true, "buttonbar", off_on },
269#endif
270 {1, S_O(volume_type), 0, "volume display", graphic_numeric },
271 {1, S_O(battery_display), 0, "battery display", graphic_numeric },
272 {1, S_O(timeformat), 0, "time format", "24hour,12hour" },
273#endif /* HAVE_LCD_BITMAP */
274 {1, S_O(show_icons), true, "show icons", off_on },
275 /* system */
276 {4, S_O(poweroff), 10,
277 "idle poweroff", "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60" },
278 {18, S_O(runtime), 0, NULL, NULL },
279 {18, S_O(topruntime), 0, NULL, NULL },
280#if MEM > 1
281 {15, S_O(max_files_in_playlist), 10000,
282 "max files in playlist", NULL }, /* 1000...20000 */
283 {14, S_O(max_files_in_dir), 400,
284 "max files in dir", NULL }, /* 50...10000 */
285#else 144#else
286 {15, S_O(max_files_in_playlist), 1000, 145 memset(buf,0,max_len);
287 "max files in playlist", NULL }, /* 1000...20000 */ 146 /* read rtc block */
288 {14, S_O(max_files_in_dir), 200, 147 for (i=0; i < max_len; i++ )
289 "max files in dir", NULL }, /* 50...10000 */ 148 buf[i] = rtc_read(0x14+i);
290#endif 149#endif
291 /* battery */ 150 /* check magic, version */
292 {12, S_O(battery_capacity), BATTERY_CAPACITY_DEFAULT, "battery capacity", 151 if ((buf[0] != 'R') || (buf[1] != 'b')
293 NULL }, /* 1500...3200 for NiMH, 2200...3200 for LiIon, 152 || (buf[2] != NVRAM_CONFIG_VERSION))
294 500...1500 for Alkaline */ 153 return false;
295#ifdef CONFIG_CHARGING 154 /* check crc32 */
296 {1, S_O(car_adapter_mode), false, "car adapter mode", off_on }, 155 crc32 = crc_32(&buf[NVRAM_DATA_START],
297#endif 156 max_len-NVRAM_DATA_START-1,0xffffffff);
298 /* tuner */ 157 if (memcmp(&crc32,&buf[4],4))
299#ifdef CONFIG_TUNER 158 return false;
300 {1, S_O(fm_force_mono), false, "force fm mono", off_on }, 159 /* all good, so read in the settings */
301 {9, S_O(last_frequency), 0, NULL, NULL }, /* Default: MIN_FREQ */ 160 var_count = buf[3];
302#endif 161 buf_pos = NVRAM_DATA_START;
303 162 for(i=0; (i<nb_settings) && (var_count>0) && (buf_pos<max_len); i++)
304#if BATTERY_TYPES_COUNT > 1 163 {
305 {1, S_O(battery_type), 0, "battery type", "alkaline,nimh" }, 164 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
306#endif 165 >>F_NVRAM_MASK_SHIFT;
307 166 if (nvram_bytes)
308#ifdef HAVE_REMOTE_LCD 167 {
309 /* remote lcd */ 168 memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
310 {6, S_O(remote_contrast), DEFAULT_REMOTE_CONTRAST_SETTING, 169 buf_pos += nvram_bytes;
311 "remote contrast", NULL }, 170 var_count--;
312 {1, S_O(remote_invert), false, "remote invert", off_on }, 171 }
313 {1, S_O(remote_flip_display), false, "remote flip display", off_on }, 172 }
314 {5, S_O(remote_backlight_timeout), 6, "remote backlight timeout", 173 return true;
315 backlight_times_conf }, 174}
316#ifdef CONFIG_CHARGING 175static bool write_nvram_data(char* buf, int max_len)
317 {5, S_O(remote_backlight_timeout_plugged), 11,
318 "remote backlight timeout plugged", backlight_times_conf },
319#endif
320#ifdef HAVE_REMOTE_LCD_TICKING
321 {1, S_O(remote_reduce_ticking), false, "remote reduce ticking", off_on },
322#endif
323#endif
324
325#ifdef CONFIG_BACKLIGHT
326 {1, S_O(bl_filter_first_keypress), false,
327 "backlight filters first keypress", off_on },
328#ifdef HAVE_REMOTE_LCD
329 {1, S_O(remote_bl_filter_first_keypress), false,
330 "backlight filters first remote keypress", off_on },
331#endif
332#endif /* CONFIG_BACKLIGHT */
333
334 /* new stuff to be added here */
335 /* If values are just added to the end, no need to bump the version. */
336
337 /* Current sum of bits: 277 (worst case, but w/o remote lcd) */
338 /* Sum of all bit sizes must not grow beyond 288! */
339};
340
341
342/* the part of the settings which ends up in HD sector only */
343static const struct bit_entry hd_bits[] =
344{ 176{
345 /* This table starts after the 44 RTC bytes = 352 bits. */ 177 unsigned crc32 = 0xffffffff;
346 /* Here we need 11 bits to tell how far this is populated. */ 178 int i = 0, buf_pos = 0;
347 179 char var_count = 0;
348 /* placeholder, containing the size information */ 180#ifndef HAVE_RTC_RAM
349 {11, 0, 0, 0, NULL, NULL }, /* 11 bit to tell how far this is populated */ 181 int fd;
350
351 /* # of bits, offset+size, default, .cfg name, .cfg values */
352 /* more display */
353#ifdef CONFIG_BACKLIGHT
354 {1, S_O(caption_backlight), false, "caption backlight", off_on },
355#endif
356#ifdef HAVE_REMOTE_LCD
357 {1, S_O(remote_caption_backlight), false,
358 "remote caption backlight", off_on },
359#endif
360#ifdef HAVE_BACKLIGHT_BRIGHTNESS
361 {6, S_O(brightness), DEFAULT_BRIGHTNESS_SETTING, "brightness", NULL },
362#endif
363#ifdef HAVE_BACKLIGHT_PWM_FADING
364 /* backlight fading */
365 {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"},
366 {3, S_O(backlight_fade_out), 3, "backlight fade out",
367 "off,500ms,1s,2s,3s,4s,5s,10s"},
368#endif
369
370 {4, S_O(scroll_speed), 9, "scroll speed", NULL }, /* 0...15 */
371 {8, S_O(scroll_delay), 100, "scroll delay", NULL }, /* 0...250 */
372 {8, S_O(bidir_limit), 50, "bidir limit", NULL }, /* 0...200 */
373
374#ifdef HAVE_REMOTE_LCD
375 {4, S_O(remote_scroll_speed), 9, "remote scroll speed", NULL }, /* 0...15 */
376 {8, S_O(remote_scroll_step), 6, "remote scroll step", NULL }, /* 1...160 */
377 {8, S_O(remote_scroll_delay), 100, "remote scroll delay", NULL }, /* 0...250 */
378 {8, S_O(remote_bidir_limit), 50, "remote bidir limit", NULL }, /* 0...200 */
379#endif
380
381#ifdef HAVE_LCD_BITMAP
382 {1, S_O(offset_out_of_view), false, "Screen Scrolls Out Of View", off_on },
383#if LCD_WIDTH > 255
384 {9, S_O(scroll_step), 6, "scroll step", NULL },
385 {9, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
386#elif LCD_WIDTH > 127
387 {8, S_O(scroll_step), 6, "scroll step", NULL },
388 {8, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
389#else
390 {7, S_O(scroll_step), 6, "scroll step", NULL },
391 {7, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
392#endif
393#endif /* HAVE_LCD_BITMAP */
394#ifdef HAVE_LCD_CHARCELLS
395 {3, S_O(jump_scroll), 0, "jump scroll", NULL }, /* 0...5 */
396 {8, S_O(jump_scroll_delay), 50, "jump scroll delay", NULL }, /* 0...250 */
397#endif
398 {1, S_O(scroll_paginated), false, "scroll paginated", off_on },
399
400#ifdef HAVE_LCD_COLOR
401 {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
402 {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
403#endif
404
405 /* more playback */
406 {1, S_O(play_selected), true, "play selected", off_on },
407 {1, S_O(fade_on_stop), true, "volume fade", off_on },
408 {4, S_O(ff_rewind_min_step), FF_REWIND_1000,
409 "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60" },
410 {4, S_O(ff_rewind_accel), 3, "scan accel", NULL },
411#if CONFIG_CODEC == SWCODEC
412 {3, S_O(buffer_margin), 0, "antiskip",
413 "5s,15s,30s,1min,2min,3min,5min,10min" },
414#else
415 {3, S_O(buffer_margin), 0, "antiskip", NULL },
416#endif
417 /* disk */
418#ifndef HAVE_MMC
419#ifdef HAVE_ATA_POWER_OFF
420 {1, S_O(disk_poweroff), false, "disk poweroff", off_on },
421#endif
422 {8, S_O(disk_spindown), 5, "disk spindown", NULL },
423#endif /* HAVE_MMC */
424
425 /* browser */
426 {3, S_O(dirfilter), SHOW_SUPPORTED,
427 "show files", "all,supported,music,playlists"
428#ifdef HAVE_TAGCACHE
429 ",id3 database"
430#endif
431 },
432 {1, S_O(sort_case), false, "sort case", off_on },
433 {1, S_O(browse_current), false, "follow playlist", off_on },
434 /* playlist */
435 {1, S_O(playlist_viewer_icons), true, "playlist viewer icons", off_on },
436 {1, S_O(playlist_viewer_indices), true,
437 "playlist viewer indices", off_on },
438 {1, S_O(playlist_viewer_track_display), 0,
439 "playlist viewer track display", "track name,full path" },
440 {2, S_O(recursive_dir_insert), RECURSE_OFF,
441 "recursive directory insert", off_on_ask },
442 /* bookmarks */
443 {3, S_O(autocreatebookmark), BOOKMARK_NO, "autocreate bookmarks",
444 "off,on,ask,recent only - on,recent only - ask" },
445 {2, S_O(autoloadbookmark), BOOKMARK_NO,
446 "autoload bookmarks", off_on_ask },
447 {2, S_O(usemrb), BOOKMARK_NO,
448 "use most-recent-bookmarks", "off,on,unique only" },
449#ifdef HAVE_LCD_BITMAP
450 /* peak meter */
451 {5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */
452 "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" },
453 {5, S_O(peak_meter_hold), 3, "peak meter hold",
454 "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" },
455 {7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */
456 {1, S_O(peak_meter_dbfs), true, "peak meter dbfs", off_on },
457 {7, S_O(peak_meter_min), 60, "peak meter min", NULL }, /* 0...100 */
458 {7, S_O(peak_meter_max), 0, "peak meter max", NULL }, /* 0...100 */
459#endif
460#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
461 {7, S_O(mdb_strength), 0, "mdb strength", NULL},
462 {7, S_O(mdb_harmonics), 0, "mdb harmonics", NULL},
463 {9, S_O(mdb_center), 0, "mdb center", NULL},
464 {9, S_O(mdb_shape), 0, "mdb shape", NULL},
465 {1, S_O(mdb_enable), 0, "mdb enable", off_on},
466#endif
467#if CONFIG_CODEC == MAS3507D
468 {1, S_O(line_in), false, "line in", off_on },
469#endif 182#endif
470 /* voice */ 183 memset(buf,0,max_len);
471 {2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover }, 184 /* magic, version */
472 {2, S_O(talk_file), 0, "talk file", off_number_spell_hover }, 185 buf[0] = 'R'; buf[1] = 'b';
473 {1, S_O(talk_menu), true, "talk menu", off_on }, 186 buf[2] = NVRAM_CONFIG_VERSION;
474 187 buf_pos = NVRAM_DATA_START;
475 {2, S_O(sort_file), 0, "sort files", "alpha,oldest,newest,type" }, 188 for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
476 {2, S_O(sort_dir), 0, "sort dirs", "alpha,oldest,newest" }, 189 {
477 {1, S_O(id3_v1_first), 0, "id3 tag priority", "v2-v1,v1-v2"}, 190 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
478 191 >>F_NVRAM_MASK_SHIFT;
479#ifdef HAVE_RECORDING 192 if (nvram_bytes)
480 /* recording */ 193 {
481 {1, S_O(recscreen_on), false, "recscreen on", off_on }, 194 memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
482 {1, S_O(rec_startup), false, "rec screen on startup", off_on }, 195 buf_pos += nvram_bytes;
483 {4, S_O(rec_timesplit), 0, "rec timesplit", /* 0...15 */ 196 var_count++;
484 "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" }, 197 }
485 {4, S_O(rec_sizesplit), 0, "rec sizesplit", /* 0...15 */ 198 }
486 "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB" }, 199 /* count and crc32 */
487 {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" }, 200 buf[3] = var_count;
488 {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" }, 201 crc32 = crc_32(&buf[NVRAM_DATA_START],
489 {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" }, 202 max_len-NVRAM_DATA_START-1,0xffffffff);
490 203 memcpy(&buf[4],&crc32,4);
204#ifndef HAVE_RTC_RAM
205 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
206 if (fd >= 0)
491 { 207 {
492#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN) 208 int len = write(fd,buf,max_len);
493 2, 209 close(fd);
210 if (len < 8)
211 return false;
212 }
494#else 213#else
495 1, 214 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
496#endif 215 that it would write a number of bytes at a time since the RTC chip
497 S_O(rec_source), 0 /* 0=mic */, "rec source", 216 supports that, but this will have to do for now 8-) */
498 "mic,line" 217 for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
499#ifdef HAVE_SPDIF_IN 218 int r = rtc_write(0x14+i, buf[i]);
500 ",spdif" 219 if (r) {
501#endif 220 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
502#ifdef HAVE_FMRADIO_IN 221 14+i, r );
503 ",fmradio" 222 return false;
504#endif 223 }
505 }, 224 }
506 {5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
507 {1, S_O(rec_directory), 0, /* rec_base_directory */
508 "rec directory", REC_BASE_DIR ",current" },
509#ifdef CONFIG_BACKLIGHT
510 {2, S_O(cliplight), 0, "cliplight", "off,main,both,remote" },
511#endif
512#if CONFIG_CODEC == MAS3587F
513 {4, S_O(rec_mic_gain), 8, "rec mic gain", NULL },
514 {4, S_O(rec_left_gain), 2 /* 0dB */, "rec left gain", NULL }, /* 0...15 */
515 {4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
516 {3, S_O(rec_frequency), 0, /* 0=44.1kHz */
517 "rec frequency", "44,48,32,22,24,16" },
518 {3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL },
519 {1, S_O(rec_editable), false, "editable recordings", off_on },
520#endif /* CONFIG_CODEC == MAS3587F */
521
522#if CONFIG_CODEC == SWCODEC
523#ifdef HAVE_UDA1380
524 {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
525 {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
526 {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
527#elif defined(HAVE_TLV320)
528 /* TLV320 only has no mic boost or 20db mic boost */
529 {1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */
530 {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
531 {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
532#elif defined(HAVE_WM8975)
533 {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
534 {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
535 {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
536#elif defined(HAVE_WM8758)
537 {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
538 {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
539 {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
540#elif defined(HAVE_WM8731)
541 {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
542 {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
543 {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
544#endif
545 {REC_FREQ_CFG_NUM_BITS, S_O(rec_frequency), REC_FREQ_DEFAULT,
546 "rec frequency", REC_FREQ_CFG_VAL_LIST },
547 {REC_FORMAT_CFG_NUM_BITS ,S_O(rec_format), REC_FORMAT_DEFAULT,
548 "rec format", REC_FORMAT_CFG_VAL_LIST },
549 /** Encoder settings start - keep these together **/
550 /* aiff_enc */
551 /* (no settings yet) */
552 /* mp3_enc */
553 {5,S_O(mp3_enc_config.bitrate), MP3_ENC_BITRATE_CFG_DEFAULT,
554 "mp3_enc bitrate", MP3_ENC_BITRATE_CFG_VALUE_LIST },
555 /* wav_enc */
556 /* (no settings yet) */
557 /* wavpack_enc */
558 /* (no settings yet) */
559 /** Encoder settings end **/
560#endif /* CONFIG_CODEC == SWCODEC */
561
562 /* values for the trigger */
563 {8 | SIGNED, S_O(rec_start_thres), -35, "trigger start threshold", NULL},
564 {8 | SIGNED, S_O(rec_stop_thres), -45, "trigger stop threshold", NULL},
565 {4, S_O(rec_start_duration), 0, "trigger start duration", trig_durations_conf},
566 {4, S_O(rec_stop_postrec), 2, "trigger stop postrec", trig_durations_conf},
567 {4, S_O(rec_stop_gap), 1, "trigger min gap", trig_durations_conf},
568 {4, S_O(rec_trigger_mode ), 0, "trigger mode", "off,once,repeat"},
569#endif /* HAVE_RECORDING */
570
571#ifdef HAVE_SPDIF_POWER
572 {1, S_O(spdif_enable), false, "spdif enable", off_on},
573#endif
574
575 {2, S_O(next_folder), false, "folder navigation", "off,on,random" },
576 {1, S_O(runtimedb), false, "gather runtime data", off_on },
577
578#if CONFIG_CODEC == SWCODEC
579 {1, S_O(replaygain), false, "replaygain", off_on },
580 {2, S_O(replaygain_type), REPLAYGAIN_ALBUM, "replaygain type",
581 "track,album,track shuffle" },
582 {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
583 {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
584 {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" },
585 {3, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,shuffle and track skip,always"},
586 {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL},
587 {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL},
588 {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL},
589 {4, S_O(crossfade_fade_out_duration), 0, "crossfade fade out duration", NULL},
590 {1, S_O(crossfade_fade_out_mixmode), 0, "crossfade fade out mode", "crossfade,mix"},
591 {1, S_O(crossfeed), false, "crossfeed", off_on },
592 {6, S_O(crossfeed_direct_gain), 15, "crossfeed direct gain", NULL },
593 {7, S_O(crossfeed_cross_gain), 60, "crossfeed cross gain", NULL },
594 {8, S_O(crossfeed_hf_attenuation), 160, "crossfeed hf attenuation", NULL },
595 {11, S_O(crossfeed_hf_cutoff), 700, "crossfeed hf cutoff", NULL },
596
597 /* equalizer */
598 {1, S_O(eq_enabled), false, "eq enabled", off_on },
599 {8, S_O(eq_precut), 0, "eq precut", NULL },
600 /* 0..32768 Hz */
601 {15, S_O(eq_band0_cutoff), 60, "eq band 0 cutoff", NULL },
602 {15, S_O(eq_band1_cutoff), 200, "eq band 1 cutoff", NULL },
603 {15, S_O(eq_band2_cutoff), 800, "eq band 2 cutoff", NULL },
604 {15, S_O(eq_band3_cutoff), 4000, "eq band 3 cutoff", NULL },
605 {15, S_O(eq_band4_cutoff), 12000, "eq band 4 cutoff", NULL },
606 /* 0..64 (or 0.0 to 6.4) */
607 {6, S_O(eq_band0_q), 7, "eq band 0 q", NULL },
608 {6, S_O(eq_band1_q), 10, "eq band 1 q", NULL },
609 {6, S_O(eq_band2_q), 10, "eq band 2 q", NULL },
610 {6, S_O(eq_band3_q), 10, "eq band 3 q", NULL },
611 {6, S_O(eq_band4_q), 7, "eq band 4 q", NULL },
612 /* -240..240 (or -24db to +24db) */
613 {9|SIGNED, S_O(eq_band0_gain), 0, "eq band 0 gain", NULL },
614 {9|SIGNED, S_O(eq_band1_gain), 0, "eq band 1 gain", NULL },
615 {9|SIGNED, S_O(eq_band2_gain), 0, "eq band 2 gain", NULL },
616 {9|SIGNED, S_O(eq_band3_gain), 0, "eq band 3 gain", NULL },
617 {9|SIGNED, S_O(eq_band4_gain), 0, "eq band 4 gain", NULL },
618
619 /* dithering */
620 {1, S_O(dithering_enabled), false, "dithering enabled", off_on },
621#endif
622
623#ifdef HAVE_DIRCACHE
624 {1, S_O(dircache), false, "dircache", off_on },
625 {22, S_O(dircache_size), 0, NULL, NULL },
626#endif
627
628#ifdef HAVE_TAGCACHE
629#ifdef HAVE_TC_RAMCACHE
630 {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
631#endif
632 {1, S_O(tagcache_autoupdate), 0, "tagcache_autoupdate", off_on },
633#endif
634
635 {4, S_O(default_codepage), 0, "default codepage",
636 "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
637
638 {1, S_O(warnon_erase_dynplaylist), false,
639 "warn when erasing dynamic playlist", off_on },
640
641#ifdef CONFIG_BACKLIGHT
642#ifdef HAS_BUTTON_HOLD
643 {2, S_O(backlight_on_button_hold), 0, "backlight on button hold",
644 "normal,off,on" },
645#endif
646
647#ifdef HAVE_LCD_SLEEP
648 {4, S_O(lcd_sleep_after_backlight_off), 3,
649 "lcd sleep after backlight off",
650 "always,never,5,10,15,20,30,45,60,90" },
651#endif
652#endif /* CONFIG_BACKLIGHT */
653
654#ifdef HAVE_WM8758
655 {1, S_O(eq_hw_enabled), false, "eq hardware enabled", off_on },
656
657 {2, S_O(eq_hw_band0_cutoff), 1, "eq hardware band 0 cutoff", "80Hz,105Hz,135Hz,175Hz" },
658 {5|SIGNED, S_O(eq_hw_band0_gain), 0, "eq hardware band 0 gain", NULL },
659
660 {2, S_O(eq_hw_band1_center), 1, "eq hardware band 1 center", "230Hz,300Hz,385Hz,500Hz" },
661 {1, S_O(eq_hw_band1_bandwidth), 0, "eq hardware band 1 bandwidth", "narrow,wide" },
662 {5|SIGNED, S_O(eq_hw_band1_gain), 0, "eq hardware band 1 gain", NULL },
663
664 {2, S_O(eq_hw_band2_center), 1, "eq hardware band 2 center", "650Hz,850Hz,1.1kHz,1.4kHz" },
665 {1, S_O(eq_hw_band2_bandwidth), 0, "eq hardware band 2 bandwidth", "narrow,wide" },
666 {5|SIGNED, S_O(eq_hw_band2_gain), 0, "eq hardware band 2 gain", NULL },
667
668 {2, S_O(eq_hw_band3_center), 1, "eq hardware band 3 center", "1.8kHz,2.4kHz,3.2kHz,4.1kHz" },
669 {1, S_O(eq_hw_band3_bandwidth), 0, "eq hardware band 3 bandwidth", "narrow,wide" },
670 {5|SIGNED, S_O(eq_hw_band3_gain), 0, "eq hardware band 3 gain", NULL },
671
672 {2, S_O(eq_hw_band4_cutoff), 1, "eq hardware band 4 cutoff", "5.3kHz,6.9kHz,9kHz,11.7kHz" },
673 {5|SIGNED, S_O(eq_hw_band4_gain), 0, "eq hardware band 4 gain", NULL },
674#endif
675 {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on },
676
677 {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" },
678#ifdef HAVE_AGC
679 {4, S_O(rec_agc_preset_mic), 1, "agc mic preset", NULL}, /* 0...5 */
680 {4, S_O(rec_agc_preset_line), 1, "agc line preset", NULL}, /* 0...5 */
681 {8|SIGNED, S_O(rec_agc_maxgain_mic), 104, "agc maximum mic gain", NULL},
682 {8|SIGNED, S_O(rec_agc_maxgain_line), 96, "agc maximum line gain", NULL},
683 {3, S_O(rec_agc_cliptime), 1, "agc cliptime", "0.2s,0.4s,0.6s,0.8,1s"},
684#endif
685
686#ifdef HAVE_REMOTE_LCD
687#ifdef HAS_REMOTE_BUTTON_HOLD
688 {2, S_O(remote_backlight_on_button_hold), 0, "remote backlight on button hold",
689 "normal,off,on" },
690#endif
691#endif
692
693#ifdef HAVE_HEADPHONE_DETECTION
694 {2, S_O(unplug_mode), 0, "pause on headphone unplug", NULL},
695 {4, S_O(unplug_rw), 0, "rewind duration on pause", NULL},
696 {1, S_O(unplug_autoresume), 0, "disable autoresume if phones not present", off_on },
697#endif
698#ifdef CONFIG_TUNER
699 {2, S_O(fm_region), 0, "fm_region", "eu,us,jp,kr" },
700#endif
701
702 {1, S_O(audioscrobbler), false, "Last.fm Logging", off_on},
703
704 /* If values are just added to the end, no need to bump the version. */
705 /* new stuff to be added at the end */
706#ifdef HAVE_RECORDING
707 {2, S_O(rec_trigger_type), 0, "trigger type", "stop,pause,nf stp"},
708#endif 225#endif
709 226 return true;
710 /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
711};
712
713/* helper function to extract n (<=32) bits from an arbitrary position
714 * counting from LSB to MSB */
715static uint32_t get_bits(
716 const uint32_t *p, /* the start of the bitfield array */
717 unsigned int from, /* bit no. to start reading from */
718 unsigned int size) /* how many bits to read */
719{
720 unsigned int long_index = from / 32;
721 unsigned int bit_index = from % 32;
722 uint32_t result;
723
724 result = p[long_index] >> bit_index;
725
726 if (bit_index + size > 32) /* crossing longword boundary */
727 result |= p[long_index+1] << (32 - bit_index);
728
729 result &= 0xFFFFFFFF >> (32 - size);
730
731 return result;
732}
733
734/* helper function to set n (<=32) bits to an arbitrary position,
735 * counting from LSB to MSB */
736static void set_bits(
737 uint32_t *p, /* the start of the bitfield array */
738 unsigned int from, /* bit no. to start writing into */
739 unsigned int size, /* how many bits to change */
740 uint32_t value) /* content (LSBs will be taken) */
741{
742 unsigned int long_index = from / 32;
743 unsigned int bit_index = from % 32;
744 uint32_t mask;
745
746 mask = 0xFFFFFFFF >> (32 - size);
747 value &= mask;
748 mask <<= bit_index;
749
750 if (bit_index + size > 32)
751 p[long_index+1] =
752 (p[long_index+1] & (0xFFFFFFFF << (bit_index + size - 32)))
753 | (value >> (32 - bit_index));
754
755 p[long_index] = (p[long_index] & ~mask) | (value << bit_index);
756} 227}
757 228
758#ifdef HAVE_LCD_COLOR 229#ifdef HAVE_LCD_COLOR
@@ -787,223 +258,89 @@ static int hex_to_rgb(const char* hex)
787 return 0; 258 return 0;
788} 259}
789#endif 260#endif
790 261bool settings_write_config(char* filename)
791/*
792 * Calculates the checksum for the config block and returns it
793 */
794
795static unsigned short calculate_config_checksum(const unsigned char* buf)
796{
797 unsigned int i;
798 unsigned char cksum[2];
799 cksum[0] = cksum[1] = 0;
800
801 for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) {
802 cksum[0] ^= buf[i];
803 cksum[1] ^= buf[i+1];
804 }
805
806 return (cksum[0] << 8) | cksum[1];
807}
808
809/*
810 * initialize the config block buffer
811 */
812static void init_config_buffer( void )
813{ 262{
814 DEBUGF( "init_config_buffer()\n" );
815
816 /* reset to 0 - all unused */
817 memset(config_block, 0, CONFIG_BLOCK_SIZE);
818 /* insert header */
819 config_block[0] = 'R';
820 config_block[1] = 'o';
821 config_block[2] = 'c';
822 config_block[3] = CONFIG_BLOCK_VERSION;
823}
824
825static bool flush_config_block_callback(void)
826{
827 ata_write_sectors(IF_MV2(0,) config_sector, 1, config_block);
828 return true;
829}
830/*
831 * save the config block buffer to disk or RTC RAM
832 */
833static int save_config_buffer( void )
834{
835 unsigned short chksum;
836#ifdef HAVE_RTC_RAM
837 unsigned int i;
838#endif
839
840 /* update the checksum in the end of the block before saving */
841 chksum = calculate_config_checksum(config_block);
842 config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8;
843 config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff;
844
845#ifdef HAVE_RTC_RAM
846 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
847 that it would write a number of bytes at a time since the RTC chip
848 supports that, but this will have to do for now 8-) */
849 for (i=0; i < RTC_BLOCK_SIZE; i++ ) {
850 int r = rtc_write(0x14+i, config_block[i]);
851 if (r) {
852 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
853 14+i, r );
854 return r;
855 }
856 }
857
858#endif
859
860 if (config_sector != 0)
861 register_ata_idle_func(flush_config_block_callback);
862 else
863 return -1;
864
865 return 0;
866}
867
868/*
869 * load the config block buffer from disk or RTC RAM
870 */
871static int load_config_buffer(int which)
872{
873 unsigned short chksum;
874 bool correct = false;
875
876
877 DEBUGF( "load_config_buffer()\n" );
878
879 if (which & SETTINGS_HD)
880 {
881 if (config_sector != 0) {
882 ata_read_sectors(IF_MV2(0,) config_sector, 1, config_block);
883 /* calculate the checksum, check it and the header */
884 chksum = calculate_config_checksum(config_block);
885
886 if (config_block[0] == 'R' &&
887 config_block[1] == 'o' &&
888 config_block[2] == 'c' &&
889 config_block[3] == CONFIG_BLOCK_VERSION &&
890 (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] &&
891 (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1])
892 {
893 DEBUGF( "load_config_buffer: header & checksum test ok\n" );
894 correct = true;
895 }
896 }
897 }
898
899#ifdef HAVE_RTC_RAM
900 if(!correct)
901 {
902 /* If the disk sector was incorrect, reinit the buffer */
903 memset(config_block, 0, CONFIG_BLOCK_SIZE);
904 }
905
906 if (which & SETTINGS_RTC)
907 {
908 unsigned int i;
909 unsigned char rtc_block[RTC_BLOCK_SIZE];
910
911 /* read rtc block */
912 for (i=0; i < RTC_BLOCK_SIZE; i++ )
913 rtc_block[i] = rtc_read(0x14+i);
914
915 chksum = calculate_config_checksum(rtc_block);
916
917 /* if rtc block is ok, use that */
918 if (rtc_block[0] == 'R' &&
919 rtc_block[1] == 'o' &&
920 rtc_block[2] == 'c' &&
921 rtc_block[3] == CONFIG_BLOCK_VERSION &&
922 (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] &&
923 (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1])
924 {
925 memcpy(config_block, rtc_block, RTC_BLOCK_SIZE);
926 correct = true;
927 }
928 }
929#endif
930
931 if ( !correct ) {
932 /* if checksum is not valid, clear the config buffer */
933 DEBUGF( "load_config_buffer: header & checksum test failed\n" );
934 init_config_buffer();
935 return -1;
936 }
937
938 return 0;
939}
940
941
942/* helper to save content of global_settings into a bitfield,
943 as described per table */
944static void save_bit_table(const struct bit_entry* p_table, int count, int bitstart)
945{
946 uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
947 uint32_t value; /* 32 bit content */
948 int i; 263 int i;
949 const struct bit_entry* p_run = p_table; /* start after the size info */ 264 int fd;
950 int curr_bit = bitstart + p_table->bit_size; 265 char value[MAX_PATH];
951 count--; /* first is excluded from loop */ 266 fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
952 267 if (fd < 0)
953 for (i=0; i<count; i++) 268 return false;
269 fdprintf(fd, "# .cfg file created by rockbox %s - "
270 "http://www.rockbox.org\r\n\r\n", appsversion);
271 for(i=0; i<nb_settings; i++)
954 { 272 {
955 p_run++; 273 if (settings[i].cfg_name == NULL)
956 /* could do a memcpy, but that would be endian-dependent */
957 switch(p_run->byte_size)
958 {
959 case 1:
960 value = ((uint8_t *)&global_settings)[p_run->settings_offset];
961 break;
962 case 2:
963 value = ((uint16_t *)&global_settings)[p_run->settings_offset/2];
964 break;
965 case 4:
966 value = ((uint32_t *)&global_settings)[p_run->settings_offset/4];
967 break;
968 default:
969 DEBUGF( "save_bit_table: illegal size!\n" );
970 continue; 274 continue;
971 } 275 switch (settings[i].flags&F_T_MASK)
972 set_bits(p_bitfield, curr_bit, p_run->bit_size & 0x3F, value);
973 curr_bit += p_run->bit_size & 0x3F;
974 }
975 set_bits(p_bitfield, bitstart, p_table->bit_size, /* write size */
976 curr_bit); /* = position after last element */
977}
978
979/*
980 * figure out the config sector from the partition table and the
981 * mounted file system
982 */
983void settings_calc_config_sector(void)
984{
985#ifdef SIMULATOR
986 config_sector = 61;
987#else
988 int i;
989 long partition_start;
990 long sector = 0;
991
992 if (fat_startsector(IF_MV(0)) != 0) /* There is a partition table */
993 {
994 sector = 61;
995 for (i = 0; i < 4; i++)
996 { 276 {
997 partition_start = disk_partinfo(i)->start; 277 case F_T_INT:
998 if (partition_start != 0 && (partition_start - 2) < sector) 278 case F_T_UINT:
999 sector = partition_start - 2; 279#ifdef HAVE_LCD_COLOR
1000 } 280 if (settings[i].flags&F_RGB)
1001 if (sector < 0) 281 {
1002 sector = 0; 282 int colour = *(int*)settings[i].setting;
1003 } 283 snprintf(value,MAX_PATH,"%02x%02x%02x",
1004 284 (int)RGB_UNPACK_RED(colour),
1005 config_sector = sector; 285 (int)RGB_UNPACK_GREEN(colour),
286 (int)RGB_UNPACK_BLUE(colour));
287 }
288 else
1006#endif 289#endif
290 if (settings[i].cfg_vals == NULL)
291 {
292 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
293 }
294 else
295 {
296 char *s,*end;
297 char vals[MAX_PATH];
298 int val = 0;
299 strncpy(vals,settings[i].cfg_vals,MAX_PATH);
300 s = strtok_r(vals,",",&end);
301 while (s)
302 {
303 if (val == *(int*)settings[i].setting)
304 {
305 strncpy(value,s,MAX_PATH);
306 break;
307 }
308 val++;
309 s = strtok_r(NULL,",",&end);
310 }
311 }
312 break;
313 case F_T_BOOL:
314 strcpy(value,*(bool*)settings[i].setting == true?"on":"off");
315 break;
316 case F_T_CHARPTR:
317 case F_T_UCHARPTR:
318 if (((char*)settings[i].setting)[0] == '\0')
319 break;
320 if (settings[i].filename_setting->prefix)
321 {
322 snprintf(value,MAX_PATH,"%s%s%s",
323 settings[i].filename_setting->prefix,
324 (char*)settings[i].setting,
325 settings[i].filename_setting->suffix);
326 }
327 else strncpy(value,(char*)settings[i].setting,
328 settings[i].filename_setting->max_len);
329 break;
330 } /* switch () */
331 if (value[0])
332 fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
333 value[0] = '\0';
334 } /* for(...) */
335 close(fd);
336 return true;
337}
338static bool flush_config_block_callback(void)
339{
340 bool r1, r2;
341 r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
342 r2 = settings_write_config(CONFIGFILE);
343 return r1 || r2;
1007} 344}
1008 345
1009/* 346/*
@@ -1011,75 +348,34 @@ void settings_calc_config_sector(void)
1011 */ 348 */
1012int settings_save( void ) 349int settings_save( void )
1013{ 350{
1014 int i; 351 int elapsed_secs;
1015
1016 {
1017 int elapsed_secs;
1018
1019 elapsed_secs = (current_tick - lasttime) / HZ;
1020 global_settings.runtime += elapsed_secs;
1021 lasttime += (elapsed_secs * HZ);
1022 352
1023 if ( global_settings.runtime > global_settings.topruntime ) 353 elapsed_secs = (current_tick - lasttime) / HZ;
1024 global_settings.topruntime = global_settings.runtime; 354 global_settings.runtime += elapsed_secs;
1025 } 355 lasttime += (elapsed_secs * HZ);
1026
1027 /* serialize scalar values into RTC and HD sector, specified via table */
1028 save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
1029 save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8);
1030
1031 i = 0xb8;
1032 strncpy((char *)&config_block[i], (char *)global_settings.wps_file,
1033 MAX_FILENAME);
1034 i+= MAX_FILENAME;
1035 strncpy((char *)&config_block[i], (char *)global_settings.lang_file,
1036 MAX_FILENAME);
1037 i+= MAX_FILENAME;
1038 strncpy((char *)&config_block[i], (char *)global_settings.font_file,
1039 MAX_FILENAME);
1040 i+= MAX_FILENAME;
1041#ifdef HAVE_REMOTE_LCD
1042 strncpy((char *)&config_block[i], (char *)global_settings.rwps_file,
1043 MAX_FILENAME);
1044 i+= MAX_FILENAME;
1045#endif
1046 356
1047#ifdef CONFIG_TUNER 357 if ( global_settings.runtime > global_settings.topruntime )
1048 strncpy((char *)&config_block[i], (char *)global_settings.fmr_file, 358 global_settings.topruntime = global_settings.runtime;
1049 MAX_FILENAME); 359#ifdef HAVE_RTC_RAM
1050 i+= MAX_FILENAME; 360 /* this will be done in the ata_callback if
1051#endif 361 target doesnt have rtc ram */
1052 362 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
1053#if LCD_DEPTH > 1
1054 strncpy((char *)&config_block[i], (char *)global_settings.backdrop_file,
1055 MAX_FILENAME);
1056 i+= MAX_FILENAME;
1057#endif
1058#ifdef HAVE_LCD_BITMAP
1059 strncpy((char *)&config_block[i], (char *)global_settings.kbd_file,
1060 MAX_FILENAME);
1061 i+= MAX_FILENAME;
1062#endif 363#endif
1063 364 if(!register_ata_idle_func(flush_config_block_callback))
1064 if(save_config_buffer())
1065 { 365 {
1066 lcd_clear_display(); 366 int i;
1067#ifdef HAVE_REMOTE_LCD 367 FOR_NB_SCREENS(i)
1068 lcd_remote_clear_display(); 368 {
1069#endif 369 screens[i].clear_display();
1070#ifdef HAVE_LCD_CHARCELLS 370#ifdef HAVE_LCD_CHARCELLS
1071 lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER)); 371 screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER));
1072 lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER)); 372 screens[i].puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER));
1073#else 373#else
1074 lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER)); 374 screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
1075 lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER)); 375 screens[i].puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
1076 lcd_update(); 376 screens[i].update();
1077#ifdef HAVE_REMOTE_LCD
1078 lcd_remote_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
1079 lcd_remote_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
1080 lcd_remote_update();
1081#endif
1082#endif 377#endif
378 }
1083 sleep(HZ*2); 379 sleep(HZ*2);
1084 return -1; 380 return -1;
1085 } 381 }
@@ -1147,6 +443,7 @@ void settings_apply(void)
1147 int i; 443 int i;
1148#endif 444#endif
1149 445
446 DEBUGF( "settings_apply()\n" );
1150 sound_settings_apply(); 447 sound_settings_apply();
1151 448
1152 audio_set_buffer_margin(global_settings.buffer_margin); 449 audio_set_buffer_margin(global_settings.buffer_margin);
@@ -1207,8 +504,7 @@ void settings_apply(void)
1207 lcd_set_invert_display(global_settings.invert); 504 lcd_set_invert_display(global_settings.invert);
1208 lcd_set_flip(global_settings.flip_display); 505 lcd_set_flip(global_settings.flip_display);
1209 button_set_flip(global_settings.flip_display); 506 button_set_flip(global_settings.flip_display);
1210 if(global_settings.invert || global_settings.flip_display) 507 lcd_update(); /* refresh after flipping the screen */
1211 lcd_update(); /* refresh after flipping the screen */
1212 settings_apply_pm_range(); 508 settings_apply_pm_range();
1213 peak_meter_init_times( 509 peak_meter_init_times(
1214 global_settings.peak_meter_release, global_settings.peak_meter_hold, 510 global_settings.peak_meter_release, global_settings.peak_meter_hold,
@@ -1239,7 +535,6 @@ void settings_apply(void)
1239 unload_main_backdrop(); 535 unload_main_backdrop();
1240 } 536 }
1241 show_main_backdrop(); 537 show_main_backdrop();
1242
1243#endif 538#endif
1244 539
1245#ifdef HAVE_LCD_COLOR 540#ifdef HAVE_LCD_COLOR
@@ -1344,131 +639,16 @@ void settings_apply(void)
1344#endif 639#endif
1345} 640}
1346 641
1347
1348/* helper to load global_settings from a bitfield, as described per table */
1349static void load_bit_table(const struct bit_entry* p_table, int count, int bitstart)
1350{
1351 uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
1352 uint32_t value; /* 32 bit content */
1353 int i;
1354 int maxbit; /* how many bits are valid in the saved part */
1355 const struct bit_entry* p_run = p_table; /* start after the size info */
1356 count--; /* first is excluded from loop */
1357 maxbit = get_bits(p_bitfield, bitstart, p_table->bit_size);
1358 bitstart += p_table->bit_size;
1359
1360 for (i=0; i<count; i++)
1361 {
1362 int size;
1363 p_run++;
1364
1365 size = p_run->bit_size & 0x3F; /* mask off abused bits */
1366 if (bitstart + size > maxbit)
1367 break; /* exit if this is not valid any more in bitfield */
1368
1369 value = get_bits(p_bitfield, bitstart, size);
1370 bitstart += size;
1371 if (p_run->bit_size & SIGNED)
1372 { // sign extend the read value
1373 unsigned long mask = 0xFFFFFFFF << (size - 1);
1374 if (value & mask) /* true if MSB of value is set */
1375 value |= mask;
1376 }
1377
1378 /* could do a memcpy, but that would be endian-dependent */
1379 switch(p_run->byte_size)
1380 {
1381 case 1:
1382 ((uint8_t *)&global_settings)[p_run->settings_offset] =
1383 (unsigned char)value;
1384 break;
1385 case 2:
1386 ((uint16_t *)&global_settings)[p_run->settings_offset/2] =
1387 (unsigned short)value;
1388 break;
1389 case 4:
1390 ((uint32_t *)&global_settings)[p_run->settings_offset/4] =
1391 (unsigned int)value;
1392 break;
1393 default:
1394 DEBUGF( "load_bit_table: illegal size!\n" );
1395 continue;
1396 }
1397 }
1398}
1399
1400
1401/* 642/*
1402 * load settings from disk or RTC RAM 643 * load settings from disk or RTC RAM
1403 */ 644 */
1404void settings_load(int which) 645void settings_load(int which)
1405{ 646{
1406 int i;
1407 DEBUGF( "reload_all_settings()\n" ); 647 DEBUGF( "reload_all_settings()\n" );
1408 648 if (which&SETTINGS_RTC)
1409 /* load the buffer from the RTC (resets it to all-unused if the block 649 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
1410 is invalid) and decode the settings which are set in the block */ 650 if (which&SETTINGS_HD)
1411 if (!load_config_buffer(which)) 651 settings_load_config(CONFIGFILE,false);
1412 {
1413 /* load scalar values from RTC and HD sector, specified via table */
1414 if (which & SETTINGS_RTC)
1415 {
1416 load_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
1417 }
1418 if (which & SETTINGS_HD)
1419 {
1420 load_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]),
1421 RTC_BLOCK_SIZE*8);
1422 }
1423
1424#ifdef HAVE_RECORDING
1425 global_settings.recscreen_on = false;
1426#endif
1427
1428#ifdef HAVE_LCD_CONTRAST
1429 if ( global_settings.contrast < MIN_CONTRAST_SETTING ||
1430 global_settings.contrast > MAX_CONTRAST_SETTING )
1431 global_settings.contrast = lcd_default_contrast();
1432#endif
1433
1434#ifdef HAVE_LCD_REMOTE
1435 if (global_settings.remote_contrast < MIN_REMOTE_CONTRAST_SETTING ||
1436 global_settings.remote_contrast > MAX_REMOTE_CONTRAST_SETTING )
1437 global_settings.remote_contrast = lcd_remote_default_contrast();
1438#endif
1439 i = 0xb8;
1440 strncpy((char *)global_settings.wps_file, (char *)&config_block[i],
1441 MAX_FILENAME);
1442 i+= MAX_FILENAME;
1443 strncpy((char *)global_settings.lang_file, (char *)&config_block[i],
1444 MAX_FILENAME);
1445 i+= MAX_FILENAME;
1446 strncpy((char *)global_settings.font_file, (char *)&config_block[i],
1447 MAX_FILENAME);
1448 i+= MAX_FILENAME;
1449#ifdef HAVE_REMOTE_LCD
1450 strncpy((char *)global_settings.rwps_file, (char *)&config_block[i],
1451 MAX_FILENAME);
1452 i+= MAX_FILENAME;
1453#endif
1454
1455#ifdef CONFIG_TUNER
1456 strncpy((char *)global_settings.fmr_file, (char *)&config_block[i],
1457 MAX_FILENAME);
1458 i+= MAX_FILENAME;
1459#endif
1460
1461#if LCD_DEPTH > 1
1462 strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i],
1463 MAX_FILENAME);
1464 i+= MAX_FILENAME;
1465#endif
1466#ifdef HAVE_LCD_BITMAP
1467 strncpy((char *)global_settings.kbd_file, (char *)&config_block[i],
1468 MAX_FILENAME);
1469 i+= MAX_FILENAME;
1470#endif
1471 }
1472} 652}
1473 653
1474void set_file(char* filename, char* setting, int maxlen) 654void set_file(char* filename, char* setting, int maxlen)
@@ -1502,94 +682,13 @@ void set_file(char* filename, char* setting, int maxlen)
1502 settings_save(); 682 settings_save();
1503} 683}
1504 684
1505/* helper to sort a .cfg file entry into a global_settings member, 685bool settings_load_config(const char* file, bool apply)
1506 as described per table. Returns the position if found, else 0. */
1507static int load_cfg_table(
1508 const struct bit_entry* p_table, /* the table which describes the entries */
1509 int count, /* number of entries in the table, including the first */
1510 const char* name, /* the item to be searched */
1511 const char* value, /* the value which got loaded for that item */
1512 int hint) /* position to start looking */
1513{
1514 int i = hint;
1515
1516 do
1517 {
1518 if (p_table[i].cfg_name != NULL && !strcasecmp(name, p_table[i].cfg_name))
1519 { /* found */
1520 int val = 0;
1521 if (p_table[i].cfg_val == NULL)
1522 { /* numerical value, just convert the string */
1523 val = atoi(value);
1524 }
1525#if HAVE_LCD_COLOR
1526 else if (!strncasecmp(p_table[i].cfg_val,"rgb",4))
1527 {
1528 val = hex_to_rgb(value);
1529 }
1530#endif
1531 else
1532 { /* set of string values, find the index */
1533 const char* item;
1534 const char* run;
1535 int len = strlen(value);
1536
1537 item = run = p_table[i].cfg_val;
1538
1539 while(1)
1540 {
1541 /* count the length of the field */
1542 while (*run != ',' && *run != '\0')
1543 run++;
1544
1545 if (!strncasecmp(value, item, MAX(run-item, len)))
1546 break; /* match, exit the search */
1547
1548 if (*run == '\0') /* reached the end of the choices */
1549 return i; /* return the position, but don't update */
1550
1551 val++; /* count the item up */
1552 run++; /* behind the ',' */
1553 item = run;
1554 }
1555 }
1556
1557 /* could do a memcpy, but that would be endian-dependent */
1558 switch(p_table[i].byte_size)
1559 {
1560 case 1:
1561 ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
1562 (unsigned char)val;
1563 break;
1564 case 2:
1565 ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
1566 (unsigned short)val;
1567 break;
1568 case 4:
1569 ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
1570 (unsigned int)val;
1571 break;
1572 default:
1573 DEBUGF( "illegal size!" );
1574 continue;
1575 }
1576
1577 return i; /* return the position */
1578 }
1579
1580 i++;
1581 if (i==count)
1582 i=1; /* wraparound */
1583 } while (i != hint); /* back where we started, all searched */
1584
1585 return 0; /* indicate not found */
1586}
1587
1588
1589bool settings_load_config(const char* file)
1590{ 686{
1591 int fd; 687 int fd;
1592 char line[128]; 688 char line[128];
689 char* name;
690 char* value;
691 int i;
1593 692
1594 fd = open(file, O_RDONLY); 693 fd = open(file, O_RDONLY);
1595 if (fd < 0) 694 if (fd < 0)
@@ -1597,180 +696,91 @@ bool settings_load_config(const char* file)
1597 696
1598 while (read_line(fd, line, sizeof line) > 0) 697 while (read_line(fd, line, sizeof line) > 0)
1599 { 698 {
1600 char* name;
1601 char* value;
1602 const struct bit_entry* table[2] = { rtc_bits, hd_bits };
1603 const int ta_size[2] = {
1604 sizeof(rtc_bits)/sizeof(rtc_bits[0]),
1605 sizeof(hd_bits)/sizeof(hd_bits[0])
1606 };
1607 int last_table = 0; /* which table was used last round */
1608 int last_pos = 1; /* at which position did we succeed */
1609 int pos; /* currently returned position */
1610
1611 if (!settings_parseline(line, &name, &value)) 699 if (!settings_parseline(line, &name, &value))
1612 continue; 700 continue;
1613 701
1614 /* check for the string values */ 702 for(i=0; i<nb_settings; i++)
1615 if (!strcasecmp(name, "wps")) {
1616#if LCD_DEPTH > 1
1617 unload_wps_backdrop();
1618#endif
1619 int fd2;
1620 if ((fd2 = open(value, O_RDONLY)) >= 0) {
1621 close(fd2);
1622 set_file(value, (char *)global_settings.wps_file, MAX_FILENAME);
1623 }
1624 }
1625#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
1626 else if (!strcasecmp(name, "rwps")) {
1627 int fd2;
1628 if ((fd2 = open(value, O_RDONLY)) >= 0) {
1629 close(fd2);
1630 set_file(value, (char *)global_settings.rwps_file, MAX_FILENAME);
1631 }
1632 }
1633#endif
1634 else if (!strcasecmp(name, "lang")) {
1635 if (!lang_load(value))
1636 {
1637 set_file(value, (char *)global_settings.lang_file, MAX_FILENAME);
1638 talk_init(); /* use voice of same language */
1639 }
1640 }
1641#ifdef CONFIG_TUNER
1642 else if (!strcasecmp(name, "fmr")) {
1643 set_file(value, global_settings.fmr_file, MAX_FILENAME);
1644 }
1645#endif
1646#ifdef HAVE_LCD_BITMAP
1647 else if (!strcasecmp(name, "font")) {
1648 if (font_load(value))
1649 set_file(value, (char *)global_settings.font_file, MAX_FILENAME);
1650 }
1651#endif
1652#if LCD_DEPTH > 1
1653 else if (!strcasecmp(name, "backdrop")) {
1654 if (load_main_backdrop(value)) {
1655 set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME);
1656 show_main_backdrop();
1657 }
1658 }
1659#endif
1660#ifdef HAVE_LCD_BITMAP
1661 else if (!strcasecmp(name, "keyboard")) {
1662 if (!load_kbd(value))
1663 set_file(value, (char *)global_settings.kbd_file, MAX_FILENAME);
1664 }
1665#endif
1666
1667
1668 /* check for scalar values, using the two tables */
1669 pos = load_cfg_table(table[last_table], ta_size[last_table],
1670 name, value, last_pos);
1671 if (pos) /* success */
1672 { 703 {
1673 last_pos = pos; /* remember as a position hint for next round */ 704 if (settings[i].cfg_name == NULL)
1674 continue; 705 continue;
1675 } 706 if (!strcasecmp(name,settings[i].cfg_name))
1676 707 {
1677 last_table = 1-last_table; /* try other table */ 708 switch (settings[i].flags&F_T_MASK)
1678 last_pos = 1; /* search from start */ 709 {
1679 pos = load_cfg_table(table[last_table], ta_size[last_table], 710 case F_T_INT:
1680 name, value, last_pos); 711 case F_T_UINT:
1681 if (pos) /* success */ 712#ifdef HAVE_LCD_COLOR
1682 { 713 if (settings[i].flags&F_RGB)
1683 last_pos = pos; /* remember as a position hint for next round */ 714 *(int*)settings[i].setting = hex_to_rgb(value);
1684 continue; 715 else
1685 } 716#endif
1686 } 717 if (settings[i].cfg_vals == NULL)
718 {
719 *(int*)settings[i].setting = atoi(value);
720 }
721 else
722 {
723 char *s,*end;
724 char vals[MAX_PATH];
725 int val = 0;
726 strncpy(vals,settings[i].cfg_vals,MAX_PATH);
727 s = strtok_r(vals,",",&end);
728 while (s)
729 {
730 if (!strcmp(value,s))
731 {
732 *(int*)settings[i].setting = val;
733 break;
734 }
735 val++;
736 s = strtok_r(NULL,",",&end);
737 }
738 }
739 break;
740 case F_T_BOOL:
741 *(bool*)settings[i].setting =
742 !strncmp(value,"off",3)?false:true;
743 break;
744 case F_T_CHARPTR:
745 case F_T_UCHARPTR:
746 {
747 char storage[MAX_PATH];
748 if (settings[i].filename_setting->prefix)
749 {
750 int len = strlen(settings[i].filename_setting->prefix);
751 if (!strncmp(value,settings[i].filename_setting->prefix,len))
752 {
753 strncpy(storage,&value[len],MAX_PATH);
754 }
755 else strncpy(storage,value,MAX_PATH);
756 }
757 else strncpy(storage,value,MAX_PATH);
758 if (settings[i].filename_setting->suffix)
759 {
760 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
761 if (s) *s = '\0';
762 }
763 strncpy((char*)settings[i].setting,storage,
764 settings[i].filename_setting->max_len);
765 ((char*)settings[i].setting)
766 [settings[i].filename_setting->max_len-1] = '\0';
767 break;
768 }
769 }
770 break;
771 } /* if (!strcmp(name,settings[i].cfg_name)) */
772 } /* for(...) */
773 } /* while(...) */
1687 774
1688 close(fd); 775 close(fd);
1689 settings_apply();
1690 settings_save(); 776 settings_save();
777 if (apply)
778 settings_apply();
1691 return true; 779 return true;
1692} 780}
1693 781
1694
1695/* helper to save content of global_settings into a file,
1696 as described per table */
1697static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
1698{
1699 long value; /* 32 bit content */
1700 int i;
1701 const struct bit_entry* p_run = p_table; /* start after the size info */
1702 count--; /* first is excluded from loop */
1703
1704 for (i=0; i<count; i++)
1705 {
1706 p_run++;
1707
1708 if (p_run->cfg_name == NULL)
1709 continue; /* this value is not to be saved */
1710
1711 /* could do a memcpy, but that would be endian-dependent */
1712 switch(p_run->byte_size)
1713 {
1714 case 1:
1715 if (p_run->bit_size & SIGNED) /* signed? */
1716 value = ((char*)&global_settings)[p_run->settings_offset];
1717 else
1718 value = ((unsigned char*)&global_settings)[p_run->settings_offset];
1719 break;
1720 case 2:
1721 if (p_run->bit_size & SIGNED) /* signed? */
1722 value = ((short*)&global_settings)[p_run->settings_offset/2];
1723 else
1724 value = ((unsigned short*)&global_settings)[p_run->settings_offset/2];
1725 break;
1726 case 4:
1727 value = ((unsigned int*)&global_settings)[p_run->settings_offset/4];
1728 break;
1729 default:
1730 DEBUGF( "illegal size!" );
1731 continue;
1732 }
1733
1734 if (p_run->cfg_val == NULL) /* write as number */
1735 {
1736 fdprintf(fd, "%s: %ld\r\n", p_run->cfg_name, value);
1737 }
1738#ifdef HAVE_LCD_COLOR
1739 else if (!strcasecmp(p_run->cfg_val, "rgb"))
1740 {
1741 fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
1742 (int)RGB_UNPACK_RED(value),
1743 (int)RGB_UNPACK_GREEN(value),
1744 (int)RGB_UNPACK_BLUE(value));
1745 }
1746#endif
1747 else /* write as item */
1748 {
1749 const char* p = p_run->cfg_val;
1750
1751 fdprintf(fd, "%s: ", p_run->cfg_name);
1752
1753 while(value >= 0)
1754 {
1755 char c = *p++; /* currently processed char */
1756 if (c == ',') /* separator */
1757 value--;
1758 else if (c == '\0') /* end of string */
1759 break; /* not found */
1760 else if (value == 0) /* the right place */
1761 write(fd, &c, 1); /* char by char, this is lame, OK */
1762 }
1763
1764 fdprintf(fd, "\r\n");
1765 if (p_run->cfg_val != off_on) /* explaination for non-bool */
1766 fdprintf(fd, "# (possible values: %s)\r\n", p_run->cfg_val);
1767 }
1768 }
1769}
1770
1771bool settings_save_config(void) 782bool settings_save_config(void)
1772{ 783{
1773 int fd;
1774 char filename[MAX_PATH]; 784 char filename[MAX_PATH];
1775 785
1776 create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2 786 create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2
@@ -1779,11 +789,7 @@ bool settings_save_config(void)
1779 /* allow user to modify filename */ 789 /* allow user to modify filename */
1780 while (true) { 790 while (true) {
1781 if (!kbd_input(filename, sizeof filename)) { 791 if (!kbd_input(filename, sizeof filename)) {
1782 fd = creat(filename, O_WRONLY); 792 break;
1783 if (fd < 0)
1784 gui_syncsplash(HZ, true, str(LANG_FAILED));
1785 else
1786 break;
1787 } 793 }
1788 else { 794 else {
1789 gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL)); 795 gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL));
@@ -1791,145 +797,43 @@ bool settings_save_config(void)
1791 } 797 }
1792 } 798 }
1793 799
1794 fdprintf(fd, "# .cfg file created by rockbox %s - " 800 if (settings_write_config(filename))
1795 "http://www.rockbox.org\r\n#\r\n#\r\n# wps / rwps / language" 801 gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
1796 " / font / fmpreset / backdrop \r\n#\r\n", appsversion); 802 else gui_syncsplash(HZ, true, str(LANG_FAILED));
1797
1798 if (global_settings.wps_file[0] != 0)
1799 fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR,
1800 global_settings.wps_file);
1801
1802#ifdef HAVE_REMOTE_LCD
1803 if (global_settings.rwps_file[0] != 0)
1804 fdprintf(fd, "rwps: %s/%s.rwps\r\n", WPS_DIR,
1805 global_settings.rwps_file);
1806#endif
1807
1808 if (global_settings.lang_file[0] != 0)
1809 fdprintf(fd, "lang: %s/%s.lng\r\n", LANG_DIR,
1810 global_settings.lang_file);
1811
1812#ifdef HAVE_LCD_BITMAP
1813 if (global_settings.font_file[0] != 0)
1814 fdprintf(fd, "font: %s/%s.fnt\r\n", FONT_DIR,
1815 global_settings.font_file);
1816#endif
1817
1818#if LCD_DEPTH > 1
1819 if (global_settings.backdrop_file[0] != 0)
1820 fdprintf(fd, "backdrop: %s/%s.bmp\r\n", BACKDROP_DIR,
1821 global_settings.backdrop_file);
1822#endif
1823
1824#ifdef CONFIG_TUNER
1825 if (global_settings.fmr_file[0] != 0)
1826 fdprintf(fd, "fmr: %s/%s.fmr\r\n", FMPRESET_PATH,
1827 global_settings.fmr_file);
1828#endif
1829
1830#ifdef HAVE_LCD_BITMAP
1831 if (global_settings.kbd_file[0] != 0)
1832 fdprintf(fd, "keyboard: %s/%s.kbd\r\n", ROCKBOX_DIR,
1833 global_settings.kbd_file);
1834#endif
1835
1836 /* here's the action: write values to file, specified via table */
1837 save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd);
1838 save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd);
1839
1840 close(fd);
1841
1842 gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
1843 return true; 803 return true;
1844} 804}
1845 805
1846 806
1847/* helper to load defaults from table into global_settings members */
1848static void default_table(const struct bit_entry* p_table, int count)
1849{
1850 int i;
1851
1852 for (i=1; i<count; i++) /* exclude the first, the size placeholder */
1853 {
1854 /* could do a memcpy, but that would be endian-dependent */
1855 switch(p_table[i].byte_size)
1856 {
1857 case 1:
1858 ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
1859 (unsigned char)p_table[i].default_val;
1860 break;
1861 case 2:
1862 ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
1863 (unsigned short)p_table[i].default_val;
1864 break;
1865 case 4:
1866 ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
1867 (unsigned int)p_table[i].default_val;
1868 break;
1869 default:
1870 DEBUGF( "illegal size!" );
1871 continue;
1872 }
1873 }
1874}
1875
1876 807
1877/* 808/*
1878 * reset all settings to their default value 809 * reset all settings to their default value
1879 */ 810 */
1880void settings_reset(void) { 811void settings_reset(void) {
1881 812
813 int i;
1882 DEBUGF( "settings_reset()\n" ); 814 DEBUGF( "settings_reset()\n" );
1883 815
1884 /* read defaults from table(s) into global_settings */ 816 for(i=0; i<nb_settings; i++)
1885 default_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0])); 817 {
1886 default_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0])); 818 switch (settings[i].flags&F_T_MASK)
1887 819 {
1888 /* do some special cases not covered by table */ 820 case F_T_INT:
1889 global_settings.volume = sound_default(SOUND_VOLUME); 821 case F_T_UINT:
1890 global_settings.balance = sound_default(SOUND_BALANCE); 822 if (settings[i].flags&F_T_SOUND)
1891 global_settings.bass = sound_default(SOUND_BASS); 823 *(int*)settings[i].setting =
1892 global_settings.treble = sound_default(SOUND_TREBLE); 824 sound_default(settings[i].sound_setting->setting);
1893 global_settings.channel_config = sound_default(SOUND_CHANNELS); 825 else *(int*)settings[i].setting = settings[i].default_val.int_;
1894 global_settings.stereo_width = sound_default(SOUND_STEREO_WIDTH); 826 break;
1895#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 827 case F_T_BOOL:
1896 global_settings.loudness = sound_default(SOUND_LOUDNESS); 828 *(bool*)settings[i].setting = settings[i].default_val.bool_;
1897 global_settings.avc = sound_default(SOUND_AVC); 829 break;
1898 global_settings.mdb_strength = sound_default(SOUND_MDB_STRENGTH); 830 case F_T_CHARPTR:
1899 global_settings.mdb_harmonics = sound_default(SOUND_MDB_HARMONICS); 831 case F_T_UCHARPTR:
1900 global_settings.mdb_center = sound_default(SOUND_MDB_CENTER); 832 strncpy((char*)settings[i].setting,
1901 global_settings.mdb_shape = sound_default(SOUND_MDB_SHAPE); 833 settings[i].default_val.charptr,MAX_FILENAME);
1902 global_settings.mdb_enable = sound_default(SOUND_MDB_ENABLE); 834 break;
1903 global_settings.superbass = sound_default(SOUND_SUPERBASS); 835 }
1904#endif 836 } /* for(...) */
1905#ifdef HAVE_LCD_CONTRAST
1906 global_settings.contrast = lcd_default_contrast();
1907#endif
1908#ifdef HAVE_LCD_REMOTE
1909 global_settings.remote_contrast = lcd_remote_default_contrast();
1910#endif
1911
1912#ifdef CONFIG_TUNER
1913 global_settings.fmr_file[0] = '\0';
1914#endif
1915 global_settings.wps_file[0] = '\0';
1916#ifdef HAVE_REMOTE_LCD
1917 global_settings.rwps_file[0] = '\0';
1918#endif
1919 global_settings.font_file[0] = '\0';
1920 global_settings.lang_file[0] = '\0';
1921#if LCD_DEPTH > 1
1922 global_settings.backdrop_file[0] = '\0';
1923#endif
1924#ifdef HAVE_LCD_COLOR
1925 global_settings.fg_color = LCD_DEFAULT_FG;
1926 global_settings.bg_color = LCD_DEFAULT_BG;
1927#endif
1928#ifdef HAVE_LCD_BITMAP
1929 global_settings.kbd_file[0] = '\0';
1930#endif
1931 global_settings.hold_lr_for_scroll_in_list = true;
1932
1933#if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC 837#if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
1934 enc_global_settings_reset(); 838 enc_global_settings_reset();
1935#endif 839#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 @@
54#define REC_BASE_DIR "/recordings" 54#define REC_BASE_DIR "/recordings"
55#define EQS_DIR ROCKBOX_DIR "/eqs" 55#define EQS_DIR ROCKBOX_DIR "/eqs"
56#define CODECS_DIR ROCKBOX_DIR"/codecs" 56#define CODECS_DIR ROCKBOX_DIR"/codecs"
57#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
58
59#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
57 60
58#define MAX_FILENAME 20 61#define MAX_FILENAME 20
59 62
@@ -547,7 +550,6 @@ struct opt_items {
547 550
548/* prototypes */ 551/* prototypes */
549 552
550void settings_calc_config_sector(void);
551int settings_save(void); 553int settings_save(void);
552void settings_load(int which); 554void settings_load(int which);
553void settings_reset(void); 555void settings_reset(void);
@@ -556,7 +558,7 @@ void settings_apply(void);
556void settings_apply_pm_range(void); 558void settings_apply_pm_range(void);
557void settings_display(void); 559void settings_display(void);
558 560
559bool settings_load_config(const char* file); 561bool settings_load_config(const char* file, bool apply);
560bool settings_save_config(void); 562bool settings_save_config(void);
561bool set_bool_options(const char* string, bool* variable, 563bool set_bool_options(const char* string, bool* variable,
562 const char* yes_str, int yes_voice, 564 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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2007 Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include <stdbool.h>
22
23#include "lang.h"
24#include "lcd.h"
25#include "settings.h"
26#include "settings_list.h"
27#include "sound.h"
28
29/* some sets of values which are used more than once, to save memory */
30static const char off_on[] = "off,on";
31static const char off_on_ask[] = "off,on,ask";
32static const char off_number_spell_hover[] = "off,number,spell,hover";
33#ifdef HAVE_LCD_BITMAP
34static const char graphic_numeric[] = "graphic,numeric";
35#endif
36
37#ifdef HAVE_RECORDING
38/* keep synchronous to trig_durations and
39 trigger_times in settings_apply_trigger */
40static const char trig_durations_conf [] =
41 "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min";
42/* these should be in the config.h files */
43#if CONFIG_CODEC == MAS3587F
44# define DEFAULT_REC_MIC_GAIN 8
45# define DEFAULT_REC_LEFT_GAIN 2
46# define DEFAULT_REC_RIGHT_GAIN 2
47#elif CONFIG_CODEC == SWCODEC
48# ifdef HAVE_UDA1380
49# define DEFAULT_REC_MIC_GAIN 16
50# define DEFAULT_REC_LEFT_GAIN 0
51# define DEFAULT_REC_RIGHT_GAIN 0
52# elif defined(HAVE_TLV320)
53# define DEFAULT_REC_MIC_GAIN 0
54# define DEFAULT_REC_LEFT_GAIN 0
55# define DEFAULT_REC_RIGHT_GAIN 0
56# elif defined(HAVE_WM8975)
57# define DEFAULT_REC_MIC_GAIN 16
58# define DEFAULT_REC_LEFT_GAIN 0
59# define DEFAULT_REC_RIGHT_GAIN 0
60# elif defined(HAVE_WM8758)
61# define DEFAULT_REC_MIC_GAIN 16
62# define DEFAULT_REC_LEFT_GAIN 0
63# define DEFAULT_REC_RIGHT_GAIN 0
64# elif defined(HAVE_WM8731)
65# define DEFAULT_REC_MIC_GAIN 16
66# define DEFAULT_REC_LEFT_GAIN 0
67# define DEFAULT_REC_RIGHT_GAIN 0
68# endif
69#endif
70
71#endif /* HAVE_RECORDING */
72
73#if defined(CONFIG_BACKLIGHT)
74static const char backlight_times_conf [] =
75 "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
76#endif
77
78
79#define GS(a) &global_settings.a
80
81#define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT)
82/** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h
83 and you may need to update it if you edit this file */
84
85#define UNUSED {.RESERVED=NULL}
86#define INT(a) {.int_ = a}
87#define UINT(a) {.uint_ = a}
88#define BOOL(a) {.bool_ = a}
89#define CHARPTR(a) {.charptr = a}
90#define UCHARPTR(a) {.ucharptr = a}
91#define NODEFAULT INT(0)
92
93#define SOUND_SETTING(flags,var,setting) \
94 {flags|F_T_INT|F_T_SOUND, GS(var), NODEFAULT,#var,NULL,\
95 {.sound_setting=(struct sound_setting[]){{setting}}} }
96
97#define BOOL_SETTING(flags,var,default,name,cfgvals,yes,no,opt_cb) \
98 {flags|F_T_BOOL, GS(var), BOOL(default),name,cfgvals, \
99 {.bool_setting=(struct bool_setting[]){{opt_cb,yes,no}}} }
100
101#define OFFON_SETTING(flags,var,default,name,cb) \
102 {flags|F_T_BOOL, GS(var), BOOL(default),name,off_on, \
103 {.bool_setting=(struct bool_setting[]) \
104 {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} }
105
106#define SYSTEM_SETTING(flags,var,default) \
107 {flags|F_T_INT, GS(var), INT(default), NULL, NULL, UNUSED}
108
109#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \
110 {flags|F_T_UCHARPTR, GS(var), CHARPTR(default),name,NULL,\
111 {.filename_setting=(struct filename_setting[]){{prefix,suffix,len}}} }
112const struct settings_list settings[] = {
113 /* sound settings */
114 SOUND_SETTING(0,volume,SOUND_VOLUME),
115 SOUND_SETTING(0,balance,SOUND_BALANCE),
116 SOUND_SETTING(0,bass,SOUND_BASS),
117 SOUND_SETTING(0,treble,SOUND_TREBLE),
118#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
119 { F_T_INT, GS(loudness), INT(0), "loudness", NULL, UNUSED },
120 { F_T_INT, GS(avc), INT(0), "auto volume", "off,20ms,2,4,8", UNUSED },
121 OFFON_SETTING(0,superbass,false,"superbass",NULL),
122#endif
123 { F_T_INT, GS(channel_config), INT(0), "channels",
124 "stereo,mono,custom,mono left,mono right,karaoke", UNUSED },
125 { F_T_INT, GS(stereo_width), INT(100), "stereo width", NULL, UNUSED },
126 /* playback */
127 OFFON_SETTING(0,resume,false,"resume", NULL),
128 OFFON_SETTING(0,playlist_shuffle,false,"shuffle", NULL),
129 SYSTEM_SETTING(NVRAM(4),resume_index,-1),
130 SYSTEM_SETTING(NVRAM(4),resume_first_index,0),
131 SYSTEM_SETTING(NVRAM(4),resume_offset,-1),
132 SYSTEM_SETTING(NVRAM(4),resume_seed,-1),
133 {F_T_INT, GS(repeat_mode), INT(REPEAT_ALL), "repeat",
134 "off,all,one,shuffle,ab" , UNUSED},
135 /* LCD */
136#ifdef HAVE_LCD_CONTRAST
137 {F_T_INT, GS(contrast), INT(DEFAULT_CONTRAST_SETTING),
138 "contrast", NULL , UNUSED},
139#endif
140#ifdef CONFIG_BACKLIGHT
141 {F_T_INT, GS(backlight_timeout), INT(6),
142 "backlight timeout",backlight_times_conf , UNUSED},
143#ifdef CONFIG_CHARGING
144 {F_T_INT, GS(backlight_timeout_plugged), INT(11),
145 "backlight timeout plugged",backlight_times_conf , UNUSED},
146#endif
147#endif /* CONFIG_BACKLIGHT */
148#ifdef HAVE_LCD_BITMAP
149 OFFON_SETTING(0,invert,false,"invert", NULL),
150 OFFON_SETTING(0,flip_display,false,"flip display", NULL),
151 /* display */
152 OFFON_SETTING(0,invert_cursor,true,"invert cursor", NULL),
153 OFFON_SETTING(0,statusbar,true,"statusbar", NULL),
154 OFFON_SETTING(0,scrollbar,true,"scrollbar", NULL),
155#if CONFIG_KEYPAD == RECORDER_PAD
156 OFFON_SETTING(0,buttonbar,true,"buttonbar", NULL),
157#endif
158 {F_T_INT,GS(volume_type),INT(0),"volume display",graphic_numeric,UNUSED},
159 {F_T_INT,GS(battery_display),INT(0),"battery display",graphic_numeric,UNUSED},
160 {F_T_INT,GS(timeformat),INT(0),"time format","24hour,12hour",UNUSED},
161#endif /* HAVE_LCD_BITMAP */
162 OFFON_SETTING(0,show_icons,true,"show icons", NULL),
163 /* system */
164 {F_T_INT,GS(poweroff),INT(10),"idle poweroff",
165 "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60",UNUSED},
166 SYSTEM_SETTING(NVRAM(4),runtime,0),
167 SYSTEM_SETTING(NVRAM(4),topruntime,0),
168#if MEM > 1
169 {F_T_INT,GS(max_files_in_playlist),INT(10000),
170 "max files in playlist",NULL,UNUSED},
171 {F_T_INT,GS(max_files_in_dir),INT(400),
172 "max files in dir",NULL,UNUSED},
173#else
174 {F_T_INT,GS(max_files_in_playlist),INT(1000),
175 "max files in playlist",NULL,UNUSED},
176 {F_T_INT,GS(max_files_in_dir),INT(200),
177 "max files in dir",NULL,UNUSED},
178#endif
179 {F_T_INT,GS(battery_capacity),INT(BATTERY_CAPACITY_DEFAULT),
180 "battery capacity",NULL,UNUSED},
181#ifdef CONFIG_CHARGING
182 OFFON_SETTING(0,car_adapter_mode,false,"car adapter mode", NULL),
183#endif
184 /* tuner */
185#ifdef CONFIG_TUNER
186 OFFON_SETTING(0,fm_force_mono,false,"force fm mono", NULL),
187 SYSTEM_SETTING(NVRAM(4),last_frequency,0),
188#endif
189
190#if BATTERY_TYPES_COUNT > 1
191 {F_T_INT,GS(battery_type),INT(0),
192 "battery type","alkaline,nimh",UNUSED},
193#endif
194#ifdef HAVE_REMOTE_LCD
195 /* remote lcd */
196 {F_T_INT,GS(remote_contrast),INT(DEFAULT_REMOTE_CONTRAST_SETTING),
197 "remote contrast",NULL,UNUSED},
198 OFFON_SETTING(0,remote_invert,false,"remote invert", NULL),
199 OFFON_SETTING(0,remote_flip_display,false,"remote flip display", NULL),
200 {F_T_INT,GS(remote_backlight_timeout),INT(6),
201 "remote backlight timeout",backlight_times_conf,UNUSED},
202#ifdef CONFIG_CHARGING
203 {F_T_INT,GS(remote_backlight_timeout_plugged),INT(11),
204 "remote backlight timeout plugged",backlight_times_conf,UNUSED},
205#endif
206#ifdef HAVE_REMOTE_LCD_TICKING
207 OFFON_SETTING(0,remote_reduce_ticking,false,"remote reduce ticking", NULL),
208#endif
209#endif
210
211#ifdef CONFIG_BACKLIGHT
212 OFFON_SETTING(0,bl_filter_first_keypress,false,
213 "backlight filters first keypress", NULL),
214#ifdef HAVE_REMOTE_LCD
215 OFFON_SETTING(0,remote_bl_filter_first_keypress,false,
216 "backlight filters first remote keypress", NULL),
217#endif
218#endif /* CONFIG_BACKLIGHT */
219
220/** End of old RTC config block **/
221
222#ifdef CONFIG_BACKLIGHT
223 OFFON_SETTING(0,caption_backlight,false,"caption backlight",NULL),
224#ifdef HAVE_REMOTE_LCD
225 OFFON_SETTING(0,remote_caption_backlight,false,"remote caption backlight",NULL),
226#endif
227#endif /* CONFIG_BACKLIGHT */
228#ifdef HAVE_BACKLIGHT_BRIGHTNESS
229 {F_T_INT,GS(brightness), INT(DEFAULT_BRIGHTNESS_SETTING), "brightness", NULL ,UNUSED},
230#endif
231#ifdef HAVE_BACKLIGHT_PWM_FADING
232 /* backlight fading */
233 {F_T_INT,GS(backlight_fade_in),INT(1),
234 "backlight fade in","off,500ms,1s,2s",UNUSED},
235 {F_T_INT,GS(backlight_fade_out),INT(1),
236 "backlight fade out","off,500ms,1s,2s,3s,4s,5s,10s",UNUSED},
237#endif
238 {F_T_INT,GS(scroll_speed),INT(9),"scroll speed",NULL,UNUSED},
239 {F_T_INT,GS(scroll_delay),INT(100),"scroll delay",NULL,UNUSED},
240 {F_T_INT,GS(bidir_limit),INT(50),"bidir limit",NULL,UNUSED},
241#ifdef HAVE_REMOTE_LCD
242 {F_T_INT,GS(remote_scroll_speed),INT(9),"remote scroll speed",NULL,UNUSED},
243 {F_T_INT,GS(remote_scroll_step),INT(6),"remote scroll step",NULL,UNUSED},
244 {F_T_INT,GS(remote_scroll_delay),INT(100),"remote scroll delay",NULL,UNUSED},
245 {F_T_INT,GS(remote_bidir_limit),INT(50),"remote bidir limit",NULL,UNUSED},
246#endif
247#ifdef HAVE_LCD_BITMAP
248 OFFON_SETTING(0,offset_out_of_view,false,"Screen Scrolls Out Of View",NULL),
249 {F_T_INT,GS(scroll_step),INT(6),"scroll step",NULL,UNUSED},
250 {F_T_INT,GS(screen_scroll_step),INT(16),"screen scroll step",NULL,UNUSED},
251#endif /* HAVE_LCD_BITMAP */
252 OFFON_SETTING(0,scroll_paginated,false,"scroll paginated",NULL),
253#ifdef HAVE_LCD_COLOR
254 {F_T_INT|F_RGB,GS(fg_color),INT(LCD_DEFAULT_FG),"foreground color",NULL,UNUSED},
255 {F_T_INT|F_RGB,GS(bg_color),INT(LCD_DEFAULT_BG),"background color",NULL,UNUSED},
256#endif
257 /* more playback */
258 OFFON_SETTING(0,play_selected,true,"play selected",NULL),
259 OFFON_SETTING(0,fade_on_stop,true,"volume fade",NULL),
260 {F_T_INT,GS(ff_rewind_min_step),INT(FF_REWIND_1000),
261 "scan min step","1,2,3,4,5,6,8,10,15,20,25,30,45,60",UNUSED},
262 {F_T_INT,GS(ff_rewind_accel),INT(3),"scan accel",NULL,UNUSED},
263#if CONFIG_CODEC == SWCODEC
264 {F_T_INT,GS(buffer_margin),INT(0),"antiskip",
265 "5s,15s,30s,1min,2min,3min,5min,10min",UNUSED},
266#else
267 {F_T_INT,GS(buffer_margin),INT(0),"antiskip",NULL,UNUSED},
268#endif
269 /* disk */
270#ifndef HAVE_MMC
271#ifdef HAVE_ATA_POWER_OFF
272 OFFON_SETTING(0,disk_poweroff,false,"disk poweroff",NULL),
273#endif
274 {F_T_INT,GS(disk_spindown),INT(5),"disk spindown",NULL,UNUSED},
275#endif /* HAVE_MMC */
276 /* browser */
277 {F_T_INT,GS(dirfilter),INT(SHOW_SUPPORTED),"show files",
278 "all,supported,music,playlists"
279#ifdef HAVE_TAGCACHE
280 ",id3 database"
281#endif
282 ,UNUSED},
283 OFFON_SETTING(0,sort_case,false,"sort case",NULL),
284 OFFON_SETTING(0,browse_current,false,"follow playlist",NULL),
285 OFFON_SETTING(0,playlist_viewer_icons,true,
286 "playlist viewer icons",NULL),
287 OFFON_SETTING(0,playlist_viewer_indices,true,
288 "playlist viewer indices",NULL),
289 {F_T_INT,GS(recursive_dir_insert),INT(RECURSE_OFF),
290 "recursive directory insert",off_on_ask,UNUSED},
291 /* bookmarks */
292 {F_T_INT,GS(autocreatebookmark),INT(BOOKMARK_NO),"autocreate bookmarks",
293 "off,on,ask,recent only - on,recent only - ask",UNUSED},
294 {F_T_INT,GS(autoloadbookmark),INT(BOOKMARK_NO),
295 "autoload bookmarks",off_on_ask,UNUSED},
296 {F_T_INT,GS(usemrb),INT(BOOKMARK_NO),
297 "use most-recent-bookmarks","off,on,unique only",UNUSED},
298#ifdef HAVE_LCD_BITMAP
299 /* peak meter */
300 {F_T_INT,GS(peak_meter_clip_hold),INT(16),"peak meter clip hold",
301 "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min"
302 ",3min,5min,10min,20min,45min,90min",UNUSED},
303 {F_T_INT,GS(peak_meter_hold),INT(3),"peak meter hold",
304 "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min",UNUSED},
305 {F_T_INT,GS(peak_meter_release),INT(8),"peak meter release",NULL,UNUSED},
306 OFFON_SETTING(0,peak_meter_dbfs,true,"peak meter dbfs",NULL),
307 {F_T_INT,GS(peak_meter_min),INT(60),"peak meter min",NULL,UNUSED},
308 {F_T_INT,GS(peak_meter_max),INT(0),"peak meter max",NULL,UNUSED},
309#endif
310#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
311 {F_T_INT,GS(mdb_strength),INT(0),"mdb strength",NULL,UNUSED},
312 {F_T_INT,GS(mdb_harmonics),INT(0),"mdb harmonics",NULL,UNUSED},
313 {F_T_INT,GS(mdb_center),INT(0),"mdb center",NULL,UNUSED},
314 {F_T_INT,GS(mdb_shape),INT(0),"mdb shape",NULL,UNUSED},
315 OFFON_SETTING(0,mdb_enable,false,"mdb enable",NULL),
316#endif
317#if CONFIG_CODEC == MAS3507D
318 OFFON_SETTING(0,line_in,false,"line in",NULL),
319#endif
320 /* voice */
321 {F_T_INT,GS(talk_dir),INT(0),"talk dir",off_number_spell_hover,UNUSED},
322 {F_T_INT,GS(talk_file),INT(0),"talk file",off_number_spell_hover,UNUSED},
323 OFFON_SETTING(0,talk_menu,true,"talk menu",NULL),
324
325 {F_T_INT,GS(sort_file),INT(0),"sort files","alpha,oldest,newest,type",UNUSED},
326 {F_T_INT,GS(sort_dir),INT(0),"sort dirs","alpha,oldest,newest",UNUSED},
327 BOOL_SETTING(0,id3_v1_first,false,"id3 tag priority","v2-v1,v1-v2",
328 LANG_ID3_V2_FIRST,LANG_ID3_V1_FIRST,NULL),
329
330#ifdef HAVE_RECORDING
331 /* recording */
332 OFFON_SETTING(0,recscreen_on,false,"recscreen on",NULL),
333 OFFON_SETTING(0,rec_startup,false,"rec screen on startup",NULL),
334 {F_T_INT,GS(rec_timesplit),INT(0),"rec timesplit",
335 "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,"
336 "04:00,06:00,08:00,10:00,12:00,18:00,24:00",UNUSED},
337 {F_T_INT,GS(rec_sizesplit),INT(0),"rec sizesplit",
338 "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,"
339 "256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB",UNUSED},
340 {F_T_INT,GS(rec_channels),INT(0),"rec channels","stereo,mono",UNUSED},
341 {F_T_INT,GS(rec_split_type),INT(0),"rec split type","Split, Stop",UNUSED},
342 {F_T_INT,GS(rec_split_method),INT(0),"rec split method","Time,Filesize",UNUSED},
343 {F_T_INT,GS(rec_source),INT(0),"rec source","mic,line"
344#ifdef HAVE_SPDIF_IN
345 ",spdif"
346#endif
347#ifdef HAVE_FMRADIO_IN
348 ",fmradio"
349#endif
350 ,UNUSED},
351 {F_T_INT,GS(rec_prerecord_time),INT(0),"prerecording time",NULL,UNUSED},
352 {F_T_INT,GS(rec_directory),INT(0),"rec directory",REC_BASE_DIR ",current",UNUSED},
353#ifdef CONFIG_BACKLIGHT
354 {F_T_INT,GS(cliplight),INT(0),"cliplight","off,main,both,remote",UNUSED},
355#endif
356 {F_T_INT,GS(rec_mic_gain),INT(DEFAULT_REC_MIC_GAIN),
357 "rec mic gain",NULL,UNUSED},
358 {F_T_INT,GS(rec_left_gain),INT(DEFAULT_REC_LEFT_GAIN),
359 "rec left gain",NULL,UNUSED},
360 {F_T_INT,GS(rec_right_gain),INT(DEFAULT_REC_RIGHT_GAIN),
361 "rec right gain",NULL,UNUSED},
362#if CONFIG_CODEC == MAS3587F
363 {F_T_INT,GS(rec_frequency),INT(0),"rec frequency","44,48,32,22,24,16",UNUSED},
364 {F_T_INT,GS(rec_quality),INT(5),"rec quality",NULL,UNUSED},
365 OFFON_SETTING(0,rec_editable,false,"editable recordings",NULL),
366#endif /* CONFIG_CODEC == MAS3587F */
367#if CONFIG_CODEC == SWCODEC
368 {F_T_INT,GS(rec_frequency),INT(REC_FREQ_DEFAULT),
369 "rec frequency",REC_FREQ_CFG_VAL_LIST,UNUSED},
370 {F_T_INT,GS(rec_format),INT(REC_FORMAT_DEFAULT),
371 "rec format",REC_FORMAT_CFG_VAL_LIST,UNUSED},
372 /** Encoder settings start - keep these together **/
373 /* aiff_enc */
374 /* (no settings yet) */
375 /* mp3_enc */
376 {F_T_INT,GS(mp3_enc_config.bitrate),INT(MP3_ENC_BITRATE_CFG_DEFAULT),
377 "mp3_enc bitrate",MP3_ENC_BITRATE_CFG_VALUE_LIST,UNUSED},
378 /* wav_enc */
379 /* (no settings yet) */
380 /* wavpack_enc */
381 /* (no settings yet) */
382 /** Encoder settings end **/
383#endif /* CONFIG_CODEC == SWCODEC */
384 /* values for the trigger */
385 {F_T_INT,GS(rec_start_thres),INT(-35),
386 "trigger start threshold",NULL,UNUSED},
387 {F_T_INT,GS(rec_stop_thres),INT(-45),
388 "trigger stop threshold",NULL,UNUSED},
389 {F_T_INT,GS(rec_start_duration),INT(0),
390 "trigger start duration",trig_durations_conf,UNUSED},
391 {F_T_INT,GS(rec_stop_postrec),INT(2),
392 "trigger stop postrec",trig_durations_conf,UNUSED},
393 {F_T_INT,GS(rec_stop_gap),INT(1),
394 "trigger min gap",trig_durations_conf,UNUSED},
395 {F_T_INT,GS(rec_trigger_mode),INT(0),
396 "trigger mode","off,once,repeat",UNUSED},
397#endif /* HAVE_RECORDING */
398
399#ifdef HAVE_SPDIF_POWER
400 OFFON_SETTING(0,spdif_enable,false,"spdif enable",NULL),
401#endif
402 {F_T_INT,GS(next_folder),INT(FOLDER_ADVANCE_OFF),
403 "folder navigation","off,on,random",UNUSED},
404 OFFON_SETTING(0,runtimedb,false,"gather runtime data",NULL),
405
406#if CONFIG_CODEC == SWCODEC
407 OFFON_SETTING(0,replaygain,false,"replaygain",NULL),
408 {F_T_INT,GS(replaygain_type),INT(REPLAYGAIN_ALBUM),
409 "replaygain type","track,album,track shuffle",UNUSED},
410 OFFON_SETTING(0,replaygain_noclip,false,"replaygain noclip",NULL),
411 {F_T_INT,GS(replaygain_preamp),INT(0),"replaygain preamp",NULL,UNUSED},
412 {F_T_INT,GS(beep),INT(0),"beep","off,weak,moderate,strong",UNUSED},
413 {F_T_INT,GS(crossfade),INT(0),"crossfade",
414 "off,shuffle,track skip,shuffle and track skip,always",UNUSED},
415 {F_T_INT,GS(crossfade_fade_in_delay),INT(0),
416 "crossfade fade in delay",NULL,UNUSED},
417 {F_T_INT,GS(crossfade_fade_out_delay),INT(0),
418 "crossfade fade out delay",NULL,UNUSED},
419 {F_T_INT,GS(crossfade_fade_in_duration),INT(0),
420 "crossfade fade in duration",NULL,UNUSED},
421 {F_T_INT,GS(crossfade_fade_out_duration),INT(0),
422 "crossfade fade out duration",NULL,UNUSED},
423 {F_T_INT,GS(crossfade_fade_out_mixmode),INT(0),
424 "crossfade fade out mode","crossfade,mix",UNUSED},
425 {F_T_INT,GS(crossfade),INT(0),"crossfade",
426 "off,shuffle,track skip,shuffle and track skip,always",UNUSED},
427 OFFON_SETTING(0,crossfeed,false,"crossfeed",NULL),
428 {F_T_INT,GS(crossfeed_direct_gain),INT(15),
429 "crossfeed direct gain",NULL,UNUSED},
430 {F_T_INT,GS(crossfeed_cross_gain),INT(60),
431 "crossfeed cross gain",NULL,UNUSED},
432 {F_T_INT,GS(crossfeed_hf_attenuation),INT(160),
433 "crossfeed hf attenuation",NULL,UNUSED},
434 {F_T_INT,GS(crossfeed_hf_cutoff),INT(700),
435 "crossfeed hf cutoff",NULL,UNUSED},
436
437 /* equalizer */
438 OFFON_SETTING(0,eq_enabled,false,"eq enabled",NULL),
439 {F_T_INT,GS(eq_precut),INT(0),
440 "eq precut",NULL,UNUSED},
441 /* 0..32768 Hz */
442 {F_T_INT,GS(eq_band0_cutoff),INT(0),
443 "eq band 0 cutoff",NULL,UNUSED},
444 {F_T_INT,GS(eq_band1_cutoff),INT(200),
445 "eq band 1 cutoff",NULL,UNUSED},
446 {F_T_INT,GS(eq_band2_cutoff),INT(800),
447 "eq band 2 cutoff",NULL,UNUSED},
448 {F_T_INT,GS(eq_band3_cutoff),INT(4000),
449 "eq band 3 cutoff",NULL,UNUSED},
450 {F_T_INT,GS(eq_band4_cutoff),INT(12000),
451 "eq band 4 cutoff",NULL,UNUSED},
452 /* 0..64 (or 0.0 to 6.4) */
453 {F_T_INT,GS(eq_band0_q),INT(7),
454 "eq band 0 q",NULL,UNUSED},
455 {F_T_INT,GS(eq_band1_q),INT(10),
456 "eq band 1 q",NULL,UNUSED},
457 {F_T_INT,GS(eq_band2_q),INT(10),
458 "eq band 2 q",NULL,UNUSED},
459 {F_T_INT,GS(eq_band3_q),INT(10),
460 "eq band 3 q",NULL,UNUSED},
461 {F_T_INT,GS(eq_band4_q),INT(7),
462 "eq band 4 q",NULL,UNUSED},
463 /* -240..240 (or -24db to +24db) */
464 {F_T_INT,GS(eq_band0_gain),INT(0),
465 "eq band 0 gain",NULL,UNUSED},
466 {F_T_INT,GS(eq_band1_gain),INT(0),
467 "eq band 1 gain",NULL,UNUSED},
468 {F_T_INT,GS(eq_band2_gain),INT(0),
469 "eq band 2 gain",NULL,UNUSED},
470 {F_T_INT,GS(eq_band3_gain),INT(0),
471 "eq band 3 gain",NULL,UNUSED},
472 {F_T_INT,GS(eq_band4_gain),INT(0),
473 "eq band 4 gain",NULL,UNUSED},
474
475 /* dithering */
476 OFFON_SETTING(0,dithering_enabled,false,"dithering enabled",NULL),
477#endif
478#ifdef HAVE_DIRCACHE
479 OFFON_SETTING(0,dircache,false,"dircache",NULL),
480 SYSTEM_SETTING(NVRAM(4),dircache_size,0),
481#endif
482
483#ifdef HAVE_TAGCACHE
484#ifdef HAVE_TC_RAMCACHE
485 OFFON_SETTING(0,tagcache_ram,false,"tagcache_ram",NULL),
486#endif
487 OFFON_SETTING(0,tagcache_autoupdate,false,"tagcache_autoupdate",NULL),
488#endif
489
490 {F_T_INT,GS(default_codepage),INT(0),"default codepage",
491 "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,"
492 "iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256",UNUSED},
493
494 OFFON_SETTING(0,warnon_erase_dynplaylist,false,
495 "warn when erasing dynamic playlist",NULL),
496
497#ifdef CONFIG_BACKLIGHT
498#ifdef HAS_BUTTON_HOLD
499 {F_T_INT,GS(backlight_on_button_hold),INT(0),
500 "backlight on button hold","normal,off,on",UNUSED},
501#endif
502
503#ifdef HAVE_LCD_SLEEP
504 {F_T_INT,GS(lcd_sleep_after_backlight_off),INT(3),
505 "lcd sleep after backlight off",
506 "always,never,5,10,15,20,30,45,60,90",UNUSED},
507#endif
508#endif /* CONFIG_BACKLIGHT */
509
510#ifdef HAVE_WM8758
511 OFFON_SETTING(0,eq_hw_enabled,false,
512 "eq hardware enabled",NULL),
513
514 {F_T_INT,GS(eq_hw_band0_cutoff),INT(1),
515 "eq hardware band 0 cutoff",
516 "80Hz,105Hz,135Hz,175Hz",UNUSED},
517 {F_T_INT,GS(eq_hw_band0_gain),INT(0),
518 "eq hardware band 0 gain",NULL,UNUSED},
519
520 {F_T_INT,GS(eq_hw_band1_center),INT(1),
521 "eq hardware band 1 center",
522 "230Hz,300Hz,385Hz,500Hz",UNUSED},
523 {F_T_INT,GS(eq_hw_band1_bandwidth),INT(0),
524 "eq hardware band 1 bandwidth","narrow,wide",UNUSED},
525 {F_T_INT,GS(eq_hw_band1_gain),INT(0),
526 "eq hardware band 1 gain",NULL,UNUSED},
527
528 {F_T_INT,GS(eq_hw_band2_center),INT(1),
529 "eq hardware band 2 center",
530 "650Hz,850Hz,1.1kHz,1.4kHz",UNUSED},
531 {F_T_INT,GS(eq_hw_band2_bandwidth),INT(0),
532 "eq hardware band 2 bandwidth","narrow,wide",UNUSED},
533 {F_T_INT,GS(eq_hw_band2_gain),INT(0),
534 "eq hardware band 1 gain",NULL,UNUSED},
535
536 {F_T_INT,GS(eq_hw_band3_center),INT(1),
537 "eq hardware band 3 center",
538 "1.8kHz,2.4kHz,3.2kHz,4.1kHz",UNUSED},
539 {F_T_INT,GS(eq_hw_band3_bandwidth),INT(0),
540 "eq hardware band 3 bandwidth","narrow,wide",UNUSED},
541 {F_T_INT,GS(eq_hw_band3_gain),INT(0),
542 "eq hardware band 3 gain",NULL,UNUSED},
543
544 {F_T_INT,GS(eq_hw_band4_cutoff),INT(1),
545 "eq hardware band 4 cutoff",
546 "5.3kHz,6.9kHz,9kHz,11.7kHz",UNUSED},
547 {F_T_INT,GS(eq_hw_band4_gain),INT(0),
548 "eq hardware band 0 gain",NULL,UNUSED},
549#endif
550
551 OFFON_SETTING(0,hold_lr_for_scroll_in_list,true,
552 "hold_lr_for_scroll_in_list",NULL),
553 {F_T_INT,GS(show_path_in_browser),INT(SHOW_PATH_OFF),
554 "show path in browser","off,current directory,full path",UNUSED},
555
556#ifdef HAVE_AGC
557 {F_T_INT,GS(rec_agc_preset_mic),INT(1),"agc mic preset",NULL,UNUSED},
558 {F_T_INT,GS(rec_agc_preset_line),INT(1),"agc line preset",NULL,UNUSED},
559 {F_T_INT,GS(rec_agc_maxgain_mic),INT(104),
560 "agc maximum mic gain",NULL,UNUSED},
561 {F_T_INT,GS(rec_agc_maxgain_line),INT(96),
562 "agc maximum line gain",NULL,UNUSED},
563 {F_T_INT,GS(rec_agc_cliptime),INT(1),
564 "agc cliptime","0.2s,0.4s,0.6s,0.8,1s",UNUSED},
565#endif
566
567#ifdef HAVE_REMOTE_LCD
568#ifdef HAS_REMOTE_BUTTON_HOLD
569 {F_T_INT,GS(remote_backlight_on_button_hold),INT(0),
570 "remote backlight on button hold","normal,off,on",UNUSED},
571#endif
572#endif
573#ifdef HAVE_HEADPHONE_DETECTION
574 {F_T_INT,GS(unplug_mode),INT(0),"pause on headphone unplug",NULL,UNUSED},
575 {F_T_INT,GS(unplug_rw),INT(0),"rewind duration on pause",NULL,UNUSED},
576 OFFON_SETTING(0,unplug_autoresume,false,
577 "disable autoresume if phones not present",NULL),
578#endif
579#ifdef CONFIG_TUNER
580 {F_T_INT,GS(fm_region),INT(0),"fm_region","eu,us,jp,kr",UNUSED},
581#endif
582
583 OFFON_SETTING(0,audioscrobbler,false,"Last.fm Logging",NULL),
584
585#ifdef HAVE_RECORDING
586 {F_T_INT,GS(rec_trigger_type),INT(0),"trigger type","stop,pause,nf stp",UNUSED},
587#endif
588
589 /** settings not in the old config blocks **/
590#ifdef CONFIG_TUNER
591 FILENAME_SETTING(0,fmr_file,"fmr","",FMPRESET_PATH "/",".fmr",MAX_FILENAME+1),
592#endif
593 FILENAME_SETTING(0,font_file,"font","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
594 FILENAME_SETTING(0,wps_file, "wps","",WPS_DIR "/",".wps",MAX_FILENAME+1),
595 FILENAME_SETTING(0,lang_file,"lang","",LANG_DIR "/",".lng",MAX_FILENAME+1),
596#ifdef HAVE_REMOTE_LCD
597 FILENAME_SETTING(0,rwps_file,"rwps","",WPS_DIR "/",".rwps",MAX_FILENAME+1),
598#endif
599#if LCD_DEPTH > 1
600 FILENAME_SETTING(0,backdrop_file,"backdrop","",BACKDROP_DIR "/",".bmp",MAX_FILENAME+1),
601#endif
602#ifdef HAVE_LCD_BITMAP
603 FILENAME_SETTING(0,lang_file,"kbd","",ROCKBOX_DIR "/",".kbd",MAX_FILENAME+1),
604#endif
605
606};
607
608const 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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2007 Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef __SETTINGSLIST_H
20#define __SETTINGSLIST_H
21#include <stdio.h>
22#include <stddef.h>
23#include <stdbool.h>
24#include <limits.h>
25#include "inttypes.h"
26
27union storage_type {
28 int int_;
29 unsigned int uint_;
30 bool bool_;
31 char *charptr;
32 unsigned char *ucharptr;
33};
34/* the variable type for the setting */
35#define F_T_INT 1
36#define F_T_UINT 2
37#define F_T_BOOL 3
38#define F_T_CHARPTR 4
39#define F_T_UCHARPTR 5
40#define F_T_MASK 0x7
41
42struct sound_setting {
43 int setting; /* from the enum in firmware/sound.h */
44};
45#define F_T_SOUND 0x8 /* this variable uses the set_sound stuff, \
46 | with one of the above types (usually F_T_INT) \
47 These settings get the default from sound_default(setting); */
48struct bool_setting {
49 void (*option_callback)(bool);
50 int lang_yes;
51 int lang_no;
52};
53#define F_BOOL_SETTING F_T_BOOL|0x10
54#define F_RGB 0x20
55
56struct int_setting {
57 void (*option_callback)(int);
58 int min;
59 int max;
60 int step;
61};
62#define F_NVRAM_BYTES_MASK 0xE00 /*0-4 bytes can be stored */
63#define F_NVRAM_MASK_SHIFT 9
64#define NVRAM_CONFIG_VERSION 1
65/* Above define should be bumped if
66- a new NVRAM setting is added between 2 other NVRAM settings
67- number of bytes for a NVRAM setting is changed
68- a NVRAM setting is removed
69*/
70
71struct filename_setting {
72 const char* prefix;
73 const char* suffix;
74 int max_len;
75};
76#define F_FILENAME 0x40
77struct settings_list {
78 uint32_t flags; /* ____ ____ ____ ____ ____ NNN_ _FRB STTT */
79 void *setting;
80 union storage_type default_val;
81 const char *cfg_name; /* this settings name in the cfg file */
82 const char *cfg_vals; /*comma seperated legal values, or NULL */
83 /* used with F_T_UCHARPTR this is the folder prefix */
84 union {
85 void *RESERVED; /* to stop compile errors, will be removed */
86 struct sound_setting *sound_setting; /* use F_T_SOUND for this */
87 struct bool_setting *bool_setting; /* F_BOOL_SETTING */
88 struct filename_setting *filename_setting; /* use F_FILENAME */
89 };
90};
91
92#ifndef PLUGIN
93/* not needed for plugins and just causes compile error,
94 possibly fix proberly later */
95extern const struct settings_list settings[];
96extern const int nb_settings;
97
98#endif
99
100#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)
1844 case YESNO_YES: 1844 case YESNO_YES:
1845 settings_reset(); 1845 settings_reset();
1846 settings_apply(); 1846 settings_apply();
1847 settings_save();
1847 break; 1848 break;
1848 case YESNO_NO: 1849 case YESNO_NO:
1849 break; 1850 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;
81#ifdef HAVE_LBA48 81#ifdef HAVE_LBA48
82static bool lba48 = false; /* set for 48 bit addressing */ 82static bool lba48 = false; /* set for 48 bit addressing */
83#endif 83#endif
84static long ata_stack[DEFAULT_STACK_SIZE/sizeof(long)]; 84static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)];
85static const char ata_thread_name[] = "ata"; 85static const char ata_thread_name[] = "ata";
86static struct event_queue ata_queue; 86static struct event_queue ata_queue;
87static bool initialized = false; 87static 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;
92 92
93#ifdef HAVE_HOTSWAP 93#ifdef HAVE_HOTSWAP
94static bool mmc_monitor_enabled = true; 94static bool mmc_monitor_enabled = true;
95static long mmc_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 95static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)];
96#else 96#else
97static long mmc_stack[DEFAULT_STACK_SIZE/sizeof(long)]; 97static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)];
98#endif 98#endif
99static const char mmc_thread_name[] = "mmc"; 99static const char mmc_thread_name[] = "mmc";
100static struct event_queue mmc_queue; 100static struct event_queue mmc_queue;