Commit graph

3750 commits

Author SHA1 Message Date
Marcin Bukat
361913fdd2 YP-CP3: make the WM8750 the I2S master
The WM8750 frames its ADC on ADCLRC and its DAC on DACLRC. As the I2S
slave both are inputs, and the rk27xx has a single LRCK, which on the
YP-CP3 evidently does not reach ADCLRC: with the rk27xx as the master,
the recording DMA got exact zeros on most visits to the recording
screen and real samples only by chance, sometimes changing partway
through a visit. That stays so with the codec PLL no longer glitching
the I2S clocks (previous commit); with the codec as the master it does
not happen.

The codec now drives BCLK and both LRCKs itself, and the rk27xx I2S
transmitter and receiver are slaves. The codec's MCLK still comes from
the rk27xx codec PLL at 256 fs, so sample rates stay exact. The
original firmware runs the codec as master too, but off a fixed 12 MHz
in USB mode.

RK27XX_I2S_MCLK says the rk27xx makes the codec's MCLK, apart from
CODEC_SLAVE, which also makes it the I2S master. The YP-CP3 drops
CODEC_SLAVE for RK27XX_I2S_MCLK, and the WM8750 driver sets its master
bit as it does for any codec that is not a slave.

Tested on a YP-CP3: playback, FM radio, the recording screen's peak
meter on every visit, recording from the microphone and from FM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I0dc93d3b2c45fddf61649702a931d11806e78cbf
2026-10-05 22:35:12 +02:00
Marcin Bukat
3b142f45ce rk27xx: fix a -Wundef warning in simulator builds
config.h defines HAVE_STORAGE_FLUSH for the rk27xx Scheme A FTL when
CONFIG_STORAGE has STORAGE_NAND and CONFIG_NAND is NAND_RK27XX. sim.h
undefines CONFIG_NAND but keeps CONFIG_STORAGE, so a simulator for a
NAND target - the iPod nano 2G - evaluated the undefined macro:

  "CONFIG_NAND" is not defined, evaluates to 0 [-Wundef]

Test that it is defined first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Id1e328f08c14d7c5528d29f110fdbb8be68ab2f5
2026-10-01 16:40:13 +02:00
Marcin Bukat
c453f4fa8f rk27xx: name the NAND's FTL scheme in each target's config
CONFIG_RK27XX_FTL selects the FTL a target's NAND uses,
RK27XX_FTL_SCHEME_A or RK27XX_FTL_SCHEME_B. rk27generic and the YP-CP3
are Scheme A, the HM-60x Scheme B. ftl-rk27xx.c mounts the one named;
for Scheme B it maps the drives onto the volumes ID block 1 records:
the system disk from LBA 0, the user volume after the system data
area.

The other rk27xx targets with NAND - HM-801, MA8, MA8C, MA9, MA9C and
iHiFi 760, 770, 770C, 800, 960 - have no confirmed scheme. They drop
the NAND from storage and build only the FTL scheme finder, so users
can report what their device holds and the scheme can then be set.

Only Scheme A flushes at shutdown: Scheme B holds nothing in RAM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I484217b82c6de7316b90b354c012bfbaa263b3dd
2026-10-01 12:15:25 +02:00
Marcin Bukat
0db035d231 rk27generic: expose the NAND as a drive
The NAND holds two volumes, SYS and USER; the split is recorded in the
boot area, so they are separate drives rather than partitions of one.
SYS is hidden: nothing in it is the user's, and deleting or overfilling
it stops the device booting. HAVE_RK27XX_NAND_SYS, documented in the
config and off, brings it back as a drive of its own.

storage.c numbers drives by driver, SD first:

                 default          HAVE_RK27XX_NAND_SYS
   drive 0       SD               SD
   drive 1       NAND USER        NAND SYS
   drive 2                        NAND USER

NUM_DRIVES was 1, which was already wrong for a target whose
CONFIG_STORAGE names both SD and NAND.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ic68921838faef0ff6fd296d43e86ec3a10a091c5
2026-10-01 12:15:25 +02:00
Marcin Bukat
a0c1085f3f rk27xx: add the Scheme A FTL
ftl-rk27xx.c has been four empty stubs since 2010. Fill them in with
the flash translation layer the rk2705/rk2706 original firmware uses,
called Scheme A here to tell it from the log-structured layout of later
firmware. It reads and writes that format exactly as the original
firmware does, so a device keeps working with its original firmware
after Rockbox has written to it.

- ftl-scheme-a.{c,h}: the FTL. The file opens with a description of
  the on-flash format and how the FTL works: the SYS and USER volumes,
  super-blocks and zones, the zone table, the remap log and its mirror,
  the exchange record and the write protocol, power-loss recovery, bad
  blocks. Oddities of the original firmware kept for compatibility are
  marked where they are.
- Parameters that differ between firmware builds - the zone reserve
  base, the system zone offset, the format flag - are recovered from
  the media at mount and checked against its structure; a mount that
  cannot confirm them is read-only. A mount that would have to repair
  the remap log while not allowed to write fails rather than serve
  wrong data.
- ftl-rk27xx.c: the storage glue. It finds the boot area's ID block,
  which records where SYS ends, and mounts the FTL.
