Skip to content
Merged
2 changes: 2 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,5 @@ Fetched at build time, never committed:
change or, for new files, as their headers say. drivers/display/panel/hakios.s6e3ha8_star2.h is data (the Galaxy S9+ panel's
dimming tables) made by tools/extract-star2-panel.py from the tables of Samsung's GPL-2.0 kernel as carried in his Apollo tree;
no code of that kernel is in it.
- Nils (github.com/dwaris): his commits to this repository, from 12 November 2026 (drivers/audio/abox/hakios.exynos_abox.c,
drivers/audio/codec/hakios.max98512.c), under the licence of the files they change.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ from your own device.
the Mali and the buses, the speakers' tone, Location Services and its tools, the GNSS bring-up of the BCM4775
(`docs/gnss.md`, `/dev/hakios-gnss`, `gnsstool`), a kept data volume that survives a reset, and a long list of fixes to
the build and the user space. His commits are in the history under his name. Thank you, Anan.
- **Nils** ([@dwaris](https://github.com/dwaris)), a Galaxy S9+ owner and one of the installer's testers. Two fixes for the
speakers found on his own phone: the first sound no longer lost when the stream starts before the amplifiers' driver has
registered, and the MAX98512's enable given a moment before it is read back, with a pause between a bus transfer's
retries. His commits are in the history under his name. Thank you, Nils.

## Licenses and the legal side

Expand Down
4 changes: 2 additions & 2 deletions devices/manifest.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ device blazer

device starlte
repository https://github.com/Scion-Project/scion-starlte.git
revision 09fd06658ec40b6b220cc975e7294b2b6c59ef0f
revision 87be95cc732570d256a6d6d462881945be671aca

soc exynos9810
path socs/exynos9810
Expand Down Expand Up @@ -67,7 +67,7 @@ uefi hakios-uefi

device star2lte
repository https://github.com/Scion-Project/scion-star2lte.git
revision 4ff9524dab195c060b161abc170785cd98830b18
revision ee5bfa3678de0f0459d4c84429171987fdb446e1

device crownlte
repository https://github.com/Scion-Project/scion-crownlte.git
Expand Down
2 changes: 1 addition & 1 deletion docs/devices/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Every device with a repository, and how far each part of it works. A device of y
| [Pixel 10](frankel.md) | `lga` | partly | no | no | partly | no | partly | no | no | | | | no | no | no | | no | no | |
| [QEMU virt (aarch64)](qemu.md) | `none` | yes | yes | yes | | no | yes | yes | | | | | | | | yes | | | |
| [POCO X5 Pro 5G](redwood.md) | `sc7280` | yes | yes | yes | yes | yes | yes | yes | partly | yes | yes | partly | yes | no | partly | | partly | | |
| [Galaxy S9+](star2lte.md) | `exynos9810` | no | no | no | no | no | no | no | no | no | no | no | no | no | no | | no | no | |
| [Galaxy S9+](star2lte.md) | `exynos9810` | yes | yes | partly | yes | partly | yes | partly | yes | partly | partly | partly | yes | partly | no | | yes | yes | partly |
| [Galaxy S9](starlte.md) | `exynos9810` | yes | yes | partly | partly | partly | yes | partly | yes | yes | partly | partly | yes | partly | no | yes | partly | yes | partly |

An empty cell is a part nobody has looked at on that device yet.
Expand Down
31 changes: 16 additions & 15 deletions docs/devices/star2lte.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@

| Part | State | |
|---|---|---|
| display | no | UEFI's framebuffer, 1440 x 2960 at 0xCC000000 as on the S9, from the S9's UEFI borrowed (mkimage.sh -U); not seen on an S9+; the brightness driver of the S9 left out (this phone's panel is s6e3ha8_star2, another variant); fb_flip and fb_dpp (the same DECON and DPP): written for the S9, not seen here |
| cpu | no | A55s 2 and 3 (cpus=2 bootcpu=2, the default), the S9's; the M3s (m3_prep=3) and the clusters' clocks (cpufreq_lit, cpufreq_gov): the same SoC, not seen on an S9+ |
| touch | no | Samsung S6SY761 (sec_ts, firmware y761_star2) at 0x48 on USI03's HSI2C, its IRQ gpa1-0 and supplies LDO35/LDO43 as on the S9 (s6sy761=1): not seen on an S9+ |
| buttons | no | power gpa2-4, volume gpa0-3/gpa0-4, Bixby gpa0-6, the S9's pins (exynos_keys=1): not seen on an S9+ |
| storage | no | UFS read through the loader and the S9's UEFI (ufs=2), the same controller; /private/var in USERDATA (ufs_write=1 var_hfs=ufs_USERDATA_data): not seen on an S9+ |
| gpu | no | Mali-G72 MP18, the same SoC (mali=N): not seen on an S9+ |
| audio | no | ABOX and the MAX98512s at the S9's addresses, codec CS47L93 as on the S9 (abox=N, max98512=N): not seen, not heard on an S9+ |
| battery | no | the MAX77705's gauge and charger, read only, with this phone's battery: 3500 mAh (fuel gauge capacity 3303), its own thermistor table (max77705=1): not seen on an S9+ |
| wifi | no | BCM4361 on PCIe channel 0 as on the S9 (wifi_pcie=N, brcmfmac=N; firmware from the phone): not seen on an S9+ |
| bluetooth | no | BCM4361's Bluetooth on UART_BT as on the S9 (bt=N): not seen on an S9+ |
| display | works | the S6E3HA8 (star2 A3 S0 panel, ID 911443) with its own gamma tables from Apollo (scion-kernel 4c4bf73), brightness from iOS (brightness_bridge=1), 1440 x 2960; SpringBoard drawn by the GPU (gpu below) |
| cpu | works | all eight cores (cpus=8 bootcpu=2); the M3s at Apollo's limits with the S2MPS18 OCP (cpufreq_ocp=1): 2314 MHz for 1-2 online, 2106/1924 MHz for more (cpufreq_gov_big_*), A55s to 1950 MHz; MIF at Samsung's starting rates (bus_max=1), never above Apollo's |
| touch | works | S6SY761 (sec_ts, y761_star2) at 0x48 on USI03's HSI2C (s6sy761=1): the phone is used by touch |
| buttons | partly | power gpa2-4, volume gpa0-3/gpa0-4, Bixby gpa0-6 (exynos_keys=1): read at every boot (released); each button's action in iOS not checked one by one |
| storage | works | UFS through the loader (ufs=2), written (ufs_write=1): the system image on SYSTEM (system_apfs=ufs_SYSTEM), /private/var an HFS Plus volume in USERDATA kept between boots (var_hfs=ufs_USERDATA_data), flushed every 5 s (var_sync) |
| gpu | partly | Mali-G72 MP18 up to step 9 (HakiosMali); the window server draws with it through Mesa's panfrost (userland GL=1, lib/libhakios.gl.dylib, Mesa in the system image); occasional drawing artefacts seen; no Metal |
| audio | partly | ABOX and the two MAX98512s (0x39/0x3A, revision 0x41): the speakers play, without ABOX's CPU (calliope) and without DSM, so little bass; the S9+'s own DSM tuning is in firmware/ for when it is; microphone, earpiece and headset not checked |
| battery | works | the MAX77705's gauge and charger, read only (max77705=1): this phone's 3303 mAh battery, level, current and temperature in iOS, charging seen |
| wifi | works | BCM4361 on PCIe (wifi=1, firmware in fw/): scans, joins, WPA2, and joins known networks by itself after a boot (scion-kernel 06d88e6: keybagd's first-unlock notice; 1bd1bcd: IO80211's RSSI bounds); SSH over it |
| bluetooth | partly | BCM4361's Bluetooth on UART_BT as on the S9 (bt=7, CONFIG_BT=7): Broadcom's patch, 4 Mbaud, the EFS address, seen on an S9+ (SM-G965N), 12 November; iOS (userland BT=1, the default since scion-kernel 6effc65): BlueTool's D22AP boot and init scripts through com.apple.uart.bluetooth (result 0), bluetoothd's stack STACK_READY and powered on, an active LE scan hearing advertisers, seen on that phone with the jobs loaded by hand, 12 November; Settings, pairing and audio not yet seen on an S9+ (../starlte/BLUETOOTH.md); since build 28 in the image itself (BT=1 with the chip's patch in fw/), discoverable as the device's name ("iPhone", src/devname.c); pairing and audio not yet seen |
| cellular | no | |
| haptic | no | the MAX77705's haptic block and PWM channel 1 (max77705_haptic=1), at the S9's strength (at most 70 % duty; Samsung drives this motor harder): not felt on an S9+ |
| thermal | no | the TMU (tmu=N), the same SoC; the CPU governor's limits (cpufreq_gov=1): not seen on an S9+ |
| camera | no | rear: S5K2L3 wide (0x20) and S5K3M3 tele (0x5A, the S9 has none); front: S5K3H1 (0x6A), as the S9's: the S9's front-camera stages (cam_s9=N) may apply; nothing tried on an S9+; no driver for the tele |
| torch | no | the S2MPB02's flash block, as on the S9 (torch=N): not seen on an S9+ |
| usb | no | USB serial log and console (usb_gadget=5 max77705_usbsw=1), the same PHY and MUIC: not seen on an S9+ |
| haptic | partly | the MAX77705's motor for iOS (/dev/hakios-haptic, max77705_haptic=1); backboardd's button haptics come up; strength not tuned for this motor |
| thermal | works | the TMU publishing kern.hakios.temp every second (tmu=3), the run ending at 110 C or 60 C on the battery |
| camera | partly | rear S5K2L3 (0x10, HSI2C0), front S5K3H1 and telephoto S5K3M3 (0x2D, I2C_CAM2) stream (cam=5); S9+ colour and focus (AK737x); the telephoto at 2x; OIS not driven; no ISP-quality processing |
| torch | partly | the S2MPB02's flash block (torch=3), shared with the camera's rails: driven from iOS, brightness steps not checked |
| sensors | partly | the sensor hub in the BCM4775 (shub=6): accelerometer at position 7 and gyro with this phone's EFS calibration (shub_gyro_cal), the hub set up at every boot; light, magnetometer, barometer and steps not finished; GNSS in the same chip not running yet (docs/gnss.md) |
| usb | works | USB serial log and console (usb_gadget=5 max77705_usbsw=1): every boot's log is read this way |

The state is what has been seen on this device, written down in `devices/star2lte/device.conf`; a part the table does not name has not been looked at.
14 changes: 13 additions & 1 deletion drivers/audio/abox/hakios.exynos_abox.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ static bool area_kept; /* RDMA0 did not say it stopped: the mem
static const struct hakios_abox_amp *volatile amp_hook;
static const struct hakios_abox_amp *amp_running; /* the one started, which is the one stopped */
static unsigned amp_failures; /* starts that failed this run (amps_start) */
static bool amp_given_up, amp_none_said;
static bool amp_given_up, amp_none_said, amp_waited;

void
hakios_abox_set_amp(const struct hakios_abox_amp *amp)
Expand All @@ -378,6 +378,18 @@ amps_start(void)
if (amp_running != NULL || amp_given_up) {
return;
}
if ((amp == NULL || amp->start == NULL) && !amp_waited) {
/*
* The amplifiers' driver may register a moment after the first sound: it is waited for, up to a second, once in
* a run. Not at every sound: on a machine or a configuration where no such driver ever registers, each start
* would otherwise hold the stream's thread for that second (this is called again at the next sound).
*/
amp_waited = true;
for (int wait = 0; wait < 100 && (amp_hook == NULL || amp_hook->start == NULL); wait++) {
delay_for_interval(10, NSEC_PER_MSEC);
}
amp = amp_hook;
}
if (amp == NULL || amp->start == NULL) {
/* (looked for again the next time: a driver may register later) */
if (!amp_none_said) {
Expand Down
9 changes: 9 additions & 0 deletions drivers/audio/codec/hakios.max98512.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ raw_write(const struct amp *a, uint16_t at, uint8_t value)
for (int i = 0; i < TRIES && error != 0; i++) {
uint8_t buf[3] = { (uint8_t)(at >> 8), (uint8_t)at, value };

if (i > 0) {
delay_for_interval(1, NSEC_PER_MSEC);
}
lck_mtx_lock(&bus_lock);
error = hakios_hsi2c_message(&bus, a->addr, false, buf, sizeof(buf), true);
lck_mtx_unlock(&bus_lock);
Expand All @@ -327,6 +330,9 @@ raw_read(const struct amp *a, uint16_t at, uint8_t *value)
for (int i = 0; i < TRIES && error != 0; i++) {
uint8_t buf[2] = { (uint8_t)(at >> 8), (uint8_t)at };

if (i > 0) {
delay_for_interval(1, NSEC_PER_MSEC);
}
lck_mtx_lock(&bus_lock);
error = hakios_hsi2c_message(&bus, a->addr, false, buf, sizeof(buf), false);
if (error == 0) {
Expand Down Expand Up @@ -380,6 +386,9 @@ write_checked(const struct amp *a, uint16_t reg, uint8_t value, uint8_t check, b
if (r->check == 0) {
return true; /* SOFT_RESET: it clears itself; reset() looks whether it took */
}
if (reg == GLOBAL_SHDN && (value & 1)) {
delay_for_interval(2, NSEC_PER_MSEC);
}
if (error == 0) {
error = raw_read(a, at, &back);
}
Expand Down
Loading