summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/samsungypr/ypr0/system-ypr0.c')
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/system-ypr0.c165
1 files changed, 160 insertions, 5 deletions
diff --git a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
index 477b71c6a2..893c710861 100644
--- a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
+++ b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
@@ -19,16 +19,26 @@
19 ****************************************************************************/ 19 ****************************************************************************/
20 20
21#include <stdlib.h> 21#include <stdlib.h>
22#include <string.h>
23#include <inttypes.h> 22#include <inttypes.h>
24#include <unistd.h> 23#include <unistd.h>
24#include <sys/mount.h>
25#include <errno.h>
26
25#include "system.h" 27#include "system.h"
28#include "kernel.h"
29#include "thread.h"
30
31#include "string-extra.h"
26#include "panic.h" 32#include "panic.h"
27#include "debug.h" 33#include "debug.h"
28#include "hostfs.h" 34#include "storage.h"
29 35#include "mv.h"
30#include "ascodec.h" 36#include "ascodec.h"
31#include "gpio-ypr.h" 37#include "gpio-ypr.h"
38#include "ascodec.h"
39#include "backlight.h"
40#include "rbunicode.h"
41#include "logdiskf.h"
32 42
33void power_off(void) 43void power_off(void)
34{ 44{
@@ -61,15 +71,160 @@ void system_exception_wait(void)
61 system_reboot(); 71 system_reboot();
62} 72}
63 73
74/* MicroSD card removal / insertion management */
75
76bool hostfs_removable(IF_MD_NONVOID(int drive))
77{
78#ifdef HAVE_MULTIDRIVE
79 if (drive > 0) /* Active LOW */
80 return true;
81 else
82#endif
83 return false; /* internal: always present */
84}
85
86bool hostfs_present(IF_MD_NONVOID(int drive))
87{
88#ifdef HAVE_MULTIDRIVE
89 if (drive > 0) /* Active LOW */
90 return (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_SD_SENSE, 0, 0));
91 else
92#endif
93 return true; /* internal: always present */
94}
95
96#ifdef HAVE_HOTSWAP
97bool volume_removable(int volume)
98{
99 /* don't support more than one partition yet, so volume == drive */
100 return hostfs_removable(volume);
101}
102
103bool volume_present(int volume)
104{
105 /* don't support more than one partition yet, so volume == drive */
106 return hostfs_present(volume);
107}
108#endif
109
110static int unmount_sd(void)
111{
112 int ret;
113 do
114 {
115 ret = umount("/mnt/mmc");
116 } while (ret && errno != EBUSY && errno != EINVAL);
117
118 return ret;
119}
120
121static int mount_sd(void)
122{
123 int ret;
124 /* kludge to make sure we get our wanted mount flags. This is needed
125 * when the sd was already mounted before we booted */
126 unmount_sd();
127 char iocharset[64] = "iocharset=";
128 strlcat(iocharset, get_current_codepage_name_linux(), sizeof(iocharset));
129 ret = mount("/dev/mmcblk0p1", "/mnt/mmc", "vfat",
130 MS_MGC_VAL | MS_SYNCHRONOUS | MS_RELATIME,
131 iocharset);
132 /* failure probably means the kernel does not support the iocharset.
133 * retry without to load the default */
134 if (ret == -1)
135 ret = mount("/dev/mmcblk0p1", "/mnt/mmc", "vfat",
136 MS_MGC_VAL | MS_SYNCHRONOUS | MS_RELATIME, NULL);
137 return ret;
138}
139
140#ifdef HAVE_HOTSWAP
141
142static int sd_thread_stack[DEFAULT_STACK_SIZE];
143
144enum {
145 STATE_POLL,
146 STATE_DEBOUNCE,
147 STATE_MOUNT,
148};
149
150static void NORETURN_ATTR sd_thread(void)
151{
152 int ret, state = STATE_POLL;
153 bool last_present, present;
154 int attempts = 0;
155
156 last_present = present = storage_present(1); /* shut up gcc */
157
158 while (1)
159 {
160 switch (state)
161 {
162 case STATE_POLL:
163 sleep(HZ/3);
164 attempts = 0;
165 present = storage_present(1);
166 if (last_present != present)
167 state = STATE_DEBOUNCE;
168 break;
169
170 case STATE_DEBOUNCE:
171 sleep(HZ/5);
172 present = storage_present(1);
173 if (last_present == present)
174 {
175 if (present)
176 queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
177 else
178 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
179 state = STATE_MOUNT;
180 }
181 else
182 state = STATE_POLL;
183 break;
184
185 case STATE_MOUNT:
186 sleep(HZ/10);
187 if (present)
188 ret = mount_sd();
189 else
190 ret = unmount_sd();
191 if (ret == 0)
192 {
193 NOTEF("Successfully %smounted SD card\n", present ? "":"un");
194 queue_broadcast(SYS_FS_CHANGED, 0);
195 state = STATE_POLL;
196 }
197 else if (++attempts > 20) /* stop retrying after 2s */
198 {
199 ERRORF("Failed to %smount SD card. Giving up.", present ? "":"un");
200 state = STATE_POLL;
201 }
202 /* else: need to retry a few times because the kernel is
203 * busy setting up the SD (=> do not change state) */
204 break;
205 }
206 last_present = present;
207 }
208}
209
210#endif
211
64void hostfs_init(void) 212void hostfs_init(void)
65{ 213{
66 /* stub */ 214 /* Setup GPIO pin for microSD sense, copied from OF */
215 gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_SD_SENSE, CONFIG_DEFAULT, 0);
216 gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_SD_SENSE, CONFIG_DEFAULT, 0);
217 if (storage_present(IF_MD(1)))
218 mount_sd();
219#ifdef HAVE_HOTSWAP
220 create_thread(sd_thread, sd_thread_stack, sizeof(sd_thread_stack), 0,
221 "sd thread" IF_PRIO(, PRIORITY_BACKGROUND) IF_COP(, CPU));
222#endif
67} 223}
68 224
69int hostfs_flush(void) 225int hostfs_flush(void)
70{ 226{
71 sync(); 227 sync();
72
73 return 0; 228 return 0;
74} 229}
75 230