- ata-nand-rk27xx.c: a drive per volume. SYS holds the original
  firmware - on a Rockbox device including the BASE.RKW that chainloads
  the bootloader - and nothing of the user's, so it is a drive only when
  the target defines HAVE_RK27XX_NAND_SYS. Capacity comes from the FTL's
  tables, not from raw block geometry.
- config.h: HAVE_STORAGE_FLUSH for the rk27xx NAND. The FTL holds up to
  three part-written pages in RAM; storage_flush() commits them at
  shutdown and ROLO.

Writing is opt-in: without FTL_ALLOW_WRITE the FTL mounts read-only and
never writes the flash, not even a repair the mount could make.

Two bugs of the original firmware are not reproduced. A write starting
before a page held part-written in RAM and running through it left two
buffers holding that page, and the older one was later programmed over
the newer data; such a write now flushes the held page first. And its
bad-block marker took two of its three metadata bytes from the stack,
which can make a retired block look like a remap-log block; the marker
is now written in full.

Tested in a host simulator on NAND images of a Samsung YP-CP3 and a
generic rk2705, against the original firmware's FTL object run under
qemu-arm: identical traces of every read, program and erase, with a
hash of the data each program writes, over mounting and reading, random
writes with every sector verified, a power cut at every flash operation
of a write, and a program or erase failure at every one.

On a generic rk2705: the read-only mount reports the layout and
capacities the original firmware does and every file's MD5 matches; a
write test passes 8192/8192 across a remount and a power cycle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I573d944389cefb456ecf38c6c7b91bebfe0fe377
2026-10-01 12:15:25 +02:00
Marcin Bukat
53bc6abc97 rk27xx: fill in the NANDC BCH register definitions
BCHCTL bit 13 and the whole of BCHST were marked unknown. Both are
needed by any driver that reads NAND through the controller's ECC
engine: a read has to be able to report an uncorrectable sector, and MLC
parts want a refresh once a sector needs enough correction.

  BCHCTL bit 13   ECC strength, clear = t=8, set = t=14 (both m=13,
                  poly 0x25af). Established by decoding both modes
                  against real media until the stored ECC bytes
                  reproduced.

  BCHST  bit 0    result valid
         bit 2    error - uncorrectable when set together with bit 0
         bits 6:3 number of corrected bit errors

Taken from the rk2705 NAND bootloader's ECC read loop:

    tst r0,#1 ; tst r0,#4     both set -> sector uncorrectable
    lsl r0,#25 ; lsr r0,#28   -> (BCHST >> 3) & 0xf, corrected bits
    cmp r0,#3                 >= 3 triggers a block refresh

The threshold agrees with MlcRefreshHook in the Samsung OF's flash.o, so
two independent firmwares say the same thing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I1e356d5510827b46035f1d7d4a2cc69f4e83f43f
2026-10-01 10:28:03 +02:00
Marcin Bukat
89e9ade855 rk27generic: FM radio screen keys, tuner noted as an RDA5807P
The FM screen had no actions for the rk27xx generic keypad; give it those
its keymap already maps (menu, play, stop, exit) in radio.c.

The board's tuner is an RDA5807P. It keeps being driven as a TEA5767, in
the chip's compatible mode, as the original firmware does: tuning, seek
and the stereo indicator work so, and the RDA mode would bring nothing
here - this variant has no RDS. Say so next to CONFIG_TUNER.

The tuner's audio is on the codec's line input 1: only that line is
powered and mixed in while the radio plays (RK27XX_CODEC_FM_LINE 1). With
line 2 instead the radio is silent.

Tested on the rk27generic board: manual tuning, seek, stereo indicator and
audio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I2135ee484705ff0fce6d88e73288d8ed2aec6c2d
2026-09-30 08:07:47 -04:00
Marcin Bukat
3689292b28 YP-CP3: recording from the microphone and FM radio
- config: HAVE_RECORDING, sources microphone and FM, 8-48 kHz
- wm8751.c: the YP-CP3's own audiohw_set_recsrc(). The rk27xx cannot
  send received samples straight back out, so what is heard of an input
  goes through the codec's analog bypass - the input PGA into the output
  mixers: the radio always, the microphone never. As in the original
  firmware, the radio passes the PGA at +12 dB when only listened to,
  and the microphone - mono, on RINPUT2 - gets +13 dB boost and is
  recorded by the right ADC onto both channels (the original firmware's
  noise gate is left out). The HD300's version assumes the microphone on
  INPUT3 and headphones on OUT1, and switches OUT2 - the YP-CP3's
  headphones - off.
- wm8751.c: the playback-only FM monitor added for the YP-CP3 goes; the
  radio is routed by audiohw_set_recsrc() now, as on the HD300
- wm8751.h: DATSEL, which ADC feeds each channel of the output data

Only partly tested on hardware: FM radio still plays, and the recording
screen's peak meter follows the microphone. Not yet tested: a recorded
file played back, recording FM, recording gain range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I3c25f4333f765d98dddc2fd722c111f8493bbe77
2026-09-29 09:52:13 +02:00
Marcin Bukat
c922ef98c3 YP-CP3: Si4703 FM radio
The YP-CP3's tuner is a Silicon Labs Si470x at I2C address 0x20, an
Si4703 by the RDS the original firmware enables. The firmware drives it
the Si470x way - writes from register 2, reads from 0x0A - starts its
oscillator with TEST1 = 0x8100 and a 500 ms wait before ENABLE, and has
no power or reset line for it.

