From 06edb8deb96d6d9f1f9b244e577d1b0058d68c84 Mon Sep 17 00:00:00 2001 From: dwaris Date: Wed, 11 Nov 2026 22:18:06 +0100 Subject: [PATCH 1/6] drivers: audio: abox: await amp_hook registration in amps_start During early boot, ABOX's UAIF1 stream can start before the speaker amplifier driver completes its identify/probe and registers via hakios_abox_set_amp(). Poll with a bounded retry (up to 1 s) in amps_start() before giving up on the speaker amplifiers. (cherry picked from commit 761450a58d0f627d7a8986294d162fbb0ad2392c) --- drivers/audio/abox/hakios.exynos_abox.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/audio/abox/hakios.exynos_abox.c b/drivers/audio/abox/hakios.exynos_abox.c index 487ba603b..a113845d3 100644 --- a/drivers/audio/abox/hakios.exynos_abox.c +++ b/drivers/audio/abox/hakios.exynos_abox.c @@ -378,6 +378,12 @@ amps_start(void) if (amp_running != NULL || amp_given_up) { return; } + if (amp == NULL || amp->start == NULL) { + 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) { From 798a7594ef72ab9ccd1076cc579b82155906f934 Mon Sep 17 00:00:00 2001 From: dwaris Date: Wed, 11 Nov 2026 22:21:10 +0100 Subject: [PATCH 2/6] drivers: audio: codec: max98512: add wake delay and retry backoff for GLOBAL_SHDN Waking the MAX98512 amplifiers out of global shutdown (GLOBAL_SHDN = 1) powers up internal charge pumps and analog stages, during which immediate I2C reads NACK (bus 0x400) and abort the driver. Add a 2 ms wake delay after writing GLOBAL_SHDN = 1 (matching vendor driver usleep_range), and add a 1 ms interval between raw_read and raw_write retries. (cherry picked from commit 6892d35351d9069f60911b1213d8c9d5396abb6a) --- drivers/audio/codec/hakios.max98512.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/audio/codec/hakios.max98512.c b/drivers/audio/codec/hakios.max98512.c index 6180297c2..3a140ba42 100644 --- a/drivers/audio/codec/hakios.max98512.c +++ b/drivers/audio/codec/hakios.max98512.c @@ -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); @@ -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) { @@ -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); } From 3041290057b52cac3afbb7fcc245c4ae90e86fb6 Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 12 Nov 2026 17:04:09 +0000 Subject: [PATCH 3/6] Audio: the wait for the amplifiers' driver happens once in a run, not at every sound 06edb8de (dwaris) lets amps_start() wait up to a second (100 x 10 ms) for the amplifiers' driver to register, which cures the first sound being lost on the S9+ when the stream starts before the MAX98512 driver has registered. amps_start() is called again at every sound while no amplifier runs, and neither amp_given_up nor amp_none_said stops that, so on a machine or a configuration where no amplifiers' driver ever registers each of those calls held the stream's thread for the full second. The wait is now taken once (amp_waited); after it a driver that registers later is still picked up at the next sound, as before his change, without waiting. --- drivers/audio/abox/hakios.exynos_abox.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/audio/abox/hakios.exynos_abox.c b/drivers/audio/abox/hakios.exynos_abox.c index a113845d3..fc8166c69 100644 --- a/drivers/audio/abox/hakios.exynos_abox.c +++ b/drivers/audio/abox/hakios.exynos_abox.c @@ -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) @@ -378,7 +378,13 @@ amps_start(void) if (amp_running != NULL || amp_given_up) { return; } - if (amp == NULL || amp->start == NULL) { + 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); } From f49dd2b5ee95b0a69c581db36c506e141e7b0b6a Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 12 Nov 2026 17:04:09 +0000 Subject: [PATCH 4/6] devices/manifest.conf: starlte and star2lte at their repositories' heads (Anan Jaser's device commits) scion-starlte 87be95cc (pull request 60) and scion-star2lte ee5bfa36 (pull request 3): the S9+'s device.conf as seen running, its own firmware lists and fetch script (no vendor file), which build.sh DEVICE=star2lte of this repository looks for, and the S9's Bluetooth page. The pins were at the commits before those. --- devices/manifest.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/manifest.conf b/devices/manifest.conf index 4af351904..7bf63e830 100644 --- a/devices/manifest.conf +++ b/devices/manifest.conf @@ -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 @@ -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 From 259851665bc4643d90b8c2c85583b3f6f0e8fb21 Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 12 Nov 2026 17:04:09 +0000 Subject: [PATCH 5/6] README, NOTICE: Nils (dwaris) among the contributors, with what was taken --- NOTICE | 2 ++ README.md | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/NOTICE b/NOTICE index 38eae76e6..b65ea273b 100644 --- a/NOTICE +++ b/NOTICE @@ -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. diff --git a/README.md b/README.md index e0c415582..2e810a18d 100644 --- a/README.md +++ b/README.md @@ -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 From 760ac75158317f93247a5f9c6b6d8ecceb0e532c Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 12 Nov 2026 17:11:27 +0000 Subject: [PATCH 6/6] docs: the device pages made again (the S9 and S9+ repositories at their new commits) --- docs/devices/index.md | 2 +- docs/devices/star2lte.md | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/devices/index.md b/docs/devices/index.md index b4ffcd45b..6ad7dbd83 100644 --- a/docs/devices/index.md +++ b/docs/devices/index.md @@ -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. diff --git a/docs/devices/star2lte.md b/docs/devices/star2lte.md index a45be67e7..77e7ee568 100644 --- a/docs/devices/star2lte.md +++ b/docs/devices/star2lte.md @@ -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.