-
Notifications
You must be signed in to change notification settings - Fork 4
/
usbms.h
223 lines (194 loc) · 8.04 KB
/
usbms.h
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
KoboUSBMS: USBMS helper for KOReader
Copyright (C) 2020-2024 NiLuJe <[email protected]>
SPDX-License-Identifier: GPL-3.0-or-later
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __USBMS_H
#define __USBMS_H
// Because we're pretty much Linux-bound ;).
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <linux/limits.h>
#include <linux/rtc.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
// Like FBInk, handle math shenanigans...
#include <math.h>
#ifdef __clang__
# if __has_builtin(__builtin_ceilf)
# define iceilf(x) ((int) (__builtin_ceilf(x)))
# endif
# if __has_builtin(__builtin_floorf)
# define ifloorf(x) ((int) (__builtin_floorf(x)))
# endif
#else
# if __STDC_VERSION__ >= 199901L
# define iceilf(x) __builtin_iceilf(x)
# define ifloorf(x) __builtin_ifloorf(x)
# endif
#endif
// I18n
#include <libintl.h>
#include <locale.h>
#include "FBInk/fbink.h"
#include "libue/libue.h"
#include "openssh/atomicio.h"
#include "openssh/bsd-closefrom.h"
#include <libevdev/libevdev.h>
// Fallback version tag...
#ifndef USBMS_VERSION
# define USBMS_VERSION "v1.4.0"
#endif
// Fallback timestamp...
#ifndef USBMS_TIMESTAMP
# define USBMS_TIMESTAMP __TIMESTAMP__
#endif
// Apparently the libevdev version string isn't available anywhere, so, fake it
#define LIBEVDEV_VERSION "1.13.3"
// Gettext
#define _(String) gettext(String)
// Logging helpers
#define LOG(prio, fmt, ...) ({ syslog(prio, fmt, ##__VA_ARGS__); })
// Same, but with __PRETTY_FUNCTION__:__LINE__ right before fmt
#define PFLOG(prio, fmt, ...) ({ LOG(prio, "[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); })
// c.f., fbink_internal.h
#define MAX(X, Y) \
({ \
__auto_type x__ = (X); \
__auto_type y__ = (Y); \
(x__ > y__) ? x__ : y__; \
})
// FBInk always returns negative error codes
#define ERRCODE(e) (-(e))
// We use a specific exit code for early aborts, in order to be able to know whether onboard is usable or not after a failure...
#define USBMS_EARLY_EXIT 86
// c.f., https://github.com/koreader/koreader-base/blob/master/input/input-kobo.h
#define KOBO_USB_DEVPATH_PLUG "/devices/platform/usb_plug" // Plugged into a plain power source
#define KOBO_USB_DEVPATH_HOST "/devices/platform/usb_host" // Plugged into a computer
// c.f., /lib/udev/rules.d/kobo.rules
#define KOBO_USB_DEVPATH_FSL "/devices/platform/fsl-usb2-udc" // OK
#define KOBO_USB_MODALIAS_CI "platform:ci_hdrc" // OK
#define KOBO_USB_DEVPATH_UDC "/devices/platform/soc/5100000.udc-controller" // OK
#define KOBO_USB_DEVPATH_MTK "/devices/platform/11211000.usb" // OK
// It sure would be nice if the kernel was recent enough that we had the `function` devattr in there...
#define KOBO_USB_GADGET_STATE_MTK "/sys/class/udc/11211000.usb/state"
char* NTX_KEYS_EVDEV = NULL;
#define NXP_BATT_CAP_SYSFS "/sys/class/power_supply/mc13892_bat/capacity"
#define SUNXI_BATT_CAP_SYSFS "/sys/class/power_supply/battery/capacity"
#define MTK_BATT_CAP_SYSFS "/sys/class/power_supply/bd71827_bat/capacity"
#define CILIX_CONNECTED_SYSFS "/sys/class/misc/cilix/cilix_conn"
#define CILIX_BATT_CAP_SYSFS "/sys/class/misc/cilix/cilix_bat_capacity"
const char* BATT_CAP_SYSFS = NULL;
// NOTE: On sunxi, the CM_USB_Plug_IN ioctl is currently broken (it's poking at "mc13892_bat" instead of "battery"),
// so, rely on sysfs ourselves instead...
#define SUNXI_BATT_STATUS_SYSFS "/sys/class/power_supply/battery/status"
#define MTK_BATT_STATUS_SYSFS "/sys/class/power_supply/bd71827_bat/status"
const char* BATT_STATUS_SYSFS = NULL;
bool (*fxpIsUSBPlugged)(int, bool) = NULL;
// These, on the other hand, are only available on Mk. 7+
#define NXP_CHARGER_TYPE_SYSFS "/sys/class/power_supply/mc13892_charger/device/charger_type"
#define SUNXI_CHARGER_TYPE_SYSFS "/sys/class/power_supply/charger/device/charger_type"
// Finally, we're also starting to see more standard stuff... (e.g., on Mk. 10)
#define STD_CHARGER_TYPE_SYSFS "/sys/class/power_supply/ac/device/charger_type"
#define MTK_CHARGER_TYPE_SYSFS "/sys/class/power_supply/bd71827_bat/charger_type"
// For ref., on mainline w/ @akemnade's driver: /sys/class/power_supply/rn5t618-usb/usb_type
const char* CHARGER_TYPE_SYSFS = NULL;
// For the weird standalone USB-C controller found on sunxi & Mk. 9...
// Ironically, it doesn't appear to do much on Mk.9, at least as far as cable sense is concerned...
#define SUNXI_USBC_PLUG_SYSFS_FMT "/sys/devices/virtual/input/input%s/USB_PLUG"
char* USBC_PLUG_SYSFS = NULL;
char* USBC_EVDEV = NULL;
// With the BD71828 PMIC, the battery status *may* report Discharging while plugged in,
// instead, the PMIC exports a dedicated power_supply named "usb" whose online entry we can check...
#define ROHM_USB_ONLINE_SYSFS "/sys/class/power_supply/usb/online"
const char* USB_ONLINE_SYSFS = NULL;
#define FL_INTENSITY_SYSFS "/sys/class/backlight/mxc_msp430.0/actual_brightness"
// Because MXCFB_WAIT_FOR_UPDATE_COMPLETE is unreliable on a few NTX boards...
int (*fxpWaitForUpdateComplete)(int, uint32_t) = NULL;
// Internal storage
#define KOBO_PARTITION "/dev/mmcblk0p3"
#define KOBO_MOUNTPOINT "/mnt/onboard"
// External storage
#define KOBO_SD_PARTITION "/dev/mmcblk1p1"
#define KOBO_SD_MOUNTPOINT "/mnt/sd"
// The timestamp file that the Kobo app creates, which Nickel uses to resync date/time after USBMS sessions
#define KOBO_EPOCH_TS KOBO_MOUNTPOINT "/.kobo/epoch.conf"
// Same idea, but for the timezone
#define KOBO_TZ_FILE KOBO_MOUNTPOINT "/.kobo/timezone.conf"
#define SYSTEM_TZPATH "/etc/zoneinfo"
#define KOBO_TZPATH "/etc/zoneinfo-kobo"
#define SYSTEM_TZFILE "/etc/localtime"
// List of exportable partitions
typedef enum
{
PARTITION_NONE = -1,
PARTITION_INTERNAL = 0,
PARTITION_EXTERNAL
} PARTITION_ID_E;
typedef struct
{
PARTITION_ID_E id;
const char* name;
const char* device;
const char* mountpoint;
} USBMSPartition;
typedef struct
{
FBInkConfig fbink_cfg;
FBInkOTConfig ot_cfg;
FBInkOTConfig countdown_cfg;
FBInkOTConfig icon_cfg;
FBInkOTConfig msg_cfg;
FBInkState fbink_state;
int fbfd;
int ntxfd;
} USBMSContext;
// c.f., arch/arm/mach-imx/imx_ntx_io.c or arch/arm/mach-sunxi/sunxi_ntx_io.c in a Kobo kernel
#define CM_USB_Plug_IN 108
#define CM_CHARGE_STATUS 204 // Mapped to CM_USB_Plug_IN on Mk. 7+...
#define CM_GET_BATTERY_STATUS 206
#define CM_FRONT_LIGHT_SET 241
// For the "checking for custom usb gadget" scandir
#define DEFAULT_NICKEL_USB_GADGET "g1"
static int
is_custom_gadget(const struct dirent* dir)
{
// We only care about directories
if (dir->d_type != DT_DIR) {
return 0;
}
// Skip . & ..
if (dir->d_name[0] == '.') {
return 0;
} else {
return strcmp(DEFAULT_NICKEL_USB_GADGET, dir->d_name) != 0;
}
}
#endif // __USBMS_H