- config: CONFIG_TUNER SI4700 with RDS, polled (no interrupt line
  needed), and FM radio as an input source
- si4700.c: the YP-CP3 starts the oscillator as the Sansas do
- power-ypcp3.c: tuner power stubs - there is nothing to switch
- the rk27xx tuner I2C glue, and "radio" in the target's configure entry
- wm8751.c: audiohw_set_monitor() for a WM8750 target that plays the
  radio but cannot record (rk27xx has no recording yet). The tuner, on
  LINPUT1/RINPUT1, goes through the input PGA at +12 dB - as in the
  original firmware - into the output mixers, the DAC staying in the mix.
  The existing monitor routing lives in the recording code and switches
  OUT2 off, which is the YP-CP3's headphone output.

Tested on a YP-CP3: stations tune and play at a sane level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ic097fc85dbd7fb71fcc28c97a9d378fa09599e79
2026-09-29 09:47:51 +02:00
Marcin Bukat
a35f344eef YP-CP3: WM8750 audio
The YP-CP3 uses Wolfson WM8750. Headphones are wired on OUT2 and
a headphone amplifier enabled by GPIO F2, active high -
all RE from the original firmware.

The original firmware runs the codec as I2S master in its 12 MHz "USB
mode", fed a fixed 12 MHz MCLK, which puts 44.1 kHz at 44.118. Rockbox
instead makes the rk27xx the master and clocks the codec from the codec
PLL at exactly 256 fs (CODEC_SLAVE, as every other rk27xx target with an
external codec), so the codec's CLOCKING register is its normal-mode
256 fs setting at every rate. 96 kHz is left out: the WM8750 cannot take
it at 256 fs.

- config: HAVE_WM8750, CODEC_SLAVE, rates 8-48 kHz; the WM8750 has
  hardware tone controls, so HAVE_SW_TONE_CONTROLS goes
- ypcp3/wmcodec-ypcp3.c: register writes over the rk27xx I2C driver
- wm8751.c: on the YP-CP3, power on and drive OUT2 instead of OUT1, set
  the volume there, and switch the amplifier with the outputs
- english.lang: the YP-CP3 gets the bass/treble cutoff settings the
  WM8750 brings

Tested on a YP-CP3: playback at 44.1 and 48 kHz on headphones, pitch and
volume correct.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I870038fb6a21a9c26b025e3df7c220fd925f49f6
2026-09-29 09:34:02 +02:00
Marcin Bukat
f7655e226c Samsung YP-CP3: Seiko S-35390A on I2C as RTC
Found in the original firmware by its command-in-address protocol
and bit-reversed data; the original firmware leaves it
in 12-hour mode, which the driver now handles.

Change-Id: I9f4147d3057aaa6aa498a1750cb4e746d69b1be6
2026-09-29 09:30:23 +02:00
Marcin Bukat
0dc08e53a9 S-35390A RTC: bring the driver back, handle 12-hour mode
The S-35390A keeps the hour either as 0-23 or - its default after a
power-on reset - as 0-11 plus a p.m. flag, selected by the 12/24 bit of
status register 1. The driver assumed 24-hour mode and never set it: it
masked the p.m. flag off, so on a chip left in 12-hour mode every
afternoon read as morning, and writing an afternoon time stored an
out-of-range hour.

Read the mode in rtc_init() and convert the hour both ways. The chip's
mode is left alone, as another firmware on the same player may depend on
it - the Samsung YP-CP3's original firmware runs it in 12-hour mode and
never touches the bit. If the status register cannot be read, the driver
keeps assuming 24-hour mode, as before.

Upstream removed the driver with its only users, the Meizu M3/M6 and
Samsung YP-S3 ports (1a33d7990a); the Samsung YP-CP3 needs it, so it
comes back here, with RTC_S35390A and its SOURCES entry.

Also pick the I2C header by CONFIG_I2C, so rk27xx targets can use the
driver; i2c_read()/i2c_write() have the same shape there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I54d8c8cfaa1b88237f6c4b08d2a510ec9fce8ec5
2026-09-29 09:20:12 +02:00
Marcin Bukat
98f162b212 New target: Samsung YP-CP3 (rk27xx)
Scaffolding for a port, starting from the rk27xx generic target: configure
entry 146 (target id 117, model number 132), config/samsungypcp3.h, and
firmware/target/arm/rk27xx/ypcp3/.

- LCD: the rk27xx LCD interface (lcdif-rk27xx.c) with this panel's init
  sequence, from RE. See g#1050. Looks like SPFD5420A 18-bit bus,
  400x240 landscape. It differs from the generic panel's sequence in the
  gamma curve and in not writing VCOM_HV1.

- Backlight: PD4 / PWM0 with the generic board's timing, which the hwstub
  work found to be the same.

- Storage: the microSD slot. Card detect is PC7, active low,
  as on the generic board.

- Keys: the YP-R0's key set - five-way yog, Back, Menu, Rec/User, Power -
  so the target uses SAMSUNG_YPR0_PAD and its keymaps. Eight keys sit on
  two resistor ladders on the LSADC, found in the original firmware and
  measured on a unit:
      channel 1   up 158, down 295, select 435, left 561, right 687
      channel 2   menu 155, back 292, user 431
  each key owning half a step either side of its reading;
  power is GPIO C1, active high.

