summaryrefslogtreecommitdiff
path: root/rbutil/ibassoboot/jni/ibassodualboot.c
diff options
context:
space:
mode:
authorSimon Rothen <rothen@gmx.net>2014-08-30 13:15:53 +0200
committerMichael Giacomelli <giac2000@hotmail.com>2014-09-18 18:19:01 +0200
commit0b5ad60c26f30dc5363c21e436b73292c09ac567 (patch)
tree2d7cee2b2133218d59e0f462c9dbdbec8e88b2e2 /rbutil/ibassoboot/jni/ibassodualboot.c
parent1f0fa0546647a191c52784a4a225982ffbd1af11 (diff)
downloadrockbox-0b5ad60c26f30dc5363c21e436b73292c09ac567.tar.gz
rockbox-0b5ad60c26f30dc5363c21e436b73292c09ac567.zip
Introducing Targets iBasso DX50 & iBasso DX90
The port to for this two targets has been entirely developped by Ilia Sergachev (alias Il or xzcc). His source can be found at https://bitbucket.org/isergachev/rockbox . The few necesary modifications for the DX90 port was done by headwhacker form head-fi.org. Unfortunately i could not try out the final state of the DX90 port. The port is hosted on android (without java) as standalone app. The official Firmware is required to run this port. Ilia did modify the source files for the "android" target in the rockbox source to make the DX port work. The work I did was to separate the code for DX50 (&DX90) from the android target. On this Target Ilia used source from tinyalsa from AOSP. I did not touch that part of the code because I do not understand it. What else I changed from Ilias sources besides the separation from the target "android": * removed a dirty hack to keep backlight off * changed value battery meter to voltage battery meter * made all plugins compile (named target as "standalone") and added keymaps * i added the graphics for the manual but did not do anything else for the manual yet * minor optimizations known bugs: * timers are slowed donw when playback is active (tinyalsa related?) * some minor bugs Things to do: * The main prolem will be how to install the app correctly. A guy called DOC2008 added a CWM (by androtab.info) to the official firmware and Ilia made a CWM installation script and a dualboot selector (rbutils/ibassoboot, build with ndk-build). We will have to find a way to install rockbox in a proper way without breaking any copyrights. Maybe ADB is an option but it is not enable with OF by default. Patching the OF is probably the way to go. * All the wiki and manual to build: needed: android ndk installed, android sdk installed with additional build-tools 19.1.0 installed ./tools/configure select iBasso DX50 or iBasso DX90 make -j apk the content of rockbox.zip/.rockbox needs to be copied to /system/rockbox/app_rockbox/rockbox/ (rockbox app not needed) the content of libs/armeabi to /system/rockbox/lib/ (rockbox app needed) The boot selector is needed as /system/bin/MangoPlayer and the iBasso app as /system/bin/MangoPlayer_original. There is also the "vold" file. The one from OF does not work with DX50 rockbox (DX90 works!?), the one from Ilia is necessary. Until we have found a proper way to install it, it can only be installed following the instructions of Ilia on his bitbucket page, using the CWM-OF and his installation script package. Change-Id: Ic4faaf84824c162aabcc08e492cee6e0068719d0 Reviewed-on: http://gerrit.rockbox.org/941 Tested: Chiwen Chang <rock1104.tw@yahoo.com.tw> Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
Diffstat (limited to 'rbutil/ibassoboot/jni/ibassodualboot.c')
-rw-r--r--rbutil/ibassoboot/jni/ibassodualboot.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/rbutil/ibassoboot/jni/ibassodualboot.c b/rbutil/ibassoboot/jni/ibassodualboot.c
new file mode 100644
index 0000000000..3f20bbeecf
--- /dev/null
+++ b/rbutil/ibassoboot/jni/ibassodualboot.c
@@ -0,0 +1,439 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Ilia Sergachev
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 <dirent.h>
23#include <errno.h>
24#include <fcntl.h>
25
26#include <linux/fb.h>
27#include <linux/input.h>
28#include <linux/reboot.h>
29
30#include <stdbool.h>
31#include <string.h>
32#include <stdint.h>
33#include <stdio.h>
34#include <stdlib.h>
35
36#include <time.h>
37
38#include <sys/limits.h>
39#include <sys/mman.h>
40#include <sys/inotify.h>
41#include <sys/ioctl.h>
42#include <sys/poll.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/types.h>
46
47#include <unistd.h>
48
49#include "qdbmp.h"
50
51
52#define MIN_TIME 1395606821
53#define TIME_FILE "/data/time_store"
54#define TIME_CHECK_PERIOD 60 /* seconds */
55#define VOLD_LINK "/data/vold"
56#define PLAYER_FILE "/data/chosen_player"
57#define NOASK_FLAG "/data/no_ask_once"
58#define POLL_MS 10
59
60
61#define KEYCODE_HEADPHONES 114
62#define KEYCODE_HOLD 115
63#define KEYCODE_PWR 116
64#define KEYCODE_PWR_LONG 117
65#define KEYCODE_SD 143
66#define KEYCODE_VOLPLUS 158
67#define KEYCODE_VOLMINUS 159
68#define KEYCODE_PREV 160
69#define KEYCODE_NEXT 162
70#define KEYCODE_PLAY 161
71
72#define KEY_HOLD_OFF 16
73
74void checktime()
75{
76 time_t t_stored=0, t_current=time(NULL);
77
78 FILE *f = fopen(TIME_FILE, "r");
79 if(f!=NULL)
80 {
81 fscanf(f, "%ld", &t_stored);
82 fclose(f);
83 }
84
85 printf("stored time: %ld, current time: %ld\n", t_stored, t_current);
86
87 if(t_stored<MIN_TIME)
88 t_stored=MIN_TIME;
89
90 if(t_stored<t_current)
91 {
92 f = fopen(TIME_FILE, "w");
93 fprintf(f, "%ld", t_current);
94 fclose(f);
95 }
96 else
97 {
98 t_stored += TIME_CHECK_PERIOD;
99 struct tm *t = localtime(&t_stored);
100 struct timeval tv = {mktime(t), 0};
101 settimeofday(&tv, 0);
102 }
103}
104
105
106static struct pollfd *ufds;
107static char **device_names;
108static int nfds;
109
110
111
112static int open_device(const char *device, int print_flags)
113{
114 int fd;
115 struct pollfd *new_ufds;
116 char **new_device_names;
117
118 fd = open(device, O_RDWR);
119 if(fd < 0)
120 {
121 fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
122 return -1;
123 }
124
125 new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
126 if(new_ufds == NULL)
127 {
128 fprintf(stderr, "out of memory\n");
129 return -1;
130 }
131 ufds = new_ufds;
132 new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
133 if(new_device_names == NULL)
134 {
135 fprintf(stderr, "out of memory\n");
136 return -1;
137 }
138 device_names = new_device_names;
139
140 ufds[nfds].fd = fd;
141 ufds[nfds].events = POLLIN;
142 device_names[nfds] = strdup(device);
143 nfds++;
144
145 return 0;
146}
147
148
149
150static int scan_dir(const char *dirname, int print_flags)
151{
152 char devname[PATH_MAX];
153 char *filename;
154 DIR *dir;
155 struct dirent *de;
156 dir = opendir(dirname);
157 if(dir == NULL)
158 return -1;
159 strcpy(devname, dirname);
160 filename = devname + strlen(devname);
161 *filename++ = '/';
162 while((de = readdir(dir)))
163 {
164 if(de->d_name[0] == '.' &&
165 (de->d_name[1] == '\0' ||
166 (de->d_name[1] == '.' && de->d_name[2] == '\0')))
167 continue;
168 strcpy(filename, de->d_name);
169 open_device(devname, print_flags);
170 }
171 closedir(dir);
172 return 0;
173}
174
175
176
177void button_init_device(void)
178{
179 int res;
180 int print_flags = 0;
181 const char *device = NULL;
182 const char *device_path = "/dev/input";
183
184 nfds = 1;
185 ufds = calloc(1, sizeof(ufds[0]));
186 ufds[0].fd = inotify_init();
187 ufds[0].events = POLLIN;
188 if(device)
189 {
190 res = open_device(device, print_flags);
191 if(res < 0) {
192 fprintf(stderr, "open device failed\n");
193 }
194 }
195 else
196 {
197 res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
198 if(res < 0)
199 {
200 fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
201 }
202 res = scan_dir(device_path, print_flags);
203 if(res < 0)
204 {
205 fprintf(stderr, "scan dir failed for %s\n", device_path);
206 }
207 }
208}
209
210
211int draw()
212{
213 int fbfd = 0;
214 struct fb_var_screeninfo vinfo;
215 struct fb_fix_screeninfo finfo;
216 long int screensize = 0;
217 char *fbp = 0;
218 int x = 0, y = 0;
219 long int location = 0;
220
221 /* Open the file for reading and writing */
222 fbfd = open("/dev/graphics/fb0", O_RDWR);
223 if (fbfd == -1)
224 {
225 perror("Error: cannot open framebuffer device");
226 exit(1);
227 }
228 /* Get fixed screen information */
229 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
230 {
231 perror("Error reading fixed information");
232 exit(2);
233 }
234
235 /* Get variable screen information */
236 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
237 {
238 perror("Error reading variable information");
239 exit(3);
240 }
241
242 /* Figure out the size of the screen in bytes */
243 screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
244
245 vinfo.xres = vinfo.xres_virtual = vinfo.width = 320;
246 vinfo.yres = vinfo.yres_virtual = vinfo.height = 240;
247 vinfo.xoffset = vinfo.yoffset = vinfo.sync = vinfo.vmode = 0;
248 vinfo.pixclock = 104377;
249 vinfo.left_margin = 20;
250 vinfo.right_margin = 50;
251 vinfo.upper_margin = 2;
252 vinfo.lower_margin = 4;
253 vinfo.hsync_len = 10;
254 vinfo.vsync_len = 2;
255 vinfo.red.offset = 11;
256 vinfo.red.length = 5;
257 vinfo.red.msb_right = 0;
258 vinfo.green.offset = 5;
259 vinfo.green.length = 6;
260 vinfo.green.msb_right = 0;
261 vinfo.blue.offset = 0;
262 vinfo.blue.length = 5;
263 vinfo.blue.msb_right = 0;
264 vinfo.transp.offset = vinfo.transp.length = vinfo.transp.msb_right = 0;
265 vinfo.nonstd = 4;
266
267 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo))
268 {
269 perror("fbset(ioctl)");
270 exit(4);
271 }
272
273
274 /* Map the device to memory */
275 fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
276 fbfd, 0);
277 if ((int)fbp == -1)
278 {
279 perror("Error: failed to map framebuffer device to memory");
280 exit(4);
281 }
282
283 BMP* bmp = BMP_ReadFile("/system/rockbox/chooser.bmp");
284 BMP_CHECK_ERROR( stderr, -1 );
285
286 UCHAR r, g, b;
287 unsigned short int t;
288
289 for (y = 0; y < 240; y++)
290 for (x = 0; x < 320; x++)
291 {
292 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
293 (y+vinfo.yoffset) * finfo.line_length;
294
295 BMP_GetPixelRGB(bmp, x, y, &r, &g, &b);
296 t = (r>>3)<<11 | (g>>2) << 5 | (b>>3);
297 *((unsigned short int*)(fbp + location)) = t;
298 }
299
300 BMP_Free( bmp );
301
302 munmap(fbp, screensize);
303 close(fbfd);
304 return 0;
305}
306
307
308int choose_player()
309{
310 int i;
311 int res;
312 struct input_event event;
313
314 while(true)
315 {
316 poll(ufds, nfds, POLL_MS);
317 for(i = 1; i < nfds; i++)
318 {
319 if(ufds[i].revents & POLLIN)
320 {
321 res = read(ufds[i].fd, &event, sizeof(event));
322 if(res < (int)sizeof(event))
323 {
324 fprintf(stderr, "could not get event\n");
325 }
326 if(event.type==1)
327 {
328 if(event.code==KEYCODE_NEXT)
329 {
330 puts("rockbox!");
331 return 1;
332 }
333 else if(event.code==KEYCODE_PREV)
334 {
335 puts("mango!");
336 return 0;
337 }
338 else if(event.code==KEYCODE_PWR || event.code==KEYCODE_PWR_LONG)
339 {
340 reboot(LINUX_REBOOT_CMD_POWER_OFF);
341 }
342 }
343 else if(event.type==3)
344 {
345 if(event.code==53) //x coord
346 {
347 if(event.value<160)
348 {
349 puts("mango!");
350 return 0;
351 }
352 else
353 {
354 puts("rockbox!");
355 return 1;
356 }
357 }
358 }
359 }
360 }
361 }
362 return true;
363}
364
365bool check_for_hold()
366{
367 FILE *f = fopen("/sys/class/axppower/holdkey", "r");
368 char x;
369 fscanf(f, "%c", &x);
370 fclose(f);
371
372 if(x & KEY_HOLD_OFF)
373 return false;
374 else
375 return true;
376}
377
378int main(int argc, char **argv)
379{
380 FILE *f;
381 int last_chosen_player = -1;
382
383 f = fopen(PLAYER_FILE, "r");
384 if(f!=NULL)
385 {
386 fscanf(f, "%d", &last_chosen_player);
387 fclose(f);
388 }
389 bool ask = (access(VOLD_LINK, F_OK) == -1) || ((access(NOASK_FLAG, F_OK) == -1) && check_for_hold()) || (last_chosen_player==-1);
390
391 if(ask)
392 {
393 draw();
394 button_init_device();
395 int player_chosen_now = choose_player();
396
397 if(last_chosen_player!=player_chosen_now)
398 {
399 f = fopen(PLAYER_FILE, "w");
400 fprintf(f, "%d", player_chosen_now);
401 fclose(f);
402 }
403
404 if(last_chosen_player!=player_chosen_now || (access(VOLD_LINK, F_OK) == -1))
405 {
406 system("rm "VOLD_LINK);
407
408 if(player_chosen_now)
409 system("ln -s /system/bin/vold_rockbox "VOLD_LINK);
410 else
411 system("ln -s /system/bin/vold_original "VOLD_LINK);
412
413 system("touch "NOASK_FLAG);
414 system("reboot");
415 }
416 last_chosen_player = player_chosen_now;
417 }
418
419 system("rm "NOASK_FLAG);
420
421 while(1)
422 {
423 if(last_chosen_player)
424 {
425// system("/system/bin/openadb");
426 system("/system/rockbox/lib/rockbox");
427 }
428 else
429// system("/system/bin/closeadb");
430 system("/system/bin/MangoPlayer_original");
431
432 sleep(1);
433 }
434
435 return 0;
436}
437
438
439