Conversation
Problem: Audio artifacts/distortion on 44.1 kHz sample rate family due to MCLKOUT stuck at 12 MHz instead of following calibrated PLL frequencies. Root cause: Clock multiplexer CLK_I2S0_8CH_TX was not being switched to CLK_I2S0_8CH_TX_SRC parent at boot, remaining on default xin_osc0_half (12 MHz). Solution: - Add CLK_I2S0_8CH_TX to assigned-clocks with parent CLK_I2S0_8CH_TX_SRC - Add I2S0_8CH_MCLKOUT to assigned-clocks with parent MCLK_I2S0_8CH_TX - Add rockchip,no-fractional-divider property to prevent fractional divider selection - Remove MCLKOUT management from driver (managed via device tree only) Clock path now matches kernel 5.10 behavior: PLL_GPLL → TX_SRC (calibrated) → CLK_TX → MCLK_TX → MCLKOUT Verified working: - 44.1 kHz → MCLKOUT = 45.158 MHz ✓ - 48 kHz → MCLKOUT = 49.152 MHz ✓ - 88.2/96/192 kHz all working correctly ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add assigned-clock-rates to external clock mode DTS configuration to ensure CLK_I2S0_8CH_TX properly switches to i2s0_mclkin parent at boot. Without this fix, CLK_I2S0_8CH_TX remains on default xin_osc0_half parent, preventing external clock mode from working. In external mode: - External oscillators (22.579 MHz / 24.576 MHz) provide MCLK - Driver switches between them via freq-domain-gpios based on sample rate - CLK_I2S0_8CH_TX must use i2s0_mclkin as parent for this to work Files updated: - rv1106_ext-ipc.dtsi (MAX variant) - rv1106_512_ext-ipc.dtsi (512MB variant) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Enable DWC3 controller by changing status from disabled to okay - Fix USB2PHY driver to handle missing main IRQ gracefully - Add support for PHY_MODE_USB_HOST_HS/FS/LS modes for kernel 6.1 - Fix fallthrough issue causing USB PHY to enter invalid mode - Enhance USB2PHY tuning for better high-speed detection - Improve signal integrity for USB devices on kernel 6.1 This fixes USB audio device detection and enumeration issues when upgrading from kernel 5.10 to 6.1 on RV1106 platform. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added USB2PHY driver fixes for proper IRQ handling - Enhanced PHY mode support for USB_HOST_HS/FS/LS modes - Fixed fallthrough bug in mode switching - Added kernel 6.1 specific USB2PHY tuning parameters - Resolved USB speed negotiation issues for audio devices 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Eliminated ~200 lines of duplicated DSD/PCM switching code - Created rockchip_i2s_tdm_handle_dsd_switch() unified function - Removed temporary //+++ markers and fixed formatting - Optimized debug logging (dev_info -> dev_dbg for non-critical messages) - Preserved all functionality: PLL/EXT clocks, PCM/DSD, mute/automute, volume control - Maintained DSD bit swap and physical pin swap capabilities - Successfully compiled and tested without breaking changes Code is now cleaner, more maintainable, and production-ready. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changes included: 1. Fixed PCM noise in EXT mode by preventing DSD routing from affecting PCM data 2. Updated I2S driver with extensive debugging and clock handling improvements 3. Modified kernel configuration and patches for proper audio support Key fix: Modified rockchip_i2s_tdm_handle_dsd_switch() to apply DSD routing only when DSD is being enabled, preventing PCM channel corruption in EXT mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add USBtoI2S button to web interface with unique purple style - Implement USB mode switching via web (host/gadget) - Remove usb-mode-switch script - not needed anymore - Add S00usbmodules init script to load USB modules on boot based on mode - Update post-build.sh to strip and remove duplicate external toolchain libraries (libstdc++, libgcc_s, libatomic, libgfortran, libgomp) - saves ~28MB - Add uac2_router package with S98uac2 for UAC2 gadget management - Update ALSA scripts to properly stop services using sh -c '/etc/init.d/S95*' - Fix I2S TDM DSD routing and BCLK calculation for UAC2 router - Add dwc3_gadget.ko custom module for USB gadget mode - Add dwc3_host.ko custom module for USB host mode - Use standard dwc3-of-simple.ko from kernel for both modes - Add USBtoI2S state file persistence across reboots - Web button shows loading spinner and locks/unlocks USB-I2S toggle - Button stays active after enable and deactivates on player switch - USB modules load based on /etc/usb_to_i2s.state file at boot - Fix external toolchain library duplication issue in /lib and /usr/lib
- OTP is identical on all devices, cannot use for unique MAC - Use Flash ID from /dev/mtd0 (NAND flash chip ID) - First 4 bytes of flash = unique identifier per chip - MAC format: BE10E0:74:ce:c4:XX:XX (last 2 bytes from random) - Flash ID is factory-programmed and survives reflashing
- Read first 6 bytes from /dev/mtd0 for unique flash ID - Use first 3 bytes from flash + 2 random bytes for NIC - Format: BE10E0:74:ce:c4:XX:XX (12 hex chars with colons) - Properly handle hexdump output with tr -d to remove spaces
- Use first 6 bytes from Flash ID for NIC (no random bytes) - MAC address: BE10E0:74:ce:c4:1f:6d (all from flash) - MAC remains constant after reflashing firmware - Removed random byte generation for consistent addresses
- No factory unique ID available on Luckfox Pico Max - Flash ID is identical on all boards - OTP is identical on all boards - CPU Serial is zeros - Solution: Generate random MAC on first boot - Save to /data/ethaddr.txt (persists in UBI rootfs) - File survives reflashing firmware - Same MAC address across reboots after first generation
- Extract Serial part: dec0a266340399cf → 0a266340399cf - Use first 12 hex chars from Serial for NIC - Generate MAC: BE10E0:0a:26:63:40:39:9c:f - Save to both U-Boot env and /data/ethaddr.txt - MAC is unique per CPU and persists through reflashing - No more random bytes!
…actor I2S/TDM driver (rockchip_i2s_tdm.c): - Add seamless_transition_active flag to keep MCLK running during frequency switches, eliminating ~6.7ms suspend/resume delay - Add active_playback pointer to track substream for DSD meander fill - DSD TRIGGER STOP: keep I2S/BCLK/DMA running, fill DMA with 0x55 meander pattern instead of stopping stream - DSD TRIGGER START: start only DMA/XFER (I2S already running in DSD) - Fix calculate_dsd_bclk(): proper BCLK per format type (U8/U16/U32) instead of raw sample_rate passthrough - PLL/SRC tolerance: skip unnecessary clk_set_rate if within ±100Hz/±1kHz - Cross-domain glitch fix: disable MCLK before PLL domain switch, re-enable after PLL is stable - DSD mute: fill buffer with 0x55 (meander) instead of 0x00 - Add ktime timing instrumentation to DSD switch, params, trigger - Remove static 50ms/500ms msleep delays from DSD switch path New package: buffer_daemon - Buildroot package for buffer management daemon with init script Kernel & DTS: - Enable CONFIG_ROCKCHIP_CPUINFO in linux.config for serial number access - Add nvmem serial-number cell to rv1106_ext.dts and rv1106_pll.dts System scripts: - S01RkLunch: simplify MAC generation (remove broken multi-fallback code), read /data/ethaddr.txt or generate from last 3 bytes of CPU serial - usb_to_i2s.sh/usb_unlock.sh: use ln -sf, run statusmonitor in background Web UI: - Rename i2s.php → handle_i2s.php - I2S modal: compact layout (300px), scrollbar, reduced font/padding sizes - CSS: remove per-toggle selector blocks (moved to JS), remove dissolve animation - JS: add 'leftjust_title' key to all 5 language dictionaries - LEFTJUST sysfs hook commented out (driver not yet supporting it) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
calculate_dsd_bclk() was returning raw sample_rate (~88-706 kHz) instead of the actual DSD bit clock. Roon passes PCM-equivalent sample rates via uac2_router, not native DSD bit rates. BCLK = sample_rate * bits_per_word: DSD_U32_LE: 88200 * 32 = 2,822,400 Hz (DSD64) DSD_U32_LE: 176400 * 32 = 5,644,800 Hz (DSD128) DSD_U32_LE: 352800 * 32 = 11,289,600 Hz (DSD256) DSD_U32_LE: 705600 * 32 = 22,579,200 Hz (DSD512) Without this fix div_bclk was computed as ~256 instead of ~8, resulting in BCLK ~256x too slow and completely wrong I2S timing in DSD mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two fixes for DSD frequencies in the 48kHz family
(DSD64/48=3.072MHz, DSD128/48=6.144MHz, etc.):
1. div_lrck is now derived from DSD format word size, not
hardcoded to 32. Relationship: LRCK = BCLK / div_lrck = sample_rate,
so div_lrck = bits_per_word:
DSD_U8: div_lrck = 8
DSD_U16_LE/BE: div_lrck = 16
DSD_U32_LE/BE: div_lrck = 32 (unchanged, primary Roon format)
2. Expected MCLK check now accounts for both frequency families
and mclk_multiplier:
44.1kHz grid: 22,579,200 Hz (x512) / 45,158,400 Hz (x1024)
48kHz grid: 24,576,000 Hz (x512) / 49,152,000 Hz (x1024)
Previously the check was hardcoded to 22,579,200 Hz only,
producing false warnings for every 48kHz DSD stream.
Note: calculate_dsd_bclk (sample_rate * bits_per_word) is already
correct for 48kHz grid — no changes needed there.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rockchip_i2s_tdm.c — calculate_dsd_bclk():
Support two DSD rate conventions from different callers:
A) uac2_router: passes native DSD bit rate (>= 1 MHz) → BCLK = rate
44.1k: 2822400/5644800/11289600/22579200 Hz
48k: 3072000/6144000/12288000/24576000 Hz
B) Roon/ALSA: passes PCM frame rate (< 1 MHz) → BCLK = rate * bits_per_word
DSD_U32_LE 44.1k: 88200*32=2822400 Hz
DSD_U32_LE 48k: 96000*32=3072000 Hz
Previous fix (multiply always) broke the uac2_router path:
2822400*32=90 MHz — completely wrong BCLK.
uac2_router.c — 48kHz DSD family support:
- Add DSD rate constants for 48kHz grid:
DSD64/48=3072000 DSD128/48=6144000
DSD256/48=12288000 DSD512/48=24576000
- is_dsd_rate(): recognize all 8 DSD rates (44.1k + 48k families)
Previously 48kHz DSD was treated as PCM → wrong ALSA format on I2S
- dsd_base_rate(): return DSD64 base rate for the correct family,
used for period_size calculation
- get_dsd_name(): names for all 8 DSD variants
- setup_pcm(): period_size now uses dsd_base_rate() for correct
~0.7ms period regardless of frequency family
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The kernel source at buildroot/output/ is a build artifact (in .gitignore) and should never be tracked. Previous 3 commits (785691f, 9c0a705, part of 979e01f) incorrectly modified it directly. All changes are now applied to the proper location: ext_tree/patches/linux_rv1106.patch. linux_rv1106.patch — calculate_dsd_bclk(): Two-convention DSD BCLK calculation: A) uac2_router: native DSD rate >= 1 MHz -> BCLK = rate (as-is) B) Roon/ALSA: PCM frame rate < 1 MHz -> BCLK = rate * bits_per_word Handles both 44.1kHz and 48kHz DSD families. linux_rv1106.patch — DSD hw_params: - MCLK check accounts for both frequency families and mclk_multiplier (was hardcoded to 22579200 Hz, now derives expected value correctly) - div_lrck derived from format word size (U8=8, U16=16, U32=32) instead of hardcoded 32 — correct for all DSD format types uac2_router.c — already committed in 979e01f, re-staged to confirm. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DLNA Bridge: - New dlna_bridge package: C daemon routes ALSA loopback → HTTP WAV → UPnP renderer - asound.bridge: type route + type multi (I2S + loopback simultaneous output) - Web UI: DLNA Bridge button with settings icon (APrender pattern), swipe-to-hide - handle_dlna.php: SSDP discovery via socket_select non-blocking loop (fix break-on-timeout) - dlna_enable/disable.sh: runtime toggle scripts USBtoI2S 8-channel: - S98uac2: c_chmask=255 (8ch TDM, was 2ch stereo) - uac2_router: I2S_CHANNELS dynamic from UAC2 sysfs (was hardcoded to 2) - usb_to_i2s.sh: switch to asound.8ch + SUBMODE=8ch PCM up to 768kHz (kernel patch): - rockchip_i2s_tdm: all_supported_rate_list constraint in startup (enumerates 705.6/768kHz) - rockchip_i2s_tdm: hw_params rejects PCM when BCLK > MCLK (needs 1024x multiplier) - dummy-codec: rate_max=22579200 covers PCM 768kHz + DSD512 Spotify Connect fix: - nice -n -15 applied directly to librespot (was renice on shell) - --normalisation-gain-type none (eliminates CPU-heavy loudness scan) - --cache-size-limit 12M (was 64M, caused memory pressure on 128MB RAM) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.