Builds as firmware and as bootloader. Status 3 (unusable) in builds.pm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Iff4984023415f341ca7507af6b5b2b551201e953
2026-09-29 08:53:27 +02:00
Marcin Bukat
d3893ead3a rk27xx: keep interrupt and bulk endpoints in separate groups
USB mass storage writes ran at 0.03 MB/s in the firmware - to the NAND
and to the SD card alike - while the bootloader, with the same driver,
wrote the same NAND at 2 MB/s. The firmware adds a HID interface, and
without it writes ran at full speed.

The UDC's endpoints come in groups of three - bulk OUT, bulk IN,
interrupt IN: 1-3, 4-6 and so on - and allocation handed out the first
free endpoint of each type, so HID's interrupt endpoint 3 landed in the
group of mass storage's bulk endpoints 1 and 2. The host polls it every
16 ms, the idle endpoint NAKs, and each poll costs the group's bulk
traffic: writes advanced about one packet per poll. Polled every 125 us
instead, they all but stopped; moved to endpoint 6, in a group of its
own, they ran at 2.36 MB/s, as without HID.

Never give an interrupt endpoint a group with bulk endpoints in use, or
the other way round, whichever class asks first. Since which endpoints
are available then depends on what is already allocated, the driver
tracks the allocation itself - option 2 of usb_drv.h, as usb-designware
does - with its context in usb-rk27xx.h, which usb_core.c includes before
usb_drv.h. HID keeps working.

