summaryrefslogtreecommitdiffstats
path: root/firmware/target/hosted/usb-hiby.c
blob: b82fa5c4ce6762e719e673f9483f907c51e053f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/***************************************************************************
 *             __________               __   ___
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 *
 * Copyright (C) 2018 by Marcin Bukat
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include <stdlib.h>
#include <sys/mount.h>
#include <string.h>
#include "config.h"
#include "disk.h"
#include "usb.h"
#include "sysfs.h"
#include "power.h"

//#define LOGF_ENABLE
#include "logf.h"

static bool adb_mode = false;

#ifdef HAVE_MULTIDRIVE
void cleanup_rbhome(void);
void startup_rbhome(void);
#endif

/* TODO: implement usb detection properly */
int usb_detect(void)
{
    return power_input_status() == POWER_INPUT_USB_CHARGER ? USB_INSERTED : USB_EXTRACTED;
}

void usb_enable(bool on)
{
    logf("usb enable %d %d\n", on, adb_mode);

    /* Ignore usb enable/disable when ADB is enabled so we can fireup adb shell
     * without entering ums mode
     */
    if (!adb_mode)
    {
        sysfs_set_int("/sys/class/android_usb/android0/enable", on ? 1 : 0);
    }
}

/* This is called by usb thread after usb extract in order to return
 * regular FS access
 *
 * returns the # of successful mounts
*/
int disk_mount_all(void)
{
    const char *dev[] = {"/dev/mmcblk0p1", "/dev/mmcblk0"};
    const char *fs[] = {"vfat", "exfat"};

    sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/lun/file", "");

    for (int i=0; i<2; i++)
    {
        for (int j=0; j<2; j++)
        {
            int rval = mount(dev[i], PIVOT_ROOT, fs[j], 0, NULL);
            if (rval == 0 || errno == -EBUSY)
            {
                logf("mount good! %d/%d %d %d", i, j, rval, errno);
#ifdef HAVE_MULTIDRIVE
                startup_rbhome();
#endif
                return 1;
            }
         }
    }

    logf("mount failed! %d", errno);
    return 0;
}

/* This is called by usb thread after all threads ACKs usb inserted message
 *
 * returns the # of successful unmounts
 */
int disk_unmount_all(void)
{
#ifdef HAVE_MULTIDRIVE
    cleanup_rbhome();
#endif

    if (umount(PIVOT_ROOT) == 0)
    {
        sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/lun/file", "/dev/mmcblk0");
        logf("umount_all good");
        return 1;
    }

    logf("umount_all failed! %d", errno);
#ifdef HAVE_MULTIDRIVE
    startup_rbhome();
#endif

    return 0;
}

void usb_init_device(void)
{
    char functions[32] = {0};

    /* Check if ADB was activated in bootloader */
    sysfs_get_string("/sys/class/android_usb/android0/functions", functions, sizeof(functions));
    adb_mode = (strstr(functions, "adb") == NULL) ? false : true;

    usb_enable(false);

    if (adb_mode)
    {
        sysfs_set_string("/sys/class/android_usb/android0/functions", "mass_storage,adb");
        sysfs_set_string("/sys/class/android_usb/android0/idVendor", "18D1");
        sysfs_set_string("/sys/class/android_usb/android0/idProduct", "D002");
    }
    else
    {
        sysfs_set_string("/sys/class/android_usb/android0/functions", "mass_storage");
        sysfs_set_string("/sys/class/android_usb/android0/idVendor", "C502");
        sysfs_set_string("/sys/class/android_usb/android0/idProduct", "0029");
    }

    sysfs_set_string("/sys/class/android_usb/android0/iManufacturer", "Rockbox.org");
    sysfs_set_string("/sys/class/android_usb/android0/iProduct", "Rockbox media player");
    sysfs_set_string("/sys/class/android_usb/android0/iSerial", "0123456789ABCDEF");
    sysfs_set_string("/sys/class/android_usb/android0/f_mass_storage/inquiry_string", "Rockbox 0100");
}