diff options
Diffstat (limited to 'firmware')
33 files changed, 2325 insertions, 11 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 7053358bee..f59475e27a 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -14,8 +14,10 @@ target/hosted/cpuinfo-linux.c | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | target/hosted/powermgmt.c | 16 | target/hosted/powermgmt.c |
17 | #ifndef SAMSUNG_YPR0 /* uses as3514 rtc */ | ||
17 | target/hosted/rtc.c | 18 | target/hosted/rtc.c |
18 | #endif | 19 | #endif |
20 | #endif | ||
19 | system.c | 21 | system.c |
20 | usb.c | 22 | usb.c |
21 | #ifdef ROCKBOX_HAS_LOGF | 23 | #ifdef ROCKBOX_HAS_LOGF |
@@ -62,6 +64,26 @@ target/hosted/sdl/app/button-application.c | |||
62 | #endif | 64 | #endif |
63 | #endif | 65 | #endif |
64 | 66 | ||
67 | #ifdef SAMSUNG_YPR0 | ||
68 | #if (CONFIG_RTC == RTC_AS3514) | ||
69 | drivers/rtc/rtc_as3514.c | ||
70 | #else | ||
71 | target/hosted/rtc.c | ||
72 | #endif | ||
73 | target/hosted/ypr0/button-ypr0.c | ||
74 | target/hosted/ypr0/kernel-ypr0.c | ||
75 | target/hosted/ypr0/lcd-ypr0.c | ||
76 | target/hosted/ypr0/system-ypr0.c | ||
77 | target/hosted/ypr0/fs-ypr0.c | ||
78 | target/hosted/ypr0/lc-ypr0.c | ||
79 | thread.c | ||
80 | #ifdef HAVE_BACKLIGHT | ||
81 | target/hosted/ypr0/backlight-ypr0.c | ||
82 | #endif | ||
83 | target/hosted/ypr0/ascodec-ypr0.c | ||
84 | target/hosted/ypr0/powermgmt-ypr0.c | ||
85 | #endif | ||
86 | |||
65 | /* Maemo specific files */ | 87 | /* Maemo specific files */ |
66 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) | 88 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) |
67 | target/hosted/maemo/maemo-thread.c | 89 | target/hosted/maemo/maemo-thread.c |
@@ -368,6 +390,10 @@ drivers/audio/aic3x.c | |||
368 | #elif defined (HAVE_DUMMY_CODEC) | 390 | #elif defined (HAVE_DUMMY_CODEC) |
369 | drivers/audio/dummy_codec.c | 391 | drivers/audio/dummy_codec.c |
370 | #endif /* defined(HAVE_*) */ | 392 | #endif /* defined(HAVE_*) */ |
393 | #else /* PLATFORM_HOSTED */ | ||
394 | #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) | ||
395 | drivers/audio/as3514.c | ||
396 | target/hosted/pcm-alsa.c | ||
371 | #elif defined(HAVE_SDL_AUDIO) | 397 | #elif defined(HAVE_SDL_AUDIO) |
372 | drivers/audio/sdl.c | 398 | drivers/audio/sdl.c |
373 | #if CONFIG_CODEC == SWCODEC | 399 | #if CONFIG_CODEC == SWCODEC |
@@ -377,6 +403,7 @@ target/hosted/maemo/pcm-gstreamer.c | |||
377 | target/hosted/sdl/pcm-sdl.c | 403 | target/hosted/sdl/pcm-sdl.c |
378 | #endif /* (CONFIG_PLATFORM & PLATFORM_MAEMO) */ | 404 | #endif /* (CONFIG_PLATFORM & PLATFORM_MAEMO) */ |
379 | #endif /* CONFIG_CODEC == SWCODEC */ | 405 | #endif /* CONFIG_CODEC == SWCODEC */ |
406 | #endif | ||
380 | #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER) */ | 407 | #endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER) */ |
381 | 408 | ||
382 | /* CPU Specific - By class then particular chip if applicable */ | 409 | /* CPU Specific - By class then particular chip if applicable */ |
@@ -722,7 +749,7 @@ target/arm/ascodec-pp.c | |||
722 | # endif | 749 | # endif |
723 | # if !defined(BOOTLOADER) || defined(CPU_PP) | 750 | # if !defined(BOOTLOADER) || defined(CPU_PP) |
724 | target/arm/adc-as3514.c | 751 | target/arm/adc-as3514.c |
725 | # ifndef SANSA_M200V4 | 752 | # if !defined(SANSA_M200V4) && !defined(SAMSUNG_YPR0) |
726 | target/arm/powermgmt-ascodec.c | 753 | target/arm/powermgmt-ascodec.c |
727 | # endif | 754 | # endif |
728 | # endif | 755 | # endif |
diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c index ed413eb03e..95bff3341f 100644 --- a/firmware/common/rbpaths.c +++ b/firmware/common/rbpaths.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <stdio.h> /* snprintf */ | 23 | #include <stdio.h> /* snprintf */ |
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | #include <stdarg.h> | 25 | #include <stdarg.h> |
26 | #include "config.h" | ||
26 | #include "rbpaths.h" | 27 | #include "rbpaths.h" |
27 | #include "file.h" /* MAX_PATH */ | 28 | #include "file.h" /* MAX_PATH */ |
28 | #include "logf.h" | 29 | #include "logf.h" |
@@ -38,11 +39,17 @@ | |||
38 | #undef mkdir | 39 | #undef mkdir |
39 | #undef rmdir | 40 | #undef rmdir |
40 | 41 | ||
42 | |||
41 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) | 43 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) |
42 | #include "dir-target.h" | 44 | #include "dir-target.h" |
43 | #define opendir opendir_android | 45 | #define opendir opendir_android |
44 | #define mkdir mkdir_android | 46 | #define mkdir mkdir_android |
45 | #define rmdir rmdir_android | 47 | #define rmdir rmdir_android |
48 | #elif defined(SAMSUNG_YPR0) | ||
49 | #include "dir-target.h" | ||
50 | #define opendir opendir_ypr0 | ||
51 | #define mkdir mkdir_ypr0 | ||
52 | #define rmdir rmdir_ypr0 | ||
46 | #elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA)) | 53 | #elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA)) |
47 | #define open sim_open | 54 | #define open sim_open |
48 | #define remove sim_remove | 55 | #define remove sim_remove |
@@ -59,6 +66,8 @@ extern int sim_rmdir(const char* name); | |||
59 | const char *rbhome; | 66 | const char *rbhome; |
60 | #endif | 67 | #endif |
61 | 68 | ||
69 | #if !defined(SAMSUNG_YPR0) | ||
70 | |||
62 | /* flags for get_user_file_path() */ | 71 | /* flags for get_user_file_path() */ |
63 | /* whether you need write access to that file/dir, especially true | 72 | /* whether you need write access to that file/dir, especially true |
64 | * for runtime generated files (config.cfg) */ | 73 | * for runtime generated files (config.cfg) */ |
@@ -238,3 +247,28 @@ int app_rmdir(const char* name) | |||
238 | } | 247 | } |
239 | return rmdir(fname); | 248 | return rmdir(fname); |
240 | } | 249 | } |
250 | |||
251 | #else | ||
252 | |||
253 | int app_open(const char *name, int o, ...) | ||
254 | { | ||
255 | if (o & O_CREAT) | ||
256 | { | ||
257 | int ret; | ||
258 | va_list ap; | ||
259 | va_start(ap, o); | ||
260 | ret = open(name, o, va_arg(ap, mode_t)); | ||
261 | va_end(ap); | ||
262 | return ret; | ||
263 | } | ||
264 | return open(name, o); | ||
265 | } | ||
266 | |||
267 | int app_creat(const char* name, mode_t mode) { return creat(name, mode); } | ||
268 | int app_remove(const char *name) { return remove(name); } | ||
269 | int app_rename(const char *old, const char *new) { return rename(old,new); } | ||
270 | DIR *app_opendir(const char *name) { return opendir(name); } | ||
271 | int app_mkdir(const char* name) { return mkdir(name); } | ||
272 | int app_rmdir(const char* name) { return rmdir(name); } | ||
273 | |||
274 | #endif | ||
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 64531cfc2b..0fe3070c19 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c | |||
@@ -78,6 +78,7 @@ const struct sound_settings_info audiohw_settings[] = { | |||
78 | #endif | 78 | #endif |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #ifndef SAMSUNG_YPR0 | ||
81 | /* Shadow registers */ | 82 | /* Shadow registers */ |
82 | static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ | 83 | static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ |
83 | 84 | ||
@@ -110,7 +111,29 @@ static void as3514_write_masked(unsigned int reg, unsigned int bits, | |||
110 | { | 111 | { |
111 | as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask)); | 112 | as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask)); |
112 | } | 113 | } |
114 | #else | ||
115 | static void as3514_write(unsigned int reg, unsigned int value) | ||
116 | { | ||
117 | ascodec_write(reg, value); | ||
118 | } | ||
119 | |||
120 | /* Helpers to set/clear bits */ | ||
121 | static void as3514_set(unsigned int reg, unsigned int bits) | ||
122 | { | ||
123 | ascodec_write(reg, ascodec_read(reg) | bits); | ||
124 | } | ||
125 | |||
126 | static void as3514_clear(unsigned int reg, unsigned int bits) | ||
127 | { | ||
128 | ascodec_write(reg, ascodec_read(reg) & ~bits); | ||
129 | } | ||
113 | 130 | ||
131 | static void as3514_write_masked(unsigned int reg, unsigned int bits, | ||
132 | unsigned int mask) | ||
133 | { | ||
134 | ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask)); | ||
135 | } | ||
136 | #endif | ||
114 | /* convert tenth of dB volume to master volume register value */ | 137 | /* convert tenth of dB volume to master volume register value */ |
115 | int tenthdb2master(int db) | 138 | int tenthdb2master(int db) |
116 | { | 139 | { |
@@ -145,8 +168,11 @@ int sound_val2phys(int setting, int value) | |||
145 | */ | 168 | */ |
146 | void audiohw_preinit(void) | 169 | void audiohw_preinit(void) |
147 | { | 170 | { |
171 | |||
172 | #ifndef SAMSUNG_YPR0 | ||
148 | /* read all reg values */ | 173 | /* read all reg values */ |
149 | ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs); | 174 | ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs); |
175 | #endif | ||
150 | 176 | ||
151 | #ifdef HAVE_AS3543 | 177 | #ifdef HAVE_AS3543 |
152 | 178 | ||
@@ -284,9 +310,14 @@ void audiohw_set_master_vol(int vol_l, int vol_r) | |||
284 | #if CONFIG_CPU == AS3525v2 | 310 | #if CONFIG_CPU == AS3525v2 |
285 | #define MIXER_MAX_VOLUME 0x1b | 311 | #define MIXER_MAX_VOLUME 0x1b |
286 | #else /* lets leave the AS3514 alone until its better tested*/ | 312 | #else /* lets leave the AS3514 alone until its better tested*/ |
313 | #ifdef SAMSUNG_YPR0 | ||
314 | #define MIXER_MAX_VOLUME 0x1a | ||
315 | #else | ||
287 | #define MIXER_MAX_VOLUME 0x16 | 316 | #define MIXER_MAX_VOLUME 0x16 |
288 | #endif | 317 | #endif |
318 | #endif | ||
289 | 319 | ||
320 | #ifndef SAMSUNG_YPR0 | ||
290 | if (vol_r <= MIXER_MAX_VOLUME) { | 321 | if (vol_r <= MIXER_MAX_VOLUME) { |
291 | mix_r = vol_r; | 322 | mix_r = vol_r; |
292 | hph_r = 0; | 323 | hph_r = 0; |
@@ -302,7 +333,16 @@ void audiohw_set_master_vol(int vol_l, int vol_r) | |||
302 | mix_l = MIXER_MAX_VOLUME; | 333 | mix_l = MIXER_MAX_VOLUME; |
303 | hph_l = vol_l - MIXER_MAX_VOLUME; | 334 | hph_l = vol_l - MIXER_MAX_VOLUME; |
304 | } | 335 | } |
305 | 336 | #else | |
337 | /* Okay. This is shit coded indeed. It is just a test. | ||
338 | Some considerations: Samsung keeps DAC constantly to 0x1a volume. It modifies only the headphone amp volume | ||
339 | */ | ||
340 | |||
341 | mix_r = 0x1a; | ||
342 | mix_l = 0x1a; | ||
343 | hph_l = vol_l; | ||
344 | hph_r = vol_r; | ||
345 | #endif | ||
306 | 346 | ||
307 | as3514_write_masked(AS3514_DAC_R, mix_r, AS3514_VOL_MASK); | 347 | as3514_write_masked(AS3514_DAC_R, mix_r, AS3514_VOL_MASK); |
308 | as3514_write_masked(AS3514_DAC_L, mix_l, AS3514_VOL_MASK); | 348 | as3514_write_masked(AS3514_DAC_L, mix_l, AS3514_VOL_MASK); |
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index 44ef3cc4a1..868fa9753b 100644 --- a/firmware/drivers/rtc/rtc_as3514.c +++ b/firmware/drivers/rtc/rtc_as3514.c | |||
@@ -141,11 +141,11 @@ void rtc_alarm_poweroff(void) | |||
141 | seconds = 24*3600; | 141 | seconds = 24*3600; |
142 | 142 | ||
143 | seconds -= tm.tm_sec; | 143 | seconds -= tm.tm_sec; |
144 | 144 | #ifndef SAMSUNG_YPR0 | |
145 | /* disable MCLK, it is a wakeup source and prevents proper shutdown */ | 145 | /* disable MCLK, it is a wakeup source and prevents proper shutdown */ |
146 | CGU_AUDIO = (2 << 0) | (1 << 11); | 146 | CGU_AUDIO = (2 << 0) | (1 << 11); |
147 | CGU_PLLBSUP = (1 << 2) | (1 << 3); | 147 | CGU_PLLBSUP = (1 << 2) | (1 << 3); |
148 | 148 | #endif | |
149 | /* write wakeup register */ | 149 | /* write wakeup register */ |
150 | alarm.seconds = seconds; | 150 | alarm.seconds = seconds; |
151 | alarm.enabled = true; | 151 | alarm.enabled = true; |
diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h index acf13444fa..bcdb1a78c6 100644 --- a/firmware/export/as3514.h +++ b/firmware/export/as3514.h | |||
@@ -131,9 +131,14 @@ extern void audiohw_set_sampr_dividers(int fsel); | |||
131 | /* Headphone volume goes from -81.0 ... +6dB */ | 131 | /* Headphone volume goes from -81.0 ... +6dB */ |
132 | #define VOLUME_MIN -810 | 132 | #define VOLUME_MIN -810 |
133 | #else | 133 | #else |
134 | #ifdef SAMSUNG_YPR0 | ||
135 | /* Headphone volume goes from -40.5 ... +6dB */ | ||
136 | #define VOLUME_MIN -405 | ||
137 | #else | ||
134 | /* Headphone volume goes from -73.5 ... +6dB */ | 138 | /* Headphone volume goes from -73.5 ... +6dB */ |
135 | #define VOLUME_MIN -735 | 139 | #define VOLUME_MIN -735 |
136 | #endif | 140 | #endif |
141 | #endif | ||
137 | #define VOLUME_MAX 60 | 142 | #define VOLUME_MAX 60 |
138 | 143 | ||
139 | /*** Audio Registers ***/ | 144 | /*** Audio Registers ***/ |
diff --git a/firmware/export/ascodec.h b/firmware/export/ascodec.h index 93cd767608..658153e420 100644 --- a/firmware/export/ascodec.h +++ b/firmware/export/ascodec.h | |||
@@ -28,4 +28,8 @@ | |||
28 | #include "ascodec-target.h" | 28 | #include "ascodec-target.h" |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #ifdef SAMSUNG_YPR0 | ||
32 | #include "ascodec-target.h" | ||
33 | #endif | ||
34 | |||
31 | #endif | 35 | #endif |
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 102d107d8a..304c5aa460 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h | |||
@@ -79,7 +79,7 @@ | |||
79 | #elif defined(HAVE_DUMMY_CODEC) | 79 | #elif defined(HAVE_DUMMY_CODEC) |
80 | #include "dummy_codec.h" | 80 | #include "dummy_codec.h" |
81 | #endif | 81 | #endif |
82 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | 82 | #if (CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO|PLATFORM_PANDORA|PLATFORM_SDL)) |
83 | /* #include <SDL_audio.h> gives errors in other code areas, | 83 | /* #include <SDL_audio.h> gives errors in other code areas, |
84 | * we don't really need it here, so don't. but it should maybe be fixed */ | 84 | * we don't really need it here, so don't. but it should maybe be fixed */ |
85 | #ifndef SIMULATOR /* simulator gets values from the target .h files */ | 85 | #ifndef SIMULATOR /* simulator gets values from the target .h files */ |
diff --git a/firmware/export/config.h b/firmware/export/config.h index 039b48a759..542587fc9d 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -143,6 +143,7 @@ | |||
143 | #define HM60X_PAD 50 | 143 | #define HM60X_PAD 50 |
144 | #define HM801_PAD 51 | 144 | #define HM801_PAD 51 |
145 | #define SANSA_CONNECT_PAD 52 | 145 | #define SANSA_CONNECT_PAD 52 |
146 | #define SAMSUNG_YPR0_PAD 53 | ||
146 | 147 | ||
147 | /* CONFIG_REMOTE_KEYPAD */ | 148 | /* CONFIG_REMOTE_KEYPAD */ |
148 | #define H100_REMOTE 1 | 149 | #define H100_REMOTE 1 |
@@ -232,6 +233,7 @@ | |||
232 | #define LCD_HX8340B 44 /* as used by the HiFiMAN HM-601/HM-602/HM-801 */ | 233 | #define LCD_HX8340B 44 /* as used by the HiFiMAN HM-601/HM-602/HM-801 */ |
233 | #define LCD_CONNECT 45 /* as used by the Sandisk Sansa Connect */ | 234 | #define LCD_CONNECT 45 /* as used by the Sandisk Sansa Connect */ |
234 | #define LCD_GIGABEATS 46 | 235 | #define LCD_GIGABEATS 46 |
236 | #define LCD_YPR0 47 | ||
235 | 237 | ||
236 | /* LCD_PIXELFORMAT */ | 238 | /* LCD_PIXELFORMAT */ |
237 | #define HORIZONTAL_PACKING 1 | 239 | #define HORIZONTAL_PACKING 1 |
@@ -483,6 +485,8 @@ Lyre prototype 1 */ | |||
483 | #include "config/nokian900.h" | 485 | #include "config/nokian900.h" |
484 | #elif defined(PANDORA) | 486 | #elif defined(PANDORA) |
485 | #include "config/pandora.h" | 487 | #include "config/pandora.h" |
488 | #elif defined(SAMSUNG_YPR0) | ||
489 | #include "config/ypr0.h" | ||
486 | #else | 490 | #else |
487 | /* no known platform */ | 491 | /* no known platform */ |
488 | #endif | 492 | #endif |
@@ -580,6 +584,10 @@ Lyre prototype 1 */ | |||
580 | #define CONFIG_BACKLIGHT_FADING BACKLIGHT_NO_FADING | 584 | #define CONFIG_BACKLIGHT_FADING BACKLIGHT_NO_FADING |
581 | #endif | 585 | #endif |
582 | 586 | ||
587 | #ifndef CONFIG_I2C | ||
588 | #define CONFIG_I2C I2C_NONE | ||
589 | #endif | ||
590 | |||
583 | #ifndef CONFIG_TUNER | 591 | #ifndef CONFIG_TUNER |
584 | #define CONFIG_TUNER 0 | 592 | #define CONFIG_TUNER 0 |
585 | #endif | 593 | #endif |
@@ -600,6 +608,14 @@ Lyre prototype 1 */ | |||
600 | #define CONFIG_RTC 0 | 608 | #define CONFIG_RTC 0 |
601 | #endif | 609 | #endif |
602 | 610 | ||
611 | #ifndef BATTERY_TYPES_COUNT | ||
612 | #define BATTERY_TYPES_COUNT 0 | ||
613 | #endif | ||
614 | |||
615 | #ifndef BATTERY_CAPACITY_INC | ||
616 | #define BATTERY_CAPACITY_INC 0 | ||
617 | #endif | ||
618 | |||
603 | #ifndef CONFIG_ORIENTATION | 619 | #ifndef CONFIG_ORIENTATION |
604 | #if LCD_HEIGHT > LCD_WIDTH | 620 | #if LCD_HEIGHT > LCD_WIDTH |
605 | #define CONFIG_ORIENTATION SCREEN_PORTRAIT | 621 | #define CONFIG_ORIENTATION SCREEN_PORTRAIT |
diff --git a/firmware/export/config/ypr0.h b/firmware/export/config/ypr0.h new file mode 100644 index 0000000000..25e1906a80 --- /dev/null +++ b/firmware/export/config/ypr0.h | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * This config file is for the RockBox as application on the Samsung YP-R0 player. | ||
3 | * The target name for ifdefs is: SAMSUNG_YPR0; or CONFIG_PLATFORM & PLAFTORM_YPR0 | ||
4 | */ | ||
5 | |||
6 | #define TARGET_TREE /* this target is using the target tree system */ | ||
7 | |||
8 | /* We don't run on hardware directly */ | ||
9 | /* YP-R0 need it too of course */ | ||
10 | #define CONFIG_PLATFORM (PLATFORM_HOSTED) | ||
11 | |||
12 | /* For Rolo and boot loader */ | ||
13 | #define MODEL_NUMBER 100 | ||
14 | |||
15 | #define MODEL_NAME "Samsung YP-R0" | ||
16 | |||
17 | /* Indeed to check that */ | ||
18 | /*TODO: R0 should charge battery automatically, no software stuff to manage that. Just to know about some as3543 registers, that should be set after loading samsung's afe.ko module | ||
19 | */ | ||
20 | /*TODO: implement USB data transfer management -> see safe mode script and think a way to implemtent it in the code */ | ||
21 | #define USB_NONE | ||
22 | |||
23 | /* Hardware controlled charging with monitoring */ | ||
24 | //#define CONFIG_CHARGING CHARGING_MONITOR | ||
25 | |||
26 | /* There is only USB charging */ | ||
27 | //#define HAVE_USB_POWER | ||
28 | |||
29 | /* define this if you have a bitmap LCD display */ | ||
30 | #define HAVE_LCD_BITMAP | ||
31 | |||
32 | /* define this if you have a colour LCD */ | ||
33 | #define HAVE_LCD_COLOR | ||
34 | |||
35 | /* define this if the LCD needs to be shutdown */ | ||
36 | /* TODO: Our framebuffer must be closed... */ | ||
37 | #define HAVE_LCD_SHUTDOWN | ||
38 | |||
39 | /* define this if you want album art for this target */ | ||
40 | #define HAVE_ALBUMART | ||
41 | |||
42 | /* define this to enable bitmap scaling */ | ||
43 | #define HAVE_BMP_SCALING | ||
44 | |||
45 | /* define this to enable JPEG decoding */ | ||
46 | #define HAVE_JPEG | ||
47 | |||
48 | /* define this if you have access to the quickscreen */ | ||
49 | #define HAVE_QUICKSCREEN | ||
50 | |||
51 | /* define this if you have access to the pitchscreen */ | ||
52 | #define HAVE_PITCHSCREEN | ||
53 | |||
54 | /* define this if you would like tagcache to build on this target */ | ||
55 | #define HAVE_TAGCACHE | ||
56 | |||
57 | /* LCD dimensions | ||
58 | * | ||
59 | * overriden by configure for application builds */ | ||
60 | #ifndef LCD_WIDTH | ||
61 | #define LCD_WIDTH 240 | ||
62 | #endif | ||
63 | |||
64 | #ifndef LCD_HEIGHT | ||
65 | #define LCD_HEIGHT 320 | ||
66 | #endif | ||
67 | |||
68 | #define LCD_DEPTH 16 | ||
69 | /* Check that but should not matter */ | ||
70 | #define LCD_PIXELFORMAT 565 | ||
71 | |||
72 | /* YP-R0 has the backlight */ | ||
73 | #define HAVE_BACKLIGHT | ||
74 | |||
75 | /* Define this for LCD backlight brightness available */ | ||
76 | #define HAVE_BACKLIGHT_BRIGHTNESS | ||
77 | |||
78 | /* Main LCD backlight brightness range and defaults */ | ||
79 | /* 0 is turned off. 31 is the real maximum for the ASCODEC DCDC but samsung doesn't use any value over 15, so it safer to don't go up too much */ | ||
80 | #define MIN_BRIGHTNESS_SETTING 1 | ||
81 | #define MAX_BRIGHTNESS_SETTING 15 | ||
82 | #define DEFAULT_BRIGHTNESS_SETTING 4 | ||
83 | |||
84 | /* Which backlight fading type? */ | ||
85 | /* TODO: ASCODEC has an auto dim feature, so disabling the supply to leds should do the trick. But for now I tested SW fading only */ | ||
86 | #define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING | ||
87 | |||
88 | /* define this if you have RTC RAM available for settings */ | ||
89 | /* TODO: in theory we could use that, ascodec offers us such a ram. we have also a small device, part of the nand of 1 MB size, that Samsung uses to store region code etc and it's almost unused space */ | ||
90 | //#define HAVE_RTC_RAM | ||
91 | |||
92 | /* define this if you have a real-time clock */ | ||
93 | //#define CONFIG_RTC APPLICATION | ||
94 | #define CONFIG_RTC RTC_AS3514 | ||
95 | #define HAVE_RTC_ALARM | ||
96 | |||
97 | /* The number of bytes reserved for loadable codecs */ | ||
98 | #define CODEC_SIZE 0x80000 | ||
99 | |||
100 | /* The number of bytes reserved for loadable plugins */ | ||
101 | #define PLUGIN_BUFFER_SIZE 0x100000 | ||
102 | |||
103 | /* We can do AB-repeat -> we use User key, our hotkey */ | ||
104 | #define AB_REPEAT_ENABLE | ||
105 | #define ACTION_WPSAB_SINGLE ACTION_WPS_HOTKEY | ||
106 | |||
107 | /* Define this if you do software codec */ | ||
108 | #define CONFIG_CODEC SWCODEC | ||
109 | |||
110 | /* R0 KeyPad configuration for plugins */ | ||
111 | #define CONFIG_KEYPAD SAMSUNG_YPR0_PAD | ||
112 | /* It's better to close /dev/r0Btn at shutdown */ | ||
113 | #define BUTTON_DRIVER_CLOSE | ||
114 | |||
115 | /* The YPR0 has a as3534 codec and we use that to control the volume */ | ||
116 | #define HAVE_AS3514 | ||
117 | #define HAVE_AS3543 | ||
118 | |||
119 | #define HAVE_SW_TONE_CONTROLS | ||
120 | |||
121 | /* TODO: Make use of the si4703 tuner hardware */ | ||
122 | /* #define CONFIG_TUNER SI4700 */ | ||
123 | /* #define HAVE_TUNER_PWR_CTRL*/ | ||
124 | |||
125 | /*TODO: In R0 there is an interrupt for this (figure out ioctls)*/ | ||
126 | /* #define HAVE_HEADPHONE_DETECTION */ | ||
127 | |||
128 | /* Define current usage levels. */ | ||
129 | /* TODO: to be filled with correct values after implementing power management */ | ||
130 | #define CURRENT_NORMAL 88 /* 18 hours from a 1600 mAh battery */ | ||
131 | #define CURRENT_BACKLIGHT 30 /* TBD */ | ||
132 | #define CURRENT_RECORD 0 /* no recording yet */ | ||
133 | |||
134 | /* TODO: We need to do battery handling */ | ||
135 | //#define BATTERY_CAPACITY_DEFAULT 600 /* default battery capacity */ | ||
136 | //#define BATTERY_CAPACITY_MIN 600 /* min. capacity selectable */ | ||
137 | //#define BATTERY_CAPACITY_MAX 700 /* max. capacity selectable */ | ||
138 | //#define BATTERY_CAPACITY_INC 50 /* capacity increment */ | ||
139 | //#define BATTERY_TYPES_COUNT 1 /* only one type */ | ||
140 | |||
141 | /* TODO: We possibly can only watch linux charging */ | ||
142 | //#define CONFIG_CHARGING CHARGING_TARGET | ||
143 | //#define HAVE_RESET_BATTERY_FILTER | ||
144 | |||
145 | /* same dimensions as gigabeats */ | ||
146 | #define CONFIG_LCD LCD_YPR0 | ||
147 | |||
148 | /* Define this if a programmable hotkey is mapped */ | ||
149 | #define HAVE_HOTKEY | ||
150 | |||
151 | /* Define this if you have a software controlled poweroff */ | ||
152 | #define HAVE_SW_POWEROFF | ||
153 | |||
154 | /* Define this if you have adjustable CPU frequency | ||
155 | * NOTE: We could do that on this device, but it's probably better | ||
156 | * to let linux do it (we set ondemand governor before loading Rockbox) */ | ||
157 | /* #define HAVE_ADJUSTABLE_CPU_FREQ */ | ||
158 | /* Define this to the CPU frequency */ | ||
159 | #define CPU_FREQ 532000000 | ||
160 | /* 0.8Vcore using 200 MHz */ | ||
161 | /* #define CPUFREQ_DEFAULT 200000000 */ | ||
162 | /* This is 400 MHz -> not so powersaving-ful */ | ||
163 | /* #define CPUFREQ_NORMAL 400000000 */ | ||
164 | /* Max IMX37 Cpu Frequency */ | ||
165 | /* #define CPUFREQ_MAX CPU_FREQ */ | ||
166 | |||
167 | /* TODO: my idea is to create a folder in the cramfs [/.rockbox], mounting it by the starter script as the current working directory, so no issues of any type keeping the rockbox folder as in all other players */ | ||
168 | #define BOOTDIR "/.rockbox" | ||
diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h index 74d26f93d3..8f554c25f4 100644 --- a/firmware/export/rbpaths.h +++ b/firmware/export/rbpaths.h | |||
@@ -44,7 +44,7 @@ | |||
44 | #define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1) | 44 | #define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1) |
45 | #endif /* def __PCTOOL__ */ | 45 | #endif /* def __PCTOOL__ */ |
46 | 46 | ||
47 | #ifndef APPLICATION | 47 | #if !defined(APPLICATION) || defined(SAMSUNG_YPR0) |
48 | 48 | ||
49 | /* make sure both are the same for native builds */ | 49 | /* make sure both are the same for native builds */ |
50 | #undef ROCKBOX_LIBRARY_PATH | 50 | #undef ROCKBOX_LIBRARY_PATH |
@@ -57,6 +57,7 @@ | |||
57 | #define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists" | 57 | #define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists" |
58 | 58 | ||
59 | #define paths_init() | 59 | #define paths_init() |
60 | |||
60 | #else /* application */ | 61 | #else /* application */ |
61 | 62 | ||
62 | #define PLUGIN_DIR ROCKBOX_LIBRARY_PATH "/rockbox/rocks" | 63 | #define PLUGIN_DIR ROCKBOX_LIBRARY_PATH "/rockbox/rocks" |
@@ -80,7 +81,7 @@ extern void paths_init(void); | |||
80 | #define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos" | 81 | #define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos" |
81 | #define VIEWERS_DIR PLUGIN_DIR "/viewers" | 82 | #define VIEWERS_DIR PLUGIN_DIR "/viewers" |
82 | 83 | ||
83 | #ifdef APPLICATION | 84 | #if defined(APPLICATION) && !defined(SAMSUNG_YPR0) |
84 | #define PLUGIN_DATA_DIR "/.rockbox/rocks.data" | 85 | #define PLUGIN_DATA_DIR "/.rockbox/rocks.data" |
85 | #define PLUGIN_GAMES_DATA_DIR PLUGIN_DATA_DIR | 86 | #define PLUGIN_GAMES_DATA_DIR PLUGIN_DATA_DIR |
86 | #define PLUGIN_APPS_DATA_DIR PLUGIN_DATA_DIR | 87 | #define PLUGIN_APPS_DATA_DIR PLUGIN_DATA_DIR |
diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h index d9a29fbada..e0fea13c14 100644 --- a/firmware/include/dir_uncached.h +++ b/firmware/include/dir_uncached.h | |||
@@ -74,7 +74,7 @@ typedef struct { | |||
74 | 74 | ||
75 | 75 | ||
76 | #if defined(APPLICATION) | 76 | #if defined(APPLICATION) |
77 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) | 77 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(SAMSUNG_YPR0) |
78 | #include "dir-target.h" | 78 | #include "dir-target.h" |
79 | #endif | 79 | #endif |
80 | # undef opendir_uncached | 80 | # undef opendir_uncached |
diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index 25c41c2586..3194f76e04 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c | |||
@@ -70,6 +70,11 @@ static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATT | |||
70 | #define MAX_IDLE_FRAMES (NATIVE_FREQUENCY*3 / MIX_FRAME_SAMPLES) | 70 | #define MAX_IDLE_FRAMES (NATIVE_FREQUENCY*3 / MIX_FRAME_SAMPLES) |
71 | static unsigned int idle_counter = 0; | 71 | static unsigned int idle_counter = 0; |
72 | 72 | ||
73 | /* Cheapo buffer align macro to align to the 16-16 PCM size */ | ||
74 | #define ALIGN_CHANNEL(start, size) \ | ||
75 | ({ start = (void *)(((uintptr_t)start + 3) & ~3); \ | ||
76 | size &= ~3; }) | ||
77 | |||
73 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | 78 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) |
74 | 79 | ||
75 | /* Include any implemented CPU-optimized mixdown routines */ | 80 | /* Include any implemented CPU-optimized mixdown routines */ |
diff --git a/firmware/sound.c b/firmware/sound.c index c97ccc243f..99db7896ab 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -235,7 +235,8 @@ static void set_prescaled_volume(void) | |||
235 | dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0); | 235 | dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0); |
236 | #endif | 236 | #endif |
237 | 237 | ||
238 | #ifndef HAVE_SDL_AUDIO | 238 | /* ypr0 with sdl has separate volume controls */ |
239 | #if !defined(HAVE_SDL_AUDIO) || defined(SAMSUNG_YPR0) | ||
239 | #if CONFIG_CODEC == MAS3507D | 240 | #if CONFIG_CODEC == MAS3507D |
240 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | 241 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
241 | #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \ | 242 | #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \ |
@@ -670,7 +671,7 @@ void sound_set(int setting, int value) | |||
670 | && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \ | 671 | && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \ |
671 | && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \ | 672 | && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \ |
672 | && !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \ | 673 | && !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \ |
673 | && !defined(HAVE_AK4537)) || (CONFIG_PLATFORM & PLATFORM_HOSTED) | 674 | && !defined(HAVE_AK4537)) || defined(SIMULATOR) |
674 | int sound_val2phys(int setting, int value) | 675 | int sound_val2phys(int setting, int value) |
675 | { | 676 | { |
676 | #if CONFIG_CODEC == MAS3587F | 677 | #if CONFIG_CODEC == MAS3587F |
diff --git a/firmware/system.c b/firmware/system.c index 7e269ee119..111a94f80e 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "string.h" | 26 | #include "string.h" |
27 | #include "file.h" | 27 | #include "file.h" |
28 | 28 | ||
29 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | 29 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
30 | long cpu_frequency SHAREDBSS_ATTR = CPU_FREQ; | 30 | long cpu_frequency SHAREDBSS_ATTR = CPU_FREQ; |
31 | #endif | 31 | #endif |
32 | 32 | ||
diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c new file mode 100644 index 0000000000..928187993e --- /dev/null +++ b/firmware/target/hosted/pcm-alsa.c | |||
@@ -0,0 +1,518 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | |||
23 | /* | ||
24 | * Based, but heavily modified, on the example given at | ||
25 | * http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html | ||
26 | * | ||
27 | * This driver uses the so-called unsafe async callback method and hardcoded device | ||
28 | * names. It fails when the audio device is busy by other apps. | ||
29 | * | ||
30 | * TODO: Rewrite this to do it properly with multithreading | ||
31 | * | ||
32 | * Alternatively, a version using polling in a tick task is provided. While | ||
33 | * supposedly safer, it appears to use more CPU (however I didn't measure it | ||
34 | * accurately, only looked at htop). At least, in this mode the "default" | ||
35 | * device works which doesnt break with other apps running. | ||
36 | * device works which doesnt break with other apps running. | ||
37 | */ | ||
38 | |||
39 | |||
40 | #include "autoconf.h" | ||
41 | |||
42 | #include <stdlib.h> | ||
43 | #include <stdbool.h> | ||
44 | #include <alsa/asoundlib.h> | ||
45 | #include "system.h" | ||
46 | #include "debug.h" | ||
47 | #include "kernel.h" | ||
48 | |||
49 | #include "pcm.h" | ||
50 | #include "pcm-internal.h" | ||
51 | #include "pcm_mixer.h" | ||
52 | #include "pcm_sampr.h" | ||
53 | |||
54 | #include <pthread.h> | ||
55 | #include <signal.h> | ||
56 | |||
57 | #define USE_ASYNC_CALLBACK | ||
58 | /* plughw:0,0 works with both, however "default" is recommended. | ||
59 | * default doesnt seem to work with async callback but doesn't break | ||
60 | * with multple applications running */ | ||
61 | static char device[] = "plughw:0,0"; /* playback device */ | ||
62 | static const snd_pcm_access_t access_ = SND_PCM_ACCESS_RW_INTERLEAVED; /* access mode */ | ||
63 | static const snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */ | ||
64 | static const int channels = 2; /* count of channels */ | ||
65 | static unsigned int rate = 44100; /* stream rate */ | ||
66 | |||
67 | static snd_pcm_t *handle; | ||
68 | static snd_pcm_sframes_t buffer_size = MIX_FRAME_SAMPLES * 32; /* ~16k */ | ||
69 | static snd_pcm_sframes_t period_size = MIX_FRAME_SAMPLES * 4; /* ~4k */ | ||
70 | static short *frames; | ||
71 | |||
72 | static const char *pcm_data = 0; | ||
73 | static size_t pcm_size = 0; | ||
74 | |||
75 | #ifdef USE_ASYNC_CALLBACK | ||
76 | static snd_async_handler_t *ahandler; | ||
77 | static pthread_mutex_t pcm_mtx; | ||
78 | #else | ||
79 | static int recursion; | ||
80 | #endif | ||
81 | |||
82 | static int set_hwparams(snd_pcm_t *handle, unsigned sample_rate) | ||
83 | { | ||
84 | unsigned int rrate; | ||
85 | int err; | ||
86 | snd_pcm_hw_params_t *params; | ||
87 | snd_pcm_hw_params_alloca(¶ms); | ||
88 | |||
89 | |||
90 | /* choose all parameters */ | ||
91 | err = snd_pcm_hw_params_any(handle, params); | ||
92 | if (err < 0) | ||
93 | { | ||
94 | printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); | ||
95 | return err; | ||
96 | } | ||
97 | /* set the interleaved read/write format */ | ||
98 | err = snd_pcm_hw_params_set_access(handle, params, access_); | ||
99 | if (err < 0) | ||
100 | { | ||
101 | printf("Access type not available for playback: %s\n", snd_strerror(err)); | ||
102 | return err; | ||
103 | } | ||
104 | /* set the sample format */ | ||
105 | err = snd_pcm_hw_params_set_format(handle, params, format); | ||
106 | if (err < 0) | ||
107 | { | ||
108 | printf("Sample format not available for playback: %s\n", snd_strerror(err)); | ||
109 | return err; | ||
110 | } | ||
111 | /* set the count of channels */ | ||
112 | err = snd_pcm_hw_params_set_channels(handle, params, channels); | ||
113 | if (err < 0) | ||
114 | { | ||
115 | printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err)); | ||
116 | return err; | ||
117 | } | ||
118 | /* set the stream rate */ | ||
119 | rrate = sample_rate; | ||
120 | err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0); | ||
121 | if (err < 0) | ||
122 | { | ||
123 | printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err)); | ||
124 | return err; | ||
125 | } | ||
126 | if (rrate != sample_rate) | ||
127 | { | ||
128 | printf("Rate doesn't match (requested %iHz, get %iHz)\n", sample_rate, err); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | /* set the buffer size */ | ||
133 | err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size); | ||
134 | if (err < 0) | ||
135 | { | ||
136 | printf("Unable to set buffer size %i for playback: %s\n", buffer_size, snd_strerror(err)); | ||
137 | return err; | ||
138 | } | ||
139 | |||
140 | /* set the period size */ | ||
141 | err = snd_pcm_hw_params_set_period_size_near (handle, params, &period_size, NULL); | ||
142 | if (err < 0) | ||
143 | { | ||
144 | printf("Unable to set period size %i for playback: %s\n", period_size, snd_strerror(err)); | ||
145 | return err; | ||
146 | } | ||
147 | if (!frames) | ||
148 | frames = malloc(period_size * channels * sizeof(short)); | ||
149 | |||
150 | /* write the parameters to device */ | ||
151 | err = snd_pcm_hw_params(handle, params); | ||
152 | if (err < 0) | ||
153 | { | ||
154 | printf("Unable to set hw params for playback: %s\n", snd_strerror(err)); | ||
155 | return err; | ||
156 | } | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | /* Set sw params: playback start threshold and low buffer watermark */ | ||
161 | static int set_swparams(snd_pcm_t *handle) | ||
162 | { | ||
163 | int err; | ||
164 | |||
165 | snd_pcm_sw_params_t *swparams; | ||
166 | snd_pcm_sw_params_alloca(&swparams); | ||
167 | |||
168 | /* get the current swparams */ | ||
169 | err = snd_pcm_sw_params_current(handle, swparams); | ||
170 | if (err < 0) | ||
171 | { | ||
172 | printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err)); | ||
173 | return err; | ||
174 | } | ||
175 | /* start the transfer when the buffer is haalmost full */ | ||
176 | err = snd_pcm_sw_params_set_start_threshold(handle, swparams, buffer_size / 2); | ||
177 | if (err < 0) | ||
178 | { | ||
179 | printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err)); | ||
180 | return err; | ||
181 | } | ||
182 | /* allow the transfer when at least period_size samples can be processed */ | ||
183 | err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size); | ||
184 | if (err < 0) | ||
185 | { | ||
186 | printf("Unable to set avail min for playback: %s\n", snd_strerror(err)); | ||
187 | return err; | ||
188 | } | ||
189 | /* write the parameters to the playback device */ | ||
190 | err = snd_pcm_sw_params(handle, swparams); | ||
191 | if (err < 0) | ||
192 | { | ||
193 | printf("Unable to set sw params for playback: %s\n", snd_strerror(err)); | ||
194 | return err; | ||
195 | } | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | /* copy pcm samples to a spare buffer, suitable for snd_pcm_writei() */ | ||
200 | static bool fill_frames(void) | ||
201 | { | ||
202 | ssize_t copy_n, frames_left = period_size; | ||
203 | bool new_buffer = false; | ||
204 | |||
205 | while (frames_left > 0) | ||
206 | { | ||
207 | if (!pcm_size) | ||
208 | { | ||
209 | new_buffer = true; | ||
210 | pcm_play_get_more_callback((void **)&pcm_data, &pcm_size); | ||
211 | if (!pcm_size || !pcm_data) | ||
212 | return false; | ||
213 | } | ||
214 | copy_n = MIN((ssize_t)pcm_size, frames_left*4); | ||
215 | memcpy(&frames[2*(period_size-frames_left)], pcm_data, copy_n); | ||
216 | |||
217 | pcm_data += copy_n; | ||
218 | pcm_size -= copy_n; | ||
219 | frames_left -= copy_n/4; | ||
220 | |||
221 | if (new_buffer) | ||
222 | { | ||
223 | new_buffer = false; | ||
224 | pcm_play_dma_started_callback(); | ||
225 | } | ||
226 | } | ||
227 | return true; | ||
228 | } | ||
229 | |||
230 | #ifdef USE_ASYNC_CALLBACK | ||
231 | static void async_callback(snd_async_handler_t *ahandler) | ||
232 | { | ||
233 | snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); | ||
234 | |||
235 | if (pthread_mutex_trylock(&pcm_mtx) != 0) | ||
236 | return; | ||
237 | #else | ||
238 | static void pcm_tick(void) | ||
239 | { | ||
240 | if (snd_pcm_state(handle) != SND_PCM_STATE_RUNNING) | ||
241 | return; | ||
242 | #endif | ||
243 | |||
244 | while (snd_pcm_avail_update(handle) >= period_size) | ||
245 | { | ||
246 | if (fill_frames()) | ||
247 | { | ||
248 | int err = snd_pcm_writei(handle, frames, period_size); | ||
249 | if (err < 0 && err != period_size && err != -EAGAIN) | ||
250 | { | ||
251 | printf("Write error: written %i expected %li\n", err, period_size); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | else | ||
256 | { | ||
257 | DEBUGF("%s: No Data.\n", __func__); | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | #ifdef USE_ASYNC_CALLBACK | ||
262 | pthread_mutex_unlock(&pcm_mtx); | ||
263 | #endif | ||
264 | } | ||
265 | |||
266 | static int async_rw(snd_pcm_t *handle) | ||
267 | { | ||
268 | int err; | ||
269 | snd_pcm_sframes_t sample_size; | ||
270 | short *samples; | ||
271 | |||
272 | #ifdef USE_ASYNC_CALLBACK | ||
273 | err = snd_async_add_pcm_handler(&ahandler, handle, async_callback, NULL); | ||
274 | if (err < 0) | ||
275 | { | ||
276 | DEBUGF("Unable to register async handler: %s\n", snd_strerror(err)); | ||
277 | return err; | ||
278 | } | ||
279 | #endif | ||
280 | |||
281 | /* fill buffer with silence to initiate playback without noisy click */ | ||
282 | sample_size = buffer_size; | ||
283 | samples = malloc(sample_size * channels * sizeof(short)); | ||
284 | |||
285 | snd_pcm_format_set_silence(format, samples, sample_size); | ||
286 | err = snd_pcm_writei(handle, samples, sample_size); | ||
287 | free(samples); | ||
288 | |||
289 | if (err < 0) | ||
290 | { | ||
291 | DEBUGF("Initial write error: %s\n", snd_strerror(err)); | ||
292 | return err; | ||
293 | } | ||
294 | if (err != (ssize_t)sample_size) | ||
295 | { | ||
296 | DEBUGF("Initial write error: written %i expected %li\n", err, sample_size); | ||
297 | return err; | ||
298 | } | ||
299 | if (snd_pcm_state(handle) == SND_PCM_STATE_PREPARED) | ||
300 | { | ||
301 | err = snd_pcm_start(handle); | ||
302 | if (err < 0) | ||
303 | { | ||
304 | DEBUGF("Start error: %s\n", snd_strerror(err)); | ||
305 | return err; | ||
306 | } | ||
307 | } | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | |||
312 | void cleanup(void) | ||
313 | { | ||
314 | free(frames); | ||
315 | frames = NULL; | ||
316 | snd_pcm_close(handle); | ||
317 | } | ||
318 | |||
319 | |||
320 | void pcm_play_dma_init(void) | ||
321 | { | ||
322 | int err; | ||
323 | |||
324 | |||
325 | if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) | ||
326 | { | ||
327 | printf("%s(): Cannot open device %s: %s\n", __func__, device, snd_strerror(err)); | ||
328 | exit(EXIT_FAILURE); | ||
329 | return; | ||
330 | } | ||
331 | |||
332 | if ((err = snd_pcm_nonblock(handle, 1))) | ||
333 | printf("Could not set non-block mode: %s\n", snd_strerror(err)); | ||
334 | |||
335 | if ((err = set_hwparams(handle, rate)) < 0) | ||
336 | { | ||
337 | printf("Setting of hwparams failed: %s\n", snd_strerror(err)); | ||
338 | exit(EXIT_FAILURE); | ||
339 | } | ||
340 | if ((err = set_swparams(handle)) < 0) | ||
341 | { | ||
342 | printf("Setting of swparams failed: %s\n", snd_strerror(err)); | ||
343 | exit(EXIT_FAILURE); | ||
344 | } | ||
345 | |||
346 | #ifdef USE_ASYNC_CALLBACK | ||
347 | pthread_mutexattr_t attr; | ||
348 | pthread_mutexattr_init(&attr); | ||
349 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||
350 | pthread_mutex_init(&pcm_mtx, &attr); | ||
351 | #else | ||
352 | tick_add_task(pcm_tick); | ||
353 | #endif | ||
354 | |||
355 | |||
356 | atexit(cleanup); | ||
357 | return; | ||
358 | } | ||
359 | |||
360 | |||
361 | void pcm_play_lock(void) | ||
362 | { | ||
363 | #ifdef USE_ASYNC_CALLBACK | ||
364 | pthread_mutex_lock(&pcm_mtx); | ||
365 | #else | ||
366 | if (recursion++ == 0) | ||
367 | tick_remove_task(pcm_tick); | ||
368 | #endif | ||
369 | } | ||
370 | |||
371 | void pcm_play_unlock(void) | ||
372 | { | ||
373 | #ifdef USE_ASYNC_CALLBACK | ||
374 | pthread_mutex_unlock(&pcm_mtx); | ||
375 | #else | ||
376 | if (--recursion == 0) | ||
377 | tick_add_task(pcm_tick); | ||
378 | #endif | ||
379 | } | ||
380 | |||
381 | static void pcm_dma_apply_settings_nolock(void) | ||
382 | { | ||
383 | snd_pcm_drop(handle); | ||
384 | set_hwparams(handle, pcm_sampr); | ||
385 | } | ||
386 | |||
387 | void pcm_dma_apply_settings(void) | ||
388 | { | ||
389 | pcm_play_lock(); | ||
390 | pcm_dma_apply_settings_nolock(); | ||
391 | pcm_play_unlock(); | ||
392 | } | ||
393 | |||
394 | |||
395 | void pcm_play_dma_pause(bool pause) | ||
396 | { | ||
397 | snd_pcm_pause(handle, pause); | ||
398 | } | ||
399 | |||
400 | |||
401 | void pcm_play_dma_stop(void) | ||
402 | { | ||
403 | snd_pcm_drain(handle); | ||
404 | } | ||
405 | |||
406 | void pcm_play_dma_start(const void *addr, size_t size) | ||
407 | { | ||
408 | pcm_dma_apply_settings_nolock(); | ||
409 | |||
410 | pcm_data = addr; | ||
411 | pcm_size = size; | ||
412 | |||
413 | while (1) | ||
414 | { | ||
415 | snd_pcm_state_t state = snd_pcm_state(handle); | ||
416 | switch (state) | ||
417 | { | ||
418 | case SND_PCM_STATE_RUNNING: | ||
419 | return; | ||
420 | case SND_PCM_STATE_XRUN: | ||
421 | { | ||
422 | DEBUGF("Trying to recover from error\n"); | ||
423 | int err = snd_pcm_recover(handle, -EPIPE, 0); | ||
424 | if (err < 0) | ||
425 | DEBUGF("Recovery failed: %s\n", snd_strerror(err)); | ||
426 | continue; | ||
427 | } | ||
428 | case SND_PCM_STATE_SETUP: | ||
429 | { | ||
430 | int err = snd_pcm_prepare(handle); | ||
431 | if (err < 0) | ||
432 | printf("Prepare error: %s\n", snd_strerror(err)); | ||
433 | /* fall through */ | ||
434 | } | ||
435 | case SND_PCM_STATE_PREPARED: | ||
436 | { /* prepared state, we need to fill the buffer with silence before | ||
437 | * starting */ | ||
438 | int err = async_rw(handle); | ||
439 | if (err < 0) | ||
440 | printf("Start error: %s\n", snd_strerror(err)); | ||
441 | return; | ||
442 | } | ||
443 | case SND_PCM_STATE_PAUSED: | ||
444 | { /* paused, simply resume */ | ||
445 | pcm_play_dma_pause(0); | ||
446 | return; | ||
447 | } | ||
448 | case SND_PCM_STATE_DRAINING: | ||
449 | /* run until drained */ | ||
450 | continue; | ||
451 | default: | ||
452 | DEBUGF("Unhandled state: %s\n", snd_pcm_state_name(state)); | ||
453 | return; | ||
454 | } | ||
455 | } | ||
456 | } | ||
457 | |||
458 | size_t pcm_get_bytes_waiting(void) | ||
459 | { | ||
460 | return pcm_size; | ||
461 | } | ||
462 | |||
463 | const void * pcm_play_dma_get_peak_buffer(int *count) | ||
464 | { | ||
465 | uintptr_t addr = (uintptr_t)pcm_data; | ||
466 | *count = pcm_size / 4; | ||
467 | return (void *)((addr + 3) & ~3); | ||
468 | } | ||
469 | |||
470 | void pcm_play_dma_postinit(void) | ||
471 | { | ||
472 | } | ||
473 | |||
474 | |||
475 | void pcm_set_mixer_volume(int volume) | ||
476 | { | ||
477 | (void)volume; | ||
478 | } | ||
479 | #ifdef HAVE_RECORDING | ||
480 | void pcm_rec_lock(void) | ||
481 | { | ||
482 | } | ||
483 | |||
484 | void pcm_rec_unlock(void) | ||
485 | { | ||
486 | } | ||
487 | |||
488 | void pcm_rec_dma_init(void) | ||
489 | { | ||
490 | } | ||
491 | |||
492 | void pcm_rec_dma_close(void) | ||
493 | { | ||
494 | } | ||
495 | |||
496 | void pcm_rec_dma_start(void *start, size_t size) | ||
497 | { | ||
498 | (void)start; | ||
499 | (void)size; | ||
500 | } | ||
501 | |||
502 | void pcm_rec_dma_stop(void) | ||
503 | { | ||
504 | } | ||
505 | |||
506 | const void * pcm_rec_dma_get_peak_buffer(void) | ||
507 | { | ||
508 | return NULL; | ||
509 | } | ||
510 | |||
511 | void audiohw_set_recvol(int left, int right, int type) | ||
512 | { | ||
513 | (void)left; | ||
514 | (void)right; | ||
515 | (void)type; | ||
516 | } | ||
517 | |||
518 | #endif /* HAVE_RECORDING */ | ||
diff --git a/firmware/target/hosted/ypr0/adc-target.h b/firmware/target/hosted/ypr0/adc-target.h new file mode 100644 index 0000000000..bdbc4cfabd --- /dev/null +++ b/firmware/target/hosted/ypr0/adc-target.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: adc-target.h 29516 2011-03-05 15:31:52Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Lorenzo Miori | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __ADC_TARGET_H__ | ||
23 | #define __ADC_TARGET_H__ | ||
24 | |||
25 | #endif /* __ADC_TARGET_H__ */ | ||
diff --git a/firmware/target/hosted/ypr0/ascodec-target.h b/firmware/target/hosted/ypr0/ascodec-target.h new file mode 100644 index 0000000000..f4ecf20a1b --- /dev/null +++ b/firmware/target/hosted/ypr0/ascodec-target.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: ascodec-target.h 26116 2010-05-17 20:53:25Z funman $ | ||
9 | * | ||
10 | * Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0 | ||
11 | * | ||
12 | * Copyright (c) 2011 Lorenzo Miori | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #ifndef _ASCODEC_TARGET_H | ||
25 | #define _ASCODEC_TARGET_H | ||
26 | |||
27 | #include "as3514.h" | ||
28 | #include "kernel.h" | ||
29 | #include "adc.h" | ||
30 | #include "ascodec.h" | ||
31 | |||
32 | /* ioctl parameter struct */ | ||
33 | |||
34 | struct codec_req_struct { | ||
35 | /* This works for every kind of afe.ko module requests */ | ||
36 | unsigned char reg; /* Main register address */ | ||
37 | unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/ | ||
38 | unsigned char value; /* To be read if reading a register; to be set if writing to a register */ | ||
39 | }; | ||
40 | |||
41 | int ascodec_init(void); | ||
42 | void ascodec_close(void); | ||
43 | int ascodec_write(unsigned int reg, unsigned int value); | ||
44 | int ascodec_read(unsigned int reg); | ||
45 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value); | ||
46 | int ascodec_read_pmu(unsigned int index, unsigned int subreg); | ||
47 | void ascodec_set(unsigned int reg, unsigned int bits); | ||
48 | void ascodec_clear(unsigned int reg, unsigned int bits); | ||
49 | void ascodec_write_masked(unsigned int reg, unsigned int bits, unsigned int mask); | ||
50 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data); | ||
51 | unsigned short adc_read(int channel); | ||
52 | void ascodec_lock(void); | ||
53 | void ascodec_unlock(void); | ||
54 | |||
55 | static inline bool ascodec_chg_status(void) | ||
56 | { | ||
57 | return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS; | ||
58 | } | ||
59 | |||
60 | static inline bool ascodec_endofch(void) | ||
61 | { | ||
62 | return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH; | ||
63 | } | ||
64 | |||
65 | static inline void ascodec_monitor_endofch(void) | ||
66 | { | ||
67 | ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH); | ||
68 | } | ||
69 | |||
70 | static inline void ascodec_wait_adc_finished(void) | ||
71 | { | ||
72 | /* | ||
73 | * FIXME: not implemented | ||
74 | * | ||
75 | * If irqs are not available on the target platform, | ||
76 | * this should be most likely implemented by polling | ||
77 | * AS3514_IRQ_ENRD2 in the same way powermgmt-ascodec.c | ||
78 | * is polling IRQ_ENDOFCH. | ||
79 | */ | ||
80 | } | ||
81 | |||
82 | static inline void ascodec_write_charger(int value) | ||
83 | { | ||
84 | ascodec_write_pmu(AS3543_CHARGER, 1, value); | ||
85 | } | ||
86 | |||
87 | static inline int ascodec_read_charger(void) | ||
88 | { | ||
89 | return ascodec_read_pmu(AS3543_CHARGER, 1); | ||
90 | } | ||
91 | |||
92 | #endif /* !_ASCODEC_TARGET_H */ | ||
diff --git a/firmware/target/hosted/ypr0/ascodec-ypr0.c b/firmware/target/hosted/ypr0/ascodec-ypr0.c new file mode 100644 index 0000000000..a4e92e6f6b --- /dev/null +++ b/firmware/target/hosted/ypr0/ascodec-ypr0.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: ascodec-target.h 26116 2010-05-17 20:53:25Z funman $ | ||
9 | * | ||
10 | * Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0 | ||
11 | * | ||
12 | * Copyright (c) 2011 Lorenzo Miori | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #include "fcntl.h" | ||
25 | #include "unistd.h" | ||
26 | #include "stdio.h" | ||
27 | #include "string.h" | ||
28 | #include "sys/ioctl.h" | ||
29 | #include "stdlib.h" | ||
30 | |||
31 | #include "ascodec-target.h" | ||
32 | |||
33 | int afe_dev = -1; | ||
34 | |||
35 | /* Write to a normal register */ | ||
36 | #define IOCTL_REG_WRITE 0x40034101 | ||
37 | /* Write to a PMU register */ | ||
38 | #define IOCTL_SUBREG_WRITE 0x40034103 | ||
39 | /* Read from a normal register */ | ||
40 | #define IOCTL_REG_READ 0x80034102 | ||
41 | /* Read from a PMU register */ | ||
42 | #define IOCTL_SUBREG_READ 0x80034103 | ||
43 | |||
44 | static struct mutex as_mtx; | ||
45 | |||
46 | int ascodec_init(void) { | ||
47 | |||
48 | afe_dev = open("/dev/afe", O_RDWR); | ||
49 | |||
50 | mutex_init(&as_mtx); | ||
51 | |||
52 | return afe_dev; | ||
53 | |||
54 | } | ||
55 | |||
56 | void ascodec_close(void) { | ||
57 | |||
58 | if (afe_dev >= 0) { | ||
59 | close(afe_dev); | ||
60 | } | ||
61 | |||
62 | } | ||
63 | |||
64 | /* Read functions returns -1 if fail, otherwise the register's value if success */ | ||
65 | /* Write functions return >= 0 if success, otherwise -1 if fail */ | ||
66 | |||
67 | int ascodec_write(unsigned int reg, unsigned int value) | ||
68 | { | ||
69 | struct codec_req_struct y; | ||
70 | struct codec_req_struct *p; | ||
71 | p = &y; | ||
72 | p->reg = reg; | ||
73 | p->value = value; | ||
74 | return ioctl(afe_dev, IOCTL_REG_WRITE, p); | ||
75 | } | ||
76 | |||
77 | int ascodec_read(unsigned int reg) | ||
78 | { | ||
79 | int retval = -1; | ||
80 | struct codec_req_struct y; | ||
81 | struct codec_req_struct *p; | ||
82 | p = &y; | ||
83 | p->reg = reg; | ||
84 | retval = ioctl(afe_dev, IOCTL_REG_READ, p); | ||
85 | if (retval >= 0) | ||
86 | return p->value; | ||
87 | else | ||
88 | return retval; | ||
89 | } | ||
90 | |||
91 | void ascodec_write_pmu(unsigned int index, unsigned int subreg, | ||
92 | unsigned int value) | ||
93 | { | ||
94 | struct codec_req_struct y; | ||
95 | struct codec_req_struct *p; | ||
96 | p = &y; | ||
97 | p->reg = index; | ||
98 | p->subreg = subreg; | ||
99 | p->value = value; | ||
100 | ioctl(afe_dev, IOCTL_SUBREG_WRITE, p); | ||
101 | } | ||
102 | |||
103 | int ascodec_read_pmu(unsigned int index, unsigned int subreg) | ||
104 | { | ||
105 | int retval = -1; | ||
106 | struct codec_req_struct y; | ||
107 | struct codec_req_struct *p; | ||
108 | p = &y; | ||
109 | p->reg = index; | ||
110 | p->subreg = subreg; | ||
111 | retval = ioctl(afe_dev, IOCTL_SUBREG_READ, p); | ||
112 | if (retval >= 0) | ||
113 | return p->value; | ||
114 | else | ||
115 | return retval; | ||
116 | } | ||
117 | |||
118 | /* Helpers to set/clear bits */ | ||
119 | void ascodec_set(unsigned int reg, unsigned int bits) | ||
120 | { | ||
121 | ascodec_write(reg, ascodec_read(reg) | bits); | ||
122 | } | ||
123 | |||
124 | void ascodec_clear(unsigned int reg, unsigned int bits) | ||
125 | { | ||
126 | ascodec_write(reg, ascodec_read(reg) & ~bits); | ||
127 | } | ||
128 | |||
129 | void ascodec_write_masked(unsigned int reg, unsigned int bits, | ||
130 | unsigned int mask) | ||
131 | { | ||
132 | ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask)); | ||
133 | } | ||
134 | |||
135 | /*FIXME: doesn't work */ | ||
136 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) | ||
137 | { | ||
138 | unsigned int i; | ||
139 | |||
140 | for (i=index; i<len; i++) { | ||
141 | data[i] = ascodec_read(i); | ||
142 | printf("Register %i: value=%i\n",index,data[i]); | ||
143 | } | ||
144 | |||
145 | printf("TOTAL: %i\n", i); | ||
146 | |||
147 | return i; | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * NOTE: | ||
152 | * After the conversion to interrupts, ascodec_(lock|unlock) are only used by | ||
153 | * adc-as3514.c to protect against other threads corrupting the result by using | ||
154 | * the ADC at the same time. | ||
155 | * | ||
156 | * Concurrent ascodec_(async_)?(read|write) calls are instead protected | ||
157 | * by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically safe | ||
158 | */ | ||
159 | |||
160 | void ascodec_lock(void) | ||
161 | { | ||
162 | mutex_lock(&as_mtx); | ||
163 | } | ||
164 | |||
165 | void ascodec_unlock(void) | ||
166 | { | ||
167 | mutex_unlock(&as_mtx); | ||
168 | } | ||
169 | |||
170 | /* Read 10-bit channel data */ | ||
171 | unsigned short adc_read(int channel) | ||
172 | { | ||
173 | unsigned short data = 0; | ||
174 | |||
175 | if ((unsigned)channel >= NUM_ADC_CHANNELS) | ||
176 | return 0; | ||
177 | |||
178 | ascodec_lock(); | ||
179 | |||
180 | /* Select channel */ | ||
181 | ascodec_write(AS3514_ADC_0, (channel << 4)); | ||
182 | unsigned char buf[2]; | ||
183 | |||
184 | /* | ||
185 | * The AS3514 ADC will trigger an interrupt when the conversion | ||
186 | * is finished, if the corresponding enable bit in IRQ_ENRD2 | ||
187 | * is set. | ||
188 | * Previously the code did not wait and this apparently did | ||
189 | * not pose any problems, but this should be more correct. | ||
190 | * Without the wait the data read back may be completely or | ||
191 | * partially (first one of the two bytes) stale. | ||
192 | */ | ||
193 | /*FIXME: not implemented*/ | ||
194 | ascodec_wait_adc_finished(); | ||
195 | |||
196 | /* Read data */ | ||
197 | ascodec_readbytes(AS3514_ADC_0, 2, buf); | ||
198 | data = (((buf[0] & 0x3) << 8) | buf[1]); | ||
199 | |||
200 | ascodec_unlock(); | ||
201 | return data; | ||
202 | } | ||
203 | |||
204 | void adc_init(void) | ||
205 | { | ||
206 | } | ||
diff --git a/firmware/target/hosted/ypr0/backlight-target.h b/firmware/target/hosted/ypr0/backlight-target.h new file mode 100644 index 0000000000..561e159e8c --- /dev/null +++ b/firmware/target/hosted/ypr0/backlight-target.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: backlight-target.h 19322 2008-12-04 04:16:53Z jethead71 $ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Lorenzo Miori | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef BACKLIGHT_TARGET_H | ||
22 | #define BACKLIGHT_TARGET_H | ||
23 | |||
24 | bool _backlight_init(void); | ||
25 | void _backlight_on(void); | ||
26 | void _backlight_off(void); | ||
27 | void _backlight_set_brightness(int brightness); | ||
28 | |||
29 | #endif /* BACKLIGHT_TARGET_H */ | ||
diff --git a/firmware/target/hosted/ypr0/backlight-ypr0.c b/firmware/target/hosted/ypr0/backlight-ypr0.c new file mode 100644 index 0000000000..930b56be2e --- /dev/null +++ b/firmware/target/hosted/ypr0/backlight-ypr0.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: backlight-gigabeat-s.c 25800 2010-05-04 10:07:53Z jethead71 $ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Lorenzo Miori | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "system.h" | ||
23 | #include "backlight.h" | ||
24 | #include "backlight-target.h" | ||
25 | #include "lcd.h" | ||
26 | #include "as3514.h" | ||
27 | #include "ascodec-target.h" | ||
28 | #include <fcntl.h> | ||
29 | #include "unistd.h" | ||
30 | |||
31 | static bool backlight_on_status = true; /* Is on or off? */ | ||
32 | |||
33 | /*TODO: see if LCD sleep could be implemented in a better way -> ie using a rockbox feature */ | ||
34 | /* Turn off LCD power supply */ | ||
35 | static void _backlight_lcd_sleep(void) | ||
36 | { | ||
37 | int fp = open("/sys/class/graphics/fb0/blank", O_RDWR); | ||
38 | write(fp, "1", 1); | ||
39 | close(fp); | ||
40 | } | ||
41 | /* Turn on LCD screen */ | ||
42 | static void _backlight_lcd_power(void) | ||
43 | { | ||
44 | int fp = open("/sys/class/graphics/fb0/blank", O_RDWR); | ||
45 | write(fp, "0", 1); | ||
46 | close(fp); | ||
47 | } | ||
48 | |||
49 | bool _backlight_init(void) | ||
50 | { | ||
51 | /* We have nothing to do */ | ||
52 | return true; | ||
53 | } | ||
54 | |||
55 | void _backlight_on(void) | ||
56 | { | ||
57 | if (!backlight_on_status) | ||
58 | { | ||
59 | /* Turn on lcd power before backlight */ | ||
60 | _backlight_lcd_power(); | ||
61 | /* Original app sets this to 0xb1 when backlight is on... */ | ||
62 | ascodec_write_pmu(AS3543_BACKLIGHT, 0x1, 0xb1); | ||
63 | } | ||
64 | |||
65 | backlight_on_status = true; | ||
66 | |||
67 | } | ||
68 | |||
69 | void _backlight_off(void) | ||
70 | { | ||
71 | if (backlight_on_status) { | ||
72 | /* Disabling the DCDC15 completely, keeps brightness register value */ | ||
73 | ascodec_write_pmu(AS3543_BACKLIGHT, 0x1, 0x00); | ||
74 | /* Turn off lcd power then */ | ||
75 | _backlight_lcd_sleep(); | ||
76 | } | ||
77 | |||
78 | backlight_on_status = false; | ||
79 | } | ||
80 | |||
81 | void _backlight_set_brightness(int brightness) | ||
82 | { | ||
83 | /* Just another check... */ | ||
84 | if (brightness > MAX_BRIGHTNESS_SETTING) | ||
85 | brightness = MAX_BRIGHTNESS_SETTING; | ||
86 | if (brightness < MIN_BRIGHTNESS_SETTING) | ||
87 | brightness = MIN_BRIGHTNESS_SETTING; | ||
88 | ascodec_write_pmu(AS3543_BACKLIGHT, 0x3, brightness << 3 & 0xf8); | ||
89 | } | ||
diff --git a/firmware/target/hosted/ypr0/button-target.h b/firmware/target/hosted/ypr0/button-target.h new file mode 100644 index 0000000000..5d65d97607 --- /dev/null +++ b/firmware/target/hosted/ypr0/button-target.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: button-target.h 29248 2011-02-08 20:05:25Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Lorenzo Miori | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef _BUTTON_TARGET_H_ | ||
23 | #define _BUTTON_TARGET_H_ | ||
24 | |||
25 | #include <stdbool.h> | ||
26 | #include "config.h" | ||
27 | |||
28 | void button_init_device(void); | ||
29 | void button_close_device(void); | ||
30 | int button_read_device(void); | ||
31 | |||
32 | /* Logical buttons key codes */ | ||
33 | #define BUTTON_UP 0x00000001 | ||
34 | #define BUTTON_DOWN 0x00000002 | ||
35 | #define BUTTON_LEFT 0x00000004 | ||
36 | #define BUTTON_RIGHT 0x00000008 | ||
37 | #define BUTTON_USER 0x00000010 | ||
38 | #define BUTTON_MENU 0x00000020 | ||
39 | #define BUTTON_BACK 0x00000040 | ||
40 | #define BUTTON_POWER 0x00000080 | ||
41 | #define BUTTON_SELECT 0x00000100 | ||
42 | |||
43 | #define BUTTON_MAIN 0x1FF /* all buttons */ | ||
44 | |||
45 | /* No remote */ | ||
46 | #define BUTTON_REMOTE 0 | ||
47 | |||
48 | /* Software power-off */ | ||
49 | #define POWEROFF_BUTTON BUTTON_POWER | ||
50 | /* About 3 seconds */ | ||
51 | #define POWEROFF_COUNT 10 | ||
52 | |||
53 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/hosted/ypr0/button-ypr0.c b/firmware/target/hosted/ypr0/button-ypr0.c new file mode 100644 index 0000000000..4298410161 --- /dev/null +++ b/firmware/target/hosted/ypr0/button-ypr0.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: button-sdl.c 30482 2011-09-08 14:53:28Z kugel $ | ||
9 | * | ||
10 | * Copyright (C) 2011 Lorenzo Miori | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <unistd.h> | ||
24 | #include <fcntl.h> | ||
25 | #include <stdlib.h> /* EXIT_SUCCESS */ | ||
26 | #include "config.h" | ||
27 | #include "button.h" | ||
28 | #include "kernel.h" | ||
29 | #include "system.h" | ||
30 | #include "button-target.h" | ||
31 | |||
32 | /* R0 physical key codes */ | ||
33 | enum ypr0_buttons { | ||
34 | R0BTN_NONE = BUTTON_NONE, | ||
35 | R0BTN_POWER = 1, | ||
36 | R0BTN_UP, | ||
37 | R0BTN_DOWN, | ||
38 | R0BTN_RIGHT, | ||
39 | R0BTN_LEFT, | ||
40 | R0BTN_CENTRAL, | ||
41 | R0BTN_MENU, | ||
42 | R0BTN_BACK, | ||
43 | R0BTN_3DOTS = 11, | ||
44 | }; | ||
45 | |||
46 | |||
47 | static int r0_btn_fd = 0; | ||
48 | /* Samsung keypad driver doesn't allow multiple key combinations :( */ | ||
49 | static enum ypr0_buttons r0_read_key(void) | ||
50 | { | ||
51 | unsigned char keys; | ||
52 | |||
53 | if (r0_btn_fd < 0) | ||
54 | return 0; | ||
55 | |||
56 | if (read(r0_btn_fd, &keys, 1)) | ||
57 | return keys; | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | /* Conversion from physical keypress code to logic key code */ | ||
63 | static int key_to_button(enum ypr0_buttons keyboard_button) | ||
64 | { | ||
65 | switch (keyboard_button) | ||
66 | { | ||
67 | default: return BUTTON_NONE; | ||
68 | case R0BTN_POWER: return BUTTON_POWER; | ||
69 | case R0BTN_UP: return BUTTON_UP; | ||
70 | case R0BTN_DOWN: return BUTTON_DOWN; | ||
71 | case R0BTN_RIGHT: return BUTTON_RIGHT; | ||
72 | case R0BTN_LEFT: return BUTTON_LEFT; | ||
73 | case R0BTN_CENTRAL: return BUTTON_SELECT; | ||
74 | case R0BTN_MENU: return BUTTON_MENU; | ||
75 | case R0BTN_BACK: return BUTTON_BACK; | ||
76 | case R0BTN_3DOTS: return BUTTON_USER; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | int button_read_device(void) | ||
81 | { | ||
82 | return key_to_button(r0_read_key()); | ||
83 | } | ||
84 | |||
85 | |||
86 | /* Open the keypad device: it is offered by r0Btn.ko module */ | ||
87 | void button_init_device(void) | ||
88 | { | ||
89 | r0_btn_fd = open("/dev/r0Btn", O_RDONLY); | ||
90 | if (r0_btn_fd < 0) | ||
91 | printf("/dev/r0Btn open error!"); | ||
92 | } | ||
93 | |||
94 | #ifdef BUTTON_DRIVER_CLOSE | ||
95 | /* I'm not sure it's called at shutdown...give a check! */ | ||
96 | void button_close_device(void) | ||
97 | { | ||
98 | if (r0_btn_fd >= 0) { | ||
99 | close(r0_btn_fd); | ||
100 | printf("/dev/r0Btn closed!"); | ||
101 | } | ||
102 | } | ||
103 | #endif /* BUTTON_DRIVER_CLOSE */ | ||
diff --git a/firmware/target/hosted/ypr0/dir-target.h b/firmware/target/hosted/ypr0/dir-target.h new file mode 100644 index 0000000000..48859526df --- /dev/null +++ b/firmware/target/hosted/ypr0/dir-target.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __DIR_TARGET_H__ | ||
23 | #define __DIR_TARGET_H__ | ||
24 | |||
25 | #include <dirent.h> | ||
26 | /* including unistd.h is too noisy */ | ||
27 | extern int rmdir(const char* name); | ||
28 | |||
29 | |||
30 | #define dirent_uncached dirent | ||
31 | #define DIR_UNCACHED DIR | ||
32 | #define opendir_uncached _opendir | ||
33 | #define readdir_uncached _readdir | ||
34 | #define closedir_uncached _closedir | ||
35 | #define mkdir_uncached _mkdir | ||
36 | #define rmdir_uncached rmdir | ||
37 | |||
38 | #define dirent_ypr0 dirent | ||
39 | #define DIR_ypr0 DIR | ||
40 | #define opendir_ypr0 _opendir | ||
41 | #define readdir_ypr0 _readdir | ||
42 | #define closedir_ypr0 _closedir | ||
43 | #define mkdir_ypr0 _mkdir | ||
44 | #define rmdir_ypr0 rmdir | ||
45 | |||
46 | extern DIR* _opendir(const char* name); | ||
47 | extern int _mkdir(const char* name); | ||
48 | extern int _closedir(DIR* dir); | ||
49 | extern struct dirent *_readdir(DIR* dir); | ||
50 | extern void fat_size(unsigned long *size, unsigned long *free); | ||
51 | |||
52 | #define DIRFUNCTIONS_DEFINED | ||
53 | #define DIRENT_DEFINED | ||
54 | #define DIR_DEFINED | ||
55 | |||
56 | #endif /* __DIR_TARGET_H__ */ | ||
diff --git a/firmware/target/hosted/ypr0/fs-ypr0.c b/firmware/target/hosted/ypr0/fs-ypr0.c new file mode 100644 index 0000000000..7f49a5f91a --- /dev/null +++ b/firmware/target/hosted/ypr0/fs-ypr0.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <sys/stat.h> /* stat() */ | ||
24 | #include <stdio.h> /* snprintf */ | ||
25 | #include <string.h> /* size_t */ | ||
26 | #include <dirent.h> | ||
27 | #include <time.h> /* localtime() */ | ||
28 | #include "system-target.h" | ||
29 | #include "dir-target.h" | ||
30 | #include "file.h" | ||
31 | #include "dir.h" | ||
32 | #include "rbpaths.h" | ||
33 | |||
34 | |||
35 | long filesize(int fd) | ||
36 | { | ||
37 | struct stat buf; | ||
38 | |||
39 | if (!fstat(fd, &buf)) | ||
40 | return buf.st_size; | ||
41 | else | ||
42 | return -1; | ||
43 | } | ||
44 | |||
45 | /* do we really need this in the app? */ | ||
46 | void fat_size(unsigned long* size, unsigned long* free) | ||
47 | { | ||
48 | *size = *free = 0; | ||
49 | } | ||
50 | |||
51 | #undef opendir | ||
52 | #undef closedir | ||
53 | #undef mkdir | ||
54 | #undef readdir | ||
55 | |||
56 | /* need to wrap around DIR* because we need to save the parent's | ||
57 | * directory path in order to determine dirinfo */ | ||
58 | struct __dir { | ||
59 | DIR *dir; | ||
60 | char *path; | ||
61 | }; | ||
62 | |||
63 | DIR* _opendir(const char *name) | ||
64 | { | ||
65 | char *buf = malloc(sizeof(struct __dir) + strlen(name)+1); | ||
66 | if (!buf) | ||
67 | return NULL; | ||
68 | |||
69 | struct __dir *this = (struct __dir*)buf; | ||
70 | |||
71 | this->path = buf+sizeof(struct __dir); | ||
72 | /* definitely fits due to strlen() */ | ||
73 | strcpy(this->path, name); | ||
74 | |||
75 | this->dir = opendir(name); | ||
76 | |||
77 | if (!this->dir) | ||
78 | { | ||
79 | free(buf); | ||
80 | return NULL; | ||
81 | } | ||
82 | return (DIR*)this; | ||
83 | } | ||
84 | |||
85 | int _mkdir(const char *name) | ||
86 | { | ||
87 | return mkdir(name, 0777); | ||
88 | } | ||
89 | |||
90 | int _closedir(DIR *dir) | ||
91 | { | ||
92 | struct __dir *this = (struct __dir*)dir; | ||
93 | int ret = closedir(this->dir); | ||
94 | free(this); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | struct dirent* _readdir(DIR* dir) | ||
99 | { | ||
100 | struct __dir *d = (struct __dir*)dir; | ||
101 | return readdir(d->dir); | ||
102 | } | ||
103 | |||
104 | struct dirinfo dir_get_info(DIR* _parent, struct dirent *dir) | ||
105 | { | ||
106 | struct __dir *parent = (struct __dir*)_parent; | ||
107 | struct stat s; | ||
108 | struct tm *tm = NULL; | ||
109 | struct dirinfo ret; | ||
110 | char path[MAX_PATH]; | ||
111 | |||
112 | snprintf(path, sizeof(path), "%s/%s", parent->path, dir->d_name); | ||
113 | memset(&ret, 0, sizeof(ret)); | ||
114 | |||
115 | if (!stat(path, &s)) | ||
116 | { | ||
117 | if (S_ISDIR(s.st_mode)) | ||
118 | { | ||
119 | ret.attribute = ATTR_DIRECTORY; | ||
120 | } | ||
121 | ret.size = s.st_size; | ||
122 | tm = localtime(&(s.st_mtime)); | ||
123 | } | ||
124 | |||
125 | if (!lstat(path, &s) && S_ISLNK(s.st_mode)) | ||
126 | { | ||
127 | ret.attribute |= ATTR_LINK; | ||
128 | } | ||
129 | |||
130 | if (tm) | ||
131 | { | ||
132 | ret.wrtdate = ((tm->tm_year - 80) << 9) | | ||
133 | ((tm->tm_mon + 1) << 5) | | ||
134 | tm->tm_mday; | ||
135 | ret.wrttime = (tm->tm_hour << 11) | | ||
136 | (tm->tm_min << 5) | | ||
137 | (tm->tm_sec >> 1); | ||
138 | } | ||
139 | |||
140 | return ret; | ||
141 | } | ||
diff --git a/firmware/target/hosted/ypr0/i2c-target.h b/firmware/target/hosted/ypr0/i2c-target.h new file mode 100644 index 0000000000..3b046bba96 --- /dev/null +++ b/firmware/target/hosted/ypr0/i2c-target.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: i2c-target.h 29516 2011-03-05 15:31:52Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __I2C_TARGET_H__ | ||
23 | #define __I2C_TARGET_H__ | ||
24 | |||
25 | #endif /* __I2C_TARGET_H__ */ | ||
diff --git a/firmware/target/hosted/ypr0/kernel-ypr0.c b/firmware/target/hosted/ypr0/kernel-ypr0.c new file mode 100644 index 0000000000..bcf2cee583 --- /dev/null +++ b/firmware/target/hosted/ypr0/kernel-ypr0.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2010 Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | |||
23 | #include <time.h> | ||
24 | #include <signal.h> | ||
25 | #include <errno.h> | ||
26 | #include <unistd.h> | ||
27 | #include <pthread.h> | ||
28 | #include "config.h" | ||
29 | #include "system.h" | ||
30 | #include "button.h" | ||
31 | #include "audio.h" | ||
32 | #include "panic.h" | ||
33 | #include "timer.h" | ||
34 | |||
35 | |||
36 | static pthread_cond_t wfi_cond = PTHREAD_COND_INITIALIZER; | ||
37 | static pthread_mutex_t wfi_mtx = PTHREAD_MUTEX_INITIALIZER; | ||
38 | /* | ||
39 | * call tick tasks and wake the scheduler up */ | ||
40 | void timer_signal(union sigval arg) | ||
41 | { | ||
42 | (void)arg; | ||
43 | call_tick_tasks(); | ||
44 | interrupt(); | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * wait on the sem which the signal handler posts to save cpu time (aka sleep) | ||
49 | * | ||
50 | * other mechanisms could use them as well */ | ||
51 | void wait_for_interrupt(void) | ||
52 | { | ||
53 | pthread_cond_wait(&wfi_cond, &wfi_mtx); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Wakeup the kernel, if sleeping (shall not be called from a signal handler) */ | ||
58 | void interrupt(void) | ||
59 | { | ||
60 | pthread_cond_signal(&wfi_cond); | ||
61 | } | ||
62 | |||
63 | |||
64 | /* | ||
65 | * setup a hrtimer to send a signal to our process every tick | ||
66 | */ | ||
67 | union sigval tick_arg = { | ||
68 | .sival_int = 0, | ||
69 | }; | ||
70 | |||
71 | void tick_start(unsigned int interval_in_ms) | ||
72 | { | ||
73 | int ret = 0; | ||
74 | timer_t timerid; | ||
75 | struct itimerspec ts; | ||
76 | sigevent_t sigev; | ||
77 | |||
78 | /* initializing in the declaration causes some weird warnings */ | ||
79 | memset(&sigev, 0, sizeof(sigevent_t)); | ||
80 | sigev.sigev_notify = SIGEV_THREAD, | ||
81 | sigev.sigev_notify_function = timer_signal; | ||
82 | |||
83 | ts.it_value.tv_sec = ts.it_interval.tv_sec = 0; | ||
84 | ts.it_value.tv_nsec = ts.it_interval.tv_nsec = interval_in_ms*1000*1000; | ||
85 | |||
86 | /* add the timer */ | ||
87 | ret |= timer_create(CLOCK_REALTIME, &sigev, &timerid); | ||
88 | ret |= timer_settime(timerid, 0, &ts, NULL); | ||
89 | |||
90 | /* Grab the mutex already now and leave it to this thread. We don't | ||
91 | * care about race conditions when signaling the condition (because | ||
92 | * they are not critical), but a mutex is necessary due to the API */ | ||
93 | pthread_mutex_lock(&wfi_mtx); | ||
94 | |||
95 | if (ret != 0) | ||
96 | panicf("%s(): %s\n", __func__, strerror(errno)); | ||
97 | } | ||
98 | |||
99 | #define cycles_to_microseconds(cycles) \ | ||
100 | ((int)((1000000*cycles)/TIMER_FREQ)) | ||
101 | |||
102 | |||
103 | static timer_t timer_tid; | ||
104 | static int timer_prio = -1; | ||
105 | void (*global_unreg_callback)(void); | ||
106 | void (*global_timer_callback)(void); | ||
107 | |||
108 | static void timer_cb(union sigval arg) | ||
109 | { | ||
110 | (void)arg; | ||
111 | if (global_timer_callback) | ||
112 | global_timer_callback(); | ||
113 | } | ||
114 | |||
115 | bool timer_register(int reg_prio, void (*unregister_callback)(void), | ||
116 | long cycles, void (*timer_callback)(void)) | ||
117 | { | ||
118 | int ret = 0; | ||
119 | struct itimerspec ts; | ||
120 | sigevent_t sigev; | ||
121 | long in_us = cycles_to_microseconds(cycles); | ||
122 | |||
123 | if (reg_prio <= timer_prio || in_us <= 0) | ||
124 | return false; | ||
125 | |||
126 | if (timer_prio >= 0 && global_unreg_callback) | ||
127 | global_unreg_callback(); | ||
128 | |||
129 | /* initializing in the declaration causes some weird warnings */ | ||
130 | memset(&sigev, 0, sizeof(sigevent_t)); | ||
131 | sigev.sigev_notify = SIGEV_THREAD, | ||
132 | sigev.sigev_notify_function = timer_cb; | ||
133 | |||
134 | ts.it_value.tv_sec = ts.it_interval.tv_sec = in_us / 1000000; | ||
135 | ts.it_value.tv_nsec = ts.it_interval.tv_nsec = (in_us%1000000)*1000; | ||
136 | |||
137 | /* add the timer */ | ||
138 | ret |= timer_create(CLOCK_REALTIME, &sigev, &timer_tid); | ||
139 | ret |= timer_settime(timer_tid, 0, &ts, NULL); | ||
140 | |||
141 | global_timer_callback = timer_callback; | ||
142 | global_unreg_callback = unregister_callback; | ||
143 | timer_prio = reg_prio; | ||
144 | |||
145 | return ret == 0; | ||
146 | } | ||
147 | |||
148 | bool timer_set_period(long cycles) | ||
149 | { | ||
150 | struct itimerspec ts; | ||
151 | long in_us = cycles_to_microseconds(cycles); | ||
152 | ts.it_value.tv_sec = ts.it_interval.tv_sec = in_us / 1000000; | ||
153 | ts.it_value.tv_nsec = ts.it_interval.tv_nsec = (in_us%1000000)*1000; | ||
154 | |||
155 | return timer_settime(timer_tid, 0, &ts, NULL) == 0; | ||
156 | } | ||
157 | |||
158 | void timer_unregister(void) | ||
159 | { | ||
160 | timer_delete(timer_tid); | ||
161 | timer_prio = -1; | ||
162 | } | ||
163 | |||
diff --git a/firmware/target/hosted/ypr0/lc-ypr0.c b/firmware/target/hosted/ypr0/lc-ypr0.c new file mode 100644 index 0000000000..434e901a56 --- /dev/null +++ b/firmware/target/hosted/ypr0/lc-ypr0.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <string.h> /* size_t */ | ||
23 | #include "load_code.h" | ||
24 | |||
25 | /* the load_code wrappers simply wrap, nothing to do */ | ||
26 | void *lc_open(const char *filename, unsigned char *buf, size_t buf_size) | ||
27 | { | ||
28 | return _lc_open(filename, buf, buf_size); | ||
29 | } | ||
30 | |||
31 | void *lc_get_header(void *handle) | ||
32 | { | ||
33 | return _lc_get_header(handle); | ||
34 | } | ||
35 | |||
36 | void lc_close(void *handle) | ||
37 | { | ||
38 | _lc_close(handle); | ||
39 | } | ||
40 | |||
diff --git a/firmware/target/hosted/ypr0/lcd-ypr0.c b/firmware/target/hosted/ypr0/lcd-ypr0.c new file mode 100644 index 0000000000..f0565ae2d4 --- /dev/null +++ b/firmware/target/hosted/ypr0/lcd-ypr0.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: lcd-bitmap.c 29248 2011-02-08 20:05:25Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2011 Lorenzo Miori, Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <unistd.h> | ||
24 | #include <stdio.h> | ||
25 | #include "string.h" | ||
26 | #include <linux/fb.h> | ||
27 | #include <sys/mman.h> | ||
28 | #include <sys/ioctl.h> | ||
29 | |||
30 | #include "file.h" | ||
31 | #include "debug.h" | ||
32 | #include "system.h" | ||
33 | #include "screendump.h" | ||
34 | #include "lcd.h" | ||
35 | |||
36 | /* eqivalent to fb + y*width + x */ | ||
37 | #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) | ||
38 | |||
39 | static int dev_fd = 0; | ||
40 | static fb_data *dev_fb = 0; | ||
41 | |||
42 | void lcd_update(void) | ||
43 | { | ||
44 | /* update the entire display */ | ||
45 | memcpy(dev_fb, lcd_framebuffer, sizeof(lcd_framebuffer)); | ||
46 | } | ||
47 | |||
48 | /* Copy Rockbox frame buffer to the mmapped lcd device */ | ||
49 | void lcd_update_rect(int x, int y, int width, int height) | ||
50 | { | ||
51 | /* nothing to draw? */ | ||
52 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || | ||
53 | (y >= LCD_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | ||
54 | return; | ||
55 | |||
56 | /* do the necessary clipping */ | ||
57 | if (x < 0) | ||
58 | { /* clip left */ | ||
59 | width += x; | ||
60 | x = 0; | ||
61 | } | ||
62 | if (y < 0) | ||
63 | { /* clip top */ | ||
64 | height += y; | ||
65 | y = 0; | ||
66 | } | ||
67 | if (x + width > LCD_WIDTH) | ||
68 | width = LCD_WIDTH - x; /* clip right */ | ||
69 | if (y + height > LCD_HEIGHT) | ||
70 | height = LCD_HEIGHT - y; /* clip bottom */ | ||
71 | |||
72 | fb_data* src = LCDADDR(x, y); | ||
73 | fb_data* dst = dev_fb + y*LCD_WIDTH + x; | ||
74 | |||
75 | if (LCD_WIDTH == width) | ||
76 | { /* optimized full-width update */ | ||
77 | memcpy(dst, src, width * height * sizeof(fb_data)); | ||
78 | } | ||
79 | else | ||
80 | { /* row by row */ | ||
81 | do | ||
82 | { | ||
83 | memcpy(dst, src, width * sizeof(fb_data)); | ||
84 | src += LCD_WIDTH; | ||
85 | dst += LCD_WIDTH; | ||
86 | } while(--height > 0); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void lcd_shutdown(void) | ||
91 | { | ||
92 | printf("FB closed."); | ||
93 | munmap(dev_fb, sizeof(lcd_framebuffer)); | ||
94 | close(dev_fd); | ||
95 | } | ||
96 | |||
97 | void lcd_init_device(void) | ||
98 | { | ||
99 | size_t screensize; | ||
100 | struct fb_var_screeninfo vinfo; | ||
101 | struct fb_fix_screeninfo finfo; | ||
102 | |||
103 | /* Open the framebuffer device */ | ||
104 | dev_fd = open("/dev/fb0", O_RDWR); | ||
105 | if (dev_fd == -1) { | ||
106 | perror("Error: cannot open framebuffer device"); | ||
107 | exit(1); | ||
108 | } | ||
109 | printf("The framebuffer device was opened successfully.\n"); | ||
110 | |||
111 | /* Get the fixed properties */ | ||
112 | if (ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) == -1) { | ||
113 | perror("Error reading fixed information"); | ||
114 | exit(2); | ||
115 | } | ||
116 | |||
117 | /* Now we get the settable settings, and we set 16 bit bpp */ | ||
118 | if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { | ||
119 | perror("Error reading variable information"); | ||
120 | exit(3); | ||
121 | } | ||
122 | |||
123 | vinfo.bits_per_pixel = 16; | ||
124 | |||
125 | if (ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo)) { | ||
126 | perror("fbset(ioctl)"); | ||
127 | exit(4); | ||
128 | } | ||
129 | |||
130 | printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); | ||
131 | |||
132 | /* Figure out the size of the screen in bytes */ | ||
133 | screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; | ||
134 | if (screensize != sizeof(lcd_framebuffer)) | ||
135 | { | ||
136 | exit(4); | ||
137 | perror("Display and framebuffer mismatch!\n"); | ||
138 | } | ||
139 | |||
140 | /* Map the device to memory */ | ||
141 | dev_fb = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0); | ||
142 | if ((int)dev_fb == -1) { | ||
143 | perror("Error: failed to map framebuffer device to memory"); | ||
144 | exit(4); | ||
145 | } | ||
146 | printf("The framebuffer device was mapped to memory successfully.\n"); | ||
147 | } | ||
diff --git a/firmware/target/hosted/ypr0/powermgmt-ypr0.c b/firmware/target/hosted/ypr0/powermgmt-ypr0.c new file mode 100644 index 0000000000..5701e9f02f --- /dev/null +++ b/firmware/target/hosted/ypr0/powermgmt-ypr0.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: powermgmt-sim.c 29543 2011-03-08 19:33:30Z thomasjfox $ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "system.h" | ||
21 | #include <time.h> | ||
22 | #include "kernel.h" | ||
23 | #include "powermgmt.h" | ||
24 | #include "ascodec-target.h" | ||
25 | #include "stdio.h" | ||
26 | |||
27 | #if 0 /*still unused*/ | ||
28 | /* The battery manufacturer's website shows discharge curves down to 3.0V, | ||
29 | so 'dangerous' and 'shutoff' levels of 3.4V and 3.3V should be safe. | ||
30 | */ | ||
31 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
32 | { | ||
33 | 3550 | ||
34 | }; | ||
35 | |||
36 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
37 | { | ||
38 | 3450 | ||
39 | }; | ||
40 | |||
41 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
42 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
43 | { | ||
44 | { 3300, 3692, 3740, 3772, 3798, 3828, 3876, 3943, 4013, 4094, 4194 } | ||
45 | }; | ||
46 | |||
47 | #if CONFIG_CHARGING | ||
48 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
49 | const unsigned short percent_to_volt_charge[11] = | ||
50 | { | ||
51 | 3417, 3802, 3856, 3888, 3905, 3931, 3973, 4025, 4084, 4161, 4219 | ||
52 | }; | ||
53 | #endif /* CONFIG_CHARGING */ | ||
54 | #endif | ||
55 | |||
56 | #define BATT_MINMVOLT 3450 /* minimum millivolts of battery */ | ||
57 | #define BATT_MAXMVOLT 4150 /* maximum millivolts of battery */ | ||
58 | #define BATT_MAXRUNTIME (10 * 60) /* maximum runtime with full battery in | ||
59 | minutes */ | ||
60 | |||
61 | extern void send_battery_level_event(void); | ||
62 | extern int last_sent_battery_level; | ||
63 | extern int battery_percent; | ||
64 | |||
65 | static unsigned int battery_millivolts = BATT_MAXMVOLT; | ||
66 | /* estimated remaining time in minutes */ | ||
67 | static int powermgmt_est_runningtime_min = BATT_MAXRUNTIME; | ||
68 | |||
69 | static void battery_status_update(void) | ||
70 | { | ||
71 | static time_t last_change = 0; | ||
72 | time_t now; | ||
73 | |||
74 | time(&now); | ||
75 | |||
76 | if (last_change < now) { | ||
77 | last_change = now; | ||
78 | |||
79 | battery_percent = 100 * (battery_millivolts - BATT_MINMVOLT) / | ||
80 | (BATT_MAXMVOLT - BATT_MINMVOLT); | ||
81 | |||
82 | powermgmt_est_runningtime_min = | ||
83 | battery_percent * BATT_MAXRUNTIME / 100; | ||
84 | } | ||
85 | |||
86 | send_battery_level_event(); | ||
87 | } | ||
88 | |||
89 | void battery_read_info(int *voltage, int *level) | ||
90 | { | ||
91 | battery_status_update(); | ||
92 | |||
93 | if (voltage) | ||
94 | *voltage = battery_millivolts; | ||
95 | |||
96 | if (level) | ||
97 | *level = battery_percent; | ||
98 | } | ||
99 | |||
100 | unsigned int battery_voltage(void) | ||
101 | { | ||
102 | battery_status_update(); | ||
103 | return battery_millivolts; | ||
104 | } | ||
105 | |||
106 | int battery_level(void) | ||
107 | { | ||
108 | battery_status_update(); | ||
109 | return battery_percent; | ||
110 | } | ||
111 | |||
112 | int battery_time(void) | ||
113 | { | ||
114 | battery_status_update(); | ||
115 | return powermgmt_est_runningtime_min; | ||
116 | } | ||
117 | |||
118 | bool battery_level_safe(void) | ||
119 | { | ||
120 | return battery_level() >= 10; | ||
121 | } | ||
122 | |||
123 | void set_battery_capacity(int capacity) | ||
124 | { | ||
125 | (void)capacity; | ||
126 | } | ||
127 | |||
128 | #if BATTERY_TYPES_COUNT > 1 | ||
129 | void set_battery_type(int type) | ||
130 | { | ||
131 | (void)type; | ||
132 | } | ||
133 | #endif | ||
diff --git a/firmware/target/hosted/ypr0/system-target.h b/firmware/target/hosted/ypr0/system-target.h new file mode 100644 index 0000000000..07a3163ea9 --- /dev/null +++ b/firmware/target/hosted/ypr0/system-target.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __SYSTEM_TARGET_H__ | ||
22 | #define __SYSTEM_TARGET_H__ | ||
23 | |||
24 | #define disable_irq() | ||
25 | #define enable_irq() | ||
26 | #define disable_irq_save() 0 | ||
27 | #define restore_irq(level) (void)level | ||
28 | |||
29 | void wait_for_interrupt(void); | ||
30 | void interrupt(void); | ||
31 | |||
32 | static inline void commit_dcache(void) {} | ||
33 | static inline void commit_discard_dcache(void) {} | ||
34 | static inline void commit_discard_idcache(void) {} | ||
35 | |||
36 | #define NEED_GENERIC_BYTESWAPS | ||
37 | #endif /* __SYSTEM_TARGET_H__ */ | ||
diff --git a/firmware/target/hosted/ypr0/system-ypr0.c b/firmware/target/hosted/ypr0/system-ypr0.c new file mode 100644 index 0000000000..3a2b30339f --- /dev/null +++ b/firmware/target/hosted/ypr0/system-ypr0.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: system-sdl.c 29925 2011-05-25 20:11:03Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <inttypes.h> | ||
25 | #include "system.h" | ||
26 | #include "panic.h" | ||
27 | #include "debug.h" | ||
28 | |||
29 | #if defined(HAVE_SDL_AUDIO) || defined(HAVE_SDL_THREADS) || defined(HAVE_SDL) | ||
30 | #include <SDL.h> | ||
31 | #endif | ||
32 | |||
33 | #include "ascodec-target.h" | ||
34 | |||
35 | void sim_do_exit(void) | ||
36 | { | ||
37 | exit(EXIT_SUCCESS); | ||
38 | } | ||
39 | |||
40 | void shutdown_hw(void) | ||
41 | { | ||
42 | /* Something that we need to do before exit on our platform YPR0 */ | ||
43 | ascodec_close(); | ||
44 | sim_do_exit(); | ||
45 | } | ||
46 | |||
47 | uintptr_t *stackbegin; | ||
48 | uintptr_t *stackend; | ||
49 | void system_init(void) | ||
50 | { | ||
51 | int *s; | ||
52 | /* fake stack, OS manages size (and growth) */ | ||
53 | stackbegin = stackend = (uintptr_t*)&s; | ||
54 | |||
55 | #if defined(HAVE_SDL_AUDIO) || defined(HAVE_SDL_THREADS) || defined(HAVE_SDL) | ||
56 | SDL_Init(0); /* need this if using any SDL subsystem */ | ||
57 | #endif | ||
58 | /* Here begins our platform specific initilization for various things */ | ||
59 | ascodec_init(); | ||
60 | } | ||
61 | |||
62 | |||
63 | void system_reboot(void) | ||
64 | { | ||
65 | sim_do_exit(); | ||
66 | } | ||
67 | |||
68 | void system_exception_wait(void) | ||
69 | { | ||
70 | system_reboot(); | ||
71 | } | ||
72 | |||
73 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
74 | #include <stdio.h> | ||
75 | #include "file.h" | ||
76 | /* This is the Linux Kernel CPU governor... */ | ||
77 | static void set_cpu_freq(int speed) | ||
78 | { | ||
79 | char temp[10]; | ||
80 | int cpu_dev; | ||
81 | cpu_dev = open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", O_WRONLY); | ||
82 | if (cpu_dev < 0) | ||
83 | return; | ||
84 | write(cpu_dev, temp, sprintf(temp, "%d", speed) + 1); | ||
85 | close(cpu_dev); | ||
86 | } | ||
87 | |||
88 | void set_cpu_frequency(long frequency) | ||
89 | { | ||
90 | switch (frequency) | ||
91 | { | ||
92 | case CPUFREQ_MAX: | ||
93 | set_cpu_freq(532000); | ||
94 | cpu_frequency = CPUFREQ_MAX; | ||
95 | break; | ||
96 | case CPUFREQ_NORMAL: | ||
97 | set_cpu_freq(400000); | ||
98 | cpu_frequency = CPUFREQ_NORMAL; | ||
99 | break; | ||
100 | default: | ||
101 | set_cpu_freq(200000); | ||
102 | cpu_frequency = CPUFREQ_DEFAULT; | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | #endif | ||
diff --git a/firmware/target/hosted/ypr0/usb-target.h b/firmware/target/hosted/ypr0/usb-target.h new file mode 100644 index 0000000000..237d179775 --- /dev/null +++ b/firmware/target/hosted/ypr0/usb-target.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: usb-target.h 29516 2011-03-05 15:31:52Z thomasjfox $ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __USB_TARGET_H__ | ||
23 | #define __USB_TARGET_H__ | ||
24 | |||
25 | #endif /* __USB_TARGET_H__ */ | ||
diff --git a/firmware/target/hosted/ypr0/ypr0.make b/firmware/target/hosted/ypr0/ypr0.make new file mode 100644 index 0000000000..c2114878db --- /dev/null +++ b/firmware/target/hosted/ypr0/ypr0.make | |||
@@ -0,0 +1,25 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | INCLUDES += -I$(FIRMDIR)/include -I$(FIRMDIR)/export $(TARGET_INC) -I$(BUILDDIR) -I$(APPSDIR) | ||
11 | |||
12 | SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS) | ||
13 | |||
14 | .SECONDEXPANSION: # $$(OBJ) is not populated until after this | ||
15 | |||
16 | |||
17 | $(BUILDDIR)/rockbox.elf : $$(OBJ) $$(FIRMLIB) $$(VOICESPEEXLIB) $$(SKINLIB) | ||
18 | $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ | ||
19 | -L$(BUILDDIR)/firmware -lfirmware \ | ||
20 | -L$(BUILDDIR)/apps/codecs $(VOICESPEEXLIB:lib%.a=-l%) \ | ||
21 | -L$(BUILDDIR)/lib -lskin_parser \ | ||
22 | $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map | ||
23 | |||
24 | $(BUILDDIR)/rockbox : $(BUILDDIR)/rockbox.elf | ||
25 | $(call PRINTS,OC $(@F))$(OC) -S -x $< $@ | ||