Tested on a generic rk2705 with ums_stress.py over USB mass storage to
the SD card: 0.03 MB/s with HID on endpoint 3, 2.36 MB/s with it on
endpoint 6 - the allocation this change produces for mass storage plus
HID. (Measured with the driver's earlier allocator, before the USB core
took allocation over; this carries the same rule into the new scheme.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ib80ed206a3705f2c76fc8457b5c0a54d60a46402
2026-09-28 16:55:21 +02:00
Paul Sauro
9aa2d7fe94 usb: accept replacement SETUP after an abandoned control transfer
A host can replace an unfinished control transfer with a new SETUP. ARC
and DesignWare flush EP0 without reporting completion callbacks, leaving
the core waiting for a data/status packet that will never arrive.

Explicitly notify the core after both directions and stale completion
bits have been cancelled. Return an abandoned data/status stage to READY.
If a queued or running handler still owns the request and data buffer,
keep that ownership and suppress its response; dispatch only the latest
replacement when it returns. A driver-owned SET_ADDRESS can also cancel
a deferred request without passing its SETUP to the core.

Do not overwrite an arbitrary busy state in usb_core_setup_received().
ARC cancellation is a prerequisite in the preceding patch; DesignWare
cancels both EP0 directions before notifying and rearming reception.

Change-Id: Ia8e0a68fe47ccab952168da24a2f76e311ca2b15
2026-09-27 09:19:39 -04:00
Paul Sauro
841007dfa1 usb: let controller drivers handle SET_ADDRESS requests
Handle SET_ADDRESS directly when each controller receives SETUP, before
passing other requests to the core. Cancel transfers, send the status
response in the driver and queue usb_core_notify_set_address(); the core
only updates its address/configuration state. Remove usb_drv_set_address
and avoid a request callback from the core back into the controller.

Keep status completions for this driver-owned request out of the core EP0
state machine. ARC writes DEVICEADDR and notifies after successful status
IN completion; other controllers retain their existing register/status
ordering or automatic address handling. Use IRQ-local operations on
DesignWare rather than helpers which unconditionally re-enable its IRQ.

Take the low seven bits of wValue; do not impose new validation on the
unspecified wIndex/wLength fields. Convert all eleven firmware backends;
the separate hwstub API is unchanged.

Change-Id: I7b96275df90c14ef4a9954f04ac6fdc004ec8d6c
2026-09-26 13:23:01 -04:00
Aidan MacDonald
c6abf3382a firmware: move iriver flash helper functions into target tree
Move the iriver-specific functions for detecting flashed
Rockbox/OF images into system-iriver.c and remove the
HAVE_FLASHED_ROCKBOX define which is now redundant (all
targets using system-iriver.c enable it).

Copyright attribution on the new system-iriver.h header
is a best guess from Git history.

Change-Id: If1933f881a63fd517162ab9ca8f4a3007b997739
2026-09-23 13:44:45 -04:00
Aidan MacDonald
29eef25ac7 hw_h264: use standard rockbox copyright headers
Some files were not using the standard header with the
Rockbox logo. Add this and move any technical notes into
a separate comment.

Change-Id: Idaac932cd56154c7b785ba0e6c0231a21878f786
2026-09-23 16:22:18 +01:00
Andrew Rice
76f8925d23 ipodnano3g: power, RTC, backlight, battery and audio
Fills in the stubs the Nano 3G port was left with, taking each from how
the original firmware drives the same hardware.

Testing evidence: firmware/target/arm/s5l8702/ipodnano3g/TESTING.md.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Iea5314769502f5941a176600869591756c5e3233
2026-09-20 08:53:53 -04:00
Andrew Rice
34a18e7616 ipodnano3g: NAND driver, FTL and storage
The Nano 3G keeps everything behind the S5L8702 flash controller and
Apple's FTL ("Whimory"), and nand-nano3g.c was a stub, so the port had
no storage at all. This is the flash driver, the FTL and the wiring that
makes the NAND Rockbox's disk. The three are one change because neither
half is usable without the other: the driver alone cannot see a
filesystem, and the FTL alone has nothing to drive.

Testing evidence: firmware/target/arm/s5l8702/ipodnano3g/TESTING.md.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ib04a991489ff3a1a63cd55552e4a8d7ec7a5fc8c
2026-09-19 20:08:03 -04:00
Andrew Rice
2adcfa08cf s5l8702: add the Nano 3G's flash controller registers
The S5L8702 has two flash memory controllers; the BootROM uses the first
at 0x38a00000 and addresses the second at +0x400. FMC_BASE was defined
for the S5L8700 and S5L8701 only.

Also add the registers Apple's NANDReadPage (BootROM 0x20009910) uses
that are not in the existing S5L8700 set, and three FMCSTAT bits. Their
real names are unknown, so they are named for what they were observed to
do and the comments say which are inferred rather than measured.

No functional change: this header only adds definitions.

AI provenance: developed with Claude Opus 5 (Anthropic), used through
Claude Code. The model wrote most of the code and this message under
Andrew Rice's direction. Any hardware testing described above was
carried out by Andrew Rice, who is responsible for this change.

Change-Id: Ib8c808128abc9a117cb811fe1fe47bffa4ec0abe
2026-09-16 08:14:24 -04:00
David Cormier
e0136bc7f4 ipod6g: add hardware H.264 video playback
Add S5L8702 VPU-B initialization, reset, bitstream input, frame output,
and cache maintenance to the iPod 6G target. Advertise it with
HAVE_HW_H264 and append a capability-gated decoder interface to the
plugin API.

Keep MP4 parsing, AAC decode and mixer output, A/V synchronization,
playback controls, resume state, and presentation in the multi-file
h264_player plugin. The target layer exposes decoder operations only.

Accept non-fragmented MP4/M4V containing Constrained Baseline H.264
through level 3.0, up to 640x480 at 30 fps, with optional AAC-LC audio.
Validate codec configuration and all sample-table relationships before
activating the hardware.

Read MP4 tables in bulk, boost the CPU while preparing them, and report
staged loading progress so long movies do not appear to hang during
startup.

Register the viewer and document its format limits and controls. The
libm4a compatibility fixes needed by video-first containers remain in
the preceding standalone change.

Tested on an iPod Classic 6G through an isolated Rolo nightly runtime:
H.264/AAC playback and M4V startup succeeded. Normal and
isolated-runtime iPod 6G builds also complete, and git diff --check is
clean.

Change-Id: I1e96c65c7d0b4231a94f602f8052f1b26d6e4a80
2026-09-13 08:07:59 -04:00
David Cormier
d2ae775f0a ipod6g: add composite video output driver
Add NTSC composite output for the iPod Classic 6G/7G using the
S5L8702 video processor, mixer, and encoder. Reconstruct the setup used
by the original firmware and mirror the 320x240 LCD in a centered
648x432 viewport.

Expose the driver through HAVE_COMPOSITE_VIDEO_OUT and a
target-neutral videoout interface. Keep the S5L8702 MMIO layout and
register definitions with the other SoC definitions in s5l87xx.h.

Convert LCD updates from RGB565 to planar YUV420. MPEG playback copies
decoded YUV420 planes directly, avoiding an RGB round trip. Hold output
clocks and CPU boost only while the memory-backed layer is active, and
restore them on disable or power-off.

Defer dock identification out of the serial tick because the accessory
resistor ADC path sleeps. Auto detection recognizes the measured Philips
DCP750/37 resistor range; manual mode can qualify other attached docks.

Leave interrupts enabled during the encoder's 10 ms reset wait so PCM
DMA can service linked-buffer completions when a dock is inserted during
audio playback. Keep reset assertion, reset release, all SVID register
writes, and pipeline start atomic so the composite setup cannot
interleave.

Hardware tested on an iPod Classic 6G/7G with a Philips DCP750/37 for
correct colors and geometry, stable UI mirroring, and full-screen MPEG
playback.

Change-Id: I669f2477d5cc707b48f7d24384c713d874a80e3f
2026-09-07 08:55:22 -04:00
Mauricio Garrido
e498c0171a 3ds: Port refactor.
This commit does the following changes to the 3ds port:

- Rename the target from ctru to 3ds.
- Rename all files and functions with the ctru naming convention to 3ds.
- Created a new file and folder structure that will better integrate future console ports that share the same codebase.
- Fixed a buffer overflow bug in pcm code.

Change-Id: I17c6f86df64eb99dd2b653485d70832ff46b2ba8
2026-09-01 08:39:07 -04:00
Aidan MacDonald
99c18f336c sdmmc_host: add quirk for card timeout on single block access
Some 512G Samsung cards (and possibly other cards) seem to
have problems with repeated single block read commands and
sometimes just time out without ever sending the data. The
card response is received OK and reports no errors but no
data is received.

The problem also occurs if a multiple block read is used to
transfer a single block but doesn't seem to occur when more
than one block is transferred.

Less commonly, timeouts can occur on write commands but it
is not clear if that happens only after a timed out read.
Adding a delay of a few tens of milliseconds before each
read/write single block command appears to prevent this.

Change-Id: I5a02b71f59cc02832acaf30e5f900a3ee8804e76
2026-08-29 19:48:22 +01:00
Aidan MacDonald
f40cae6cdc x1000: rewrite SD driver using sdmmc_host
Remove all SD protocol handling and all target specific code
like GPIO/interrupt handling and clock parent setup. This can
now be handled from sdmmc_host_target_init() for each target.

Now only the clock frequency is managed by the MSC driver.
To make this code easier to factor out later, it's confined
to helper functions that do not access the driver state.

One small change is that MSCxDIV output is now clamped to a
minimum of 50MHz to avoid unnecessary frequency changes. The
MSC_CLKRT divider can still divide 50MHz down to 400 KHz so
there is no downside to this.

Auto-CMD12 is now unused. Using it would make error handling
more difficult for sdmmc_host since the controller does not
expose response data for the auto-CMD12.

Explicit CMD12 was not handled correctly in the old version
of the driver because the busy signal was ignored for R1b
responses if there was no associated data transfer. This is
now fixed by waiting for the PRG_DONE interrupt instead of
END_CMD_RES for non-data transfer R1b type commands.

Since existing X1000 targets are all very similar they use
a shared implementation in sdmmc-x1000-common.c for clock
setup and card detection. New targets can either use this
or create a separate file if they are different enough to
warrant one.

Change-Id: I35396637325d7c06a10151bb6aee64cabdc7b682
2026-08-29 14:48:12 -04:00
Vencislav Atanasov
0e2a3cc0c6 3DS: enable software tone controls via DSP (Olivier Senn)
Route bass and treble adjustments through Rockbox's DSP pipeline
using biquad filters, making the Bass/Treble sliders in Sound
Settings functional rather than no-ops.

💘 Generated with Crush

Assisted-by: Crush:deepseek-v4-pro
Change-Id: I5d168aaa233fe450defaea03d6657732abd2ec47
2026-08-26 02:22:30 +03:00
Michael McAllister
ec59f570dd keyboard: point-mode virtual keyboard for touchscreens
On large touchscreens the software keyboard can now run in "point mode". Keys are laid out finger-sized and tapped directly instead of being navigated with a cursor. Targets opt in with HAVE_KBD_POINT_MODE.

Key size is derived from LCD_DPI so a key is about 5mm across whatever the panel density, falling back to a fixed size where DPI is unknown.

A phone-style default layout in the UI font, across three flip pages of eight lines. Page two is page one shifted (i.e caps). Page three completes Latin-1 and adds additional accented letters common to the other European locales.

Space is drawn as an icon, since the UI font has no glyph for it.

Change-Id: Ibe2e305b3c22b1f9152358cf3864b9445b67b463
Co-Author: Claude Opus 4.8
2026-08-25 09:56:46 -04:00
Aidan MacDonald
69a36026f8 sdmmc_poll: add edge triggered polling support
Change-Id: I958a09efc055d474da5e03a06d80719dbb2f5b14
2026-08-25 07:51:14 -04:00
Aidan MacDonald
5e71adddf9 sdmmc_host: add generic SDMMC polling helper
Pull this out of the echoplayer target so it can be reused
easily by other targets.

Change-Id: If14e23a90c133d8435f7944d7b1607630baaf3bb
2026-08-25 07:51:14 -04:00
Aidan MacDonald
94a0fe608a sdmmc_host: trigger LED on disk activity
Change-Id: Ic7c43de01f381b7d87ed6b234fa63d5276ae31a5
2026-08-25 07:51:14 -04:00
Aidan MacDonald
cdad8cde64 sdmmc_host: add support for SET_BLOCK_COUNT (CMD23)
According to commit 7327d9fb6c ("Implement set block count
(CMD23) for x1000 target") some cards may experience data
corruption with certain controllers when CMD12 is used to
terminate multiblock writes. Using set block count (CMD23)
is reported to fix this issue.

Following the approach in that patch, use the SCR register
to probe support for CMD23, but disable use at runtime if
CMD23 generates an illegal command error.

Change-Id: I3ee1e48939b79b848fbda12c6737f2f974f47fa0
2026-08-25 07:49:05 -04:00
Aidan MacDonald
afe5e7191d sdmmc_host: add helper for allocating disk cache buffer
Change-Id: I918a34a92e2e0f53c19ba44fb2b42396719b92e1
2026-08-25 07:49:05 -04:00
Aidan MacDonald
1f1db58d44 sdmmc: add optional SCR register to tCardInfo struct
The SCR register is needed for detecting if the card
supports certain commands like SET_BLOCK_COUNT.

Change-Id: I48cbf8fff497b71fb831ba546a462b27bb30851f
2026-08-25 07:49:05 -04:00
Aidan MacDonald
b621a519e2 sdmmc_host: add helper to get bus frequency from enum
Change-Id: I5796d19a4c28986bbb3674a39cc93f3fa473ae3c
2026-08-20 19:22:43 +01:00
Skye
df85814e74
erosqnative: use hwvol at runtime on es9018k2m
Change-Id: I0ea89ff44a7d7c7c4aeb65ec2b56287324533bcc
2026-08-14 22:39:35 +09:00
Skye
9a7ffac2e4
pcm_sink: allow per-sink swvol/hwvol selection
Change-Id: I5b0a66f2e41ca32a2d6c88bda3ffe0db0df08ce0
2026-08-14 22:39:13 +09:00
Jerry Shen
51d7d56803 ap80max: New hosted port
HibyOS-based target: keymaps, LED, powermgmt, bootloader and sim support,
plus cabbiev2 for the new 360x640x16 screen. Opus 5 helped w/ debugging
and the initial scaffolding.

Updated name to FB_STRIDE_MISMATCH, added simulator bmp and specs.

Change-Id: If797ac6581cf75d9d1fcf36e615ee03cf6f905d6
2026-08-13 17:55:06 -07:00
Michael McAllister
ef20bc4c78 usb: keep the USB Serial setting across connects
Debug -> USB Serial calls usb_core_enable_driver(USB_DRIVER_SERIAL, ...), which sets a flag inside usb_core. usb_core_init() clears every driver's enabled flag on each connect and runs after the toggle, so the choice is gone before any descriptor is built: the menu reports the new state and nothing changes.

Hold the setting in firmware/usb.c and reapply it from usb_configure_drivers() on each connect, which is where the other drivers are already configured. usb_set_serial()/usb_get_serial() sit alongside usb_set_hid(), which works this way for the same reason.

toggle_usb_core_driver() goes with it: toggle_usb_serial() was its only
caller, and a generic wrapper around a call that cannot persist is not worth keeping.

Affects any target building USB_ENABLE_SERIAL.

Change-Id: I171a532d23cc9cf0efe0a01c2836b69846333a4d
Co-Authored-By: Claude Opus 4.8
2026-08-10 15:32:36 -04:00
Hemant Kumar
b217a55059 ipod6g: Add inline earphone remote support
Decode the jack remote's play/pause and volume buttons via the
"Mikey" controller (I2C 0x72) and report them as multimedia keys so
they work on every screen, like the OF. Protocol reverse engineered
on-device, notes in mikey-6g.c.

Change-Id: If5f3d3abf043c0ce0d8ca7beb0f4b591e41c5c43
2026-08-05 08:40:24 -04:00
Michael McAllister
4f6aac445f hiby: raise the plugin buffer to 2MiB on the 64MB targets
PictureFlow refuses to start on the larger panels in this family with
"Not enough memory for album art cache", no matter how small the
library is.

It is PF_PLAYBACK_CAPABLE here, so it deliberately takes the plugin
buffer instead of stealing the audio buffer in order to keep playback
running. It then gives a quarter of that buffer to its album art cache,
which needs DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(pix_t) bytes:

  HiBy R1        480x800  ->  400x533  ->  416 KiB
  HiBy R3 Pro II 480x720  ->  360x480  ->  338 KiB
  Surfans F28    320x480  ->  240x320  ->  150 KiB

A quarter of 512KiB is only 128KiB, so all three fail the check before
they ever look at the library. The rest of the family tops out at
320x240 and needs at most 68KiB, which is why the old value went
unnoticed.

Most hibyos devices only have 32MB of RAM in total, and the OS and its
daemons eat about two thirds of that, so there is nothing spare to hand
out and the buffer stays at 512KiB. The three affected targets happen to
be exactly the 64MB ones, and they are also the only members of the
family configured with MEMORYSIZE >= 16, so key the size off that.

Plugins are dlopen()ed on hosted targets, so pluginbuf is plain BSS and
plugin.lds/DRAMSIZE do not apply.

Change-Id: I38db01231bbb8d139cb2239623a79250e0e46b61
2026-07-27 08:03:54 +01:00
Michael McAllister
dbd53ef8ae hibyr1: implement USB DAC
Implement the USB Audio Class DAC on the HiBy R1 and R3ProII, driven by
the usb_audio setting from the scaffolding patch: the host plays audio
over USB and the player's CS43131 renders it.

The vendor kernel provides a UAC gadget function "uac_sa" whose char
device /dev/uac_sa delivers the host's PCM: the isochronous OUT frames
are converted to left-justified S16-in-S32 stereo and queued in a kernel
ring, drained with a non-blocking read(). The data path lives in
usb-dac-hiby.c -- a pump thread drains /dev/uac_sa into a small
single-producer/single-consumer ring and the mixer callback hands that
PCM to the codec through the normal ALSA output path. No resampling is
needed because Rockbox clocks the codec at the host-negotiated rate.

The DAC is built on the existing configfs gadget and binds the UDC like
ADB, while usb_power_only keeps the USB thread out of the way. In charge
mode it is a standalone self-bound gadget. In adb mode it is composed
alongside adb on one gadget so the host gets a sound card and adb at
once; uac_sa must be the first-linked function (audio interfaces 0-1)
because the vendor function hard-codes its interface numbers.

The pump is hardware-only, so usb-dac-hiby.c is excluded from simulator
builds; the usb_audio_get_active() playback-interlock stub lives with the
scaffolding.

The R3ProII shares this hosted HiBy port and the same userspace gadget,
and the data path is codec-agnostic, so nothing here is R1-specific.
Only the R1 has been validated on-device.

Co-Authored-By: Claude Opus 4.8
Change-Id: I64c57ede27f411a2c61d41a7e0fa127b51a7b5b9
2026-07-22 15:22:46 -04:00
Michael McAllister
ea775fa501 hibyr1: add USB DAC scaffolding
Introduce the generic, target-agnostic pieces for a gadget-driven USB
Audio Class DAC, gated by the HAVE_HOST_USB_AUDIO target flag so they stay
inert unless a target opts in.

Rather than adding a new USB mode, reuse the existing usb_audio setting
(never / always / while charge-only / while mass-storage) with its
LANG_USB_DAC string, usb_set_audio() callback and the
PCM_MIXER_CHAN_USBAUDIO mixer channel. HAVE_HOST_USB_AUDIO becomes the
umbrella capability flag for this common code; USB_ENABLE_AUDIO stays the
native usbstack class-driver contract (which needs HAVE_USBSTACK and so
cannot be used by hosted ports whose kernel owns the USB controller).

usb_set_audio() is declared here and implemented by the target (natively
by the usbstack driver, or in the hosted port for gadget targets, as with
usb_audio_get_active()), and applied at settings load. The playback
interlock in wps.c/playback.c keeps local playback from mixing with host
audio while the DAC is active. Simulator stubs for usb_set_audio() and
usb_audio_get_active() keep sim builds linking.

Co-Authored-By: Claude Opus 4.8
Change-Id: I5b7738508c24721d91d4c32379102a1ac7c6228b
2026-07-22 15:22:46 -04:00
Skye
f463f4a17a audiohw: remove unused BALANCE_CAP and CLIPPING_CAP
Change-Id: I8905e9a656fcba20c8adeb840d148bcd97511665
2026-07-20 12:47:12 -04:00
Aidan MacDonald
862370982c stm32h743: implement timer API
Change-Id: Idcac3ab528e154097fb76fcfda78540ef02494df
2026-07-11 17:23:36 -04:00
Solomon Peachy
f11c89aae2 usb: Fix usb mode not initialized/restored on the DX50/DX90
* Devices with ADB now have HAVE_USB_ADB
 * DX50/DX90 no longer set USB_NONE
   * stub out necessary functions
 * usb_set_mode() and global_settings.usb_mode are now:
   * called for all devices with (HAVE_USB_ADB | HAVE_USB_POWER)
   * wrapped with consistent #ifdefs

Fixes regression in ce88de54b8

Change-Id: Ib0c16082fe237e8159cd42847355186ea5c74589
2026-07-03 12:26:34 -04:00
William Wilgus
d87755c535 FS#13944 - FONT_UI loads the last loaded font not global_status.font_id
FONT_UI scans from MAXFONTS-1 to 0 to maximize the chances of getting a loaded
font but this may result in global_status.font_id being ignored even
if set through setuifont

this should take care of all the plugin woes dues to this
by setting the lcd font to the ui font before loading the plugin
and also making FONT_UI map to this font when font_get(FONT_UI) is called
if the desired font is not loaded then fallback to the previous behavior

Change-Id: I101d6f91910c17b08fca2b988a0a99c9e6899bee
2026-06-30 13:29:23 -04:00
William Wilgus
3e08b86e4b FixRed a824085 skin: add %pX tag checkwps, ATA builds
ata_disk_isssd() return 0 for SIMULATOR

Change-Id: If281b5ce7a98f338dfd81635c8936dd90c41b9bb
2026-06-27 13:27:35 -04:00
Solomon Peachy
5462f203d3 bidi: Expand+Correct the list of RTL codepoints in is_rtl_char()
Was missing:

 * Arabic Supplement
 * Arabic Extended B
 * Arabic Extended A
 * Rumi Numerals
 * Arabic Extended C
 * Indic Isqaq Numerals
 * Ottoman Siyaq Numerals
 * Arabic Mathematical Alphabet Symbols

Worth noting that most of these are vanishingly unlikely to ever show up
in the context of Rockbox.  (The exceptions are "Arabic Supplement" and
possibly the Mathematical Symbols)

Also corrected "Arabic Presentation" into two distint blocks, as
the characters between them (fe00-fe6f) are NOT indicative of RTL.

Change-Id: I0c5c547921c789d32425682c8c75edb21428f549
2026-06-27 10:20:03 -04:00
elishay
0e3355de50 keyboard: fix RTL (Hebrew/Arabic) on-screen keyboard
Commit d1be73c ("keyboard.c Use viewports, move text box pos")
moved the picker and edit line into dedicated viewports. Under an
RTL UI language these viewports get VP_FLAG_ALIGN_RIGHT, so
lcd_putsxy mirrors every call; with the per-character cell drawing
this reversed the picker grid and the edit line (Hebrew shown
reversed, Latin filenames backwards, wrong caret).

- Clear the alignment flag on the keyboard own viewports so the
  picker grid and cell layout are no longer mirrored.
- Draw the edit line as a single string so the bidi engine reorders
  mixed Hebrew/Latin correctly, and use the full line width.
- Compute the caret from the bidi (LTR-base) visual layout so it
  lands at the insertion point, including mixed Hebrew+Latin text.
- Pick the edit-line direction and invert the left/right cursor
  keys based on the text first strong character.

Change-Id: I79f1c444bc9121fd5018ad5f6f4148afe2c1a3e1
2026-06-27 07:45:12 -04:00