mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ismaïl Bahloul" <i.bahloul01@gmail.com>
To: linux-sound@vger.kernel.org
Cc: tiwai@suse.com, perex@perex.cz, linux-usb@vger.kernel.org,
	alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org,
	corbet@lwn.net, skhan@linuxfoundation.org, rdunlap@infradead.org,
	linux-doc@vger.kernel.org,
	"Ismaïl Bahloul" <i.bahloul01@gmail.com>
Subject: [RFC PATCH v6 0/8] ALSA: usb: add RME Babyface Pro driver (proprietary mode)
Date: Sat,  3 Oct 2026 21:41:29 +0200	[thread overview]
Message-ID: <20261003194137.86176-1-i.bahloul01@gmail.com> (raw)

Hi Takashi,

This is v6 of the RME Babyface Pro proprietary-mode driver.  The split
is the one you asked for in the v4 review and that v5 introduced: a
minimal core first, the mixer added piece by piece, suspend/resume near
the end, the front panel and the DSP EQ last, and a design document.
v6 keeps that split and folds in the work done since v5, most of it in
the stream core; it is rebased on next-20261002.

Changes since v5:

 - Stream sessions (patch 1, David Fredman).  A session now lives from
   the first prepare to the last hw_free; trigger START/STOP only
   gates the audio the URB handlers move, so an xrun restart no longer
   tears the session down.  A session start sends what the RME Windows
   driver sends (rate write, trigger pair, URBs, arm) instead of
   re-running the cold init and replaying the whole mixer state: about
   1 ms instead of about 1 s, and it waits until 50 ms have passed
   since the previous stop, since a session triggered within ~15 ms of
   the last one comes up silent.  After three consecutive bad URBs the
   handlers stop resubmitting; disconnect and suspend kill the URBs
   before cancelling the work their handlers queue; hw_params is
   refused once the device is gone; the handlers read the substream
   pointers under RCU.

 - The latency follows the application (patch 1, David Fredman).  The
   URBs are sized from the period in hw_params, two periods in flight,
   instead of a fixed 8 x 256 frames queue (42.7 ms at 48 kHz whatever
   buffer the application asked for).  While another application has
   the other direction set up it is offered the running rate and a
   period no shorter than the session's; the application that holds
   both directions may change the rate or the buffer size itself, as a
   DAW does from its settings.  The round trip through the analog path
   is now the queue, two periods, plus 66 to 184 frames, for example
   2.7 ms at a 32-frame period (64-frame buffer) and 48 kHz, where it
   was 44 ms.

 - runtime->delay (patch 1, David Fredman): the audio queued in the
   URBs plus a fixed delay for the converters and the device, per speed,
   taken from RME's own driver.  The capture figures at 96 and 192 kHz
   are estimates for the Pro FS.

 - mmap access (patch 1).  The ring the core allocates was never
   offered for mmap, so JACK, which needs it, could not open the card
   ("mmap-based access is not possible for the capture stream").  The
   URB handlers already copy to and from that ring and take the
   application's position from the shared control page, so offering
   MMAP and MMAP_VALID was enough.

 - Core fixes (patch 1): a failed probe no longer dereferences a NULL
   URB/DMA array in the unwind; a partially filled playback URB plays
   silence after the queued frames instead of the previous URB's audio.

 - Mixer (patches 2-4): a volume change no longer unmutes a muted
   output (David Fredman); the power-on default routes only the
   playback channels; the fader controls validate a value before
   narrowing it; a failed preamp write no longer leaves the cache
   claiming the new state; a re-applied DIM rebuilds its restore point.
   The saved-state list is purged after usb_deregister(), not before.

 - Front panel (patch 6): a DIM press is reported through a "DIM
   Button Press Count" control for a mixer application to act on,
   rather than the driver changing a level itself; the wheel ignores a
   muted output; the controls the panel changes (volume, gain, 48V,
   monitoring crosspoint) are notified (David Fredman for the first
   two).  The SELECT channel selection cannot be read, and the unit
   keeps one per IN pair across IN switches and power cycles, with the
   first press after an IN switch only showing it again.  v5 assumed it
   starts empty and steps from there, so SET and the wheel could act on
   a channel other than the lit one.  It is now one "Front Panel
   Selection" control per pair, which alsactl keeps across boots; a
   pair that was never told starts unknown and SET and the wheel do
   nothing on it rather than guess.  The state shared with the control
   callbacks is accessed with READ_ONCE/WRITE_ONCE, and the mixer state
   is saved at disconnect only after the poll has stopped.

 - DSP EQ (patch 7): the EQ is saved and re-uploaded across resume and
   a re-probe; an inactive band uploads a defined shared scale; the Q
   controls start at 1.0 instead of an out-of-range 0.

 - The split itself.  v5's patches 2-7 had lost the DIM restore-point
   update on a Phones volume change; it is back, in patch 4.  Resume
   now re-applies the routing flags, which v5 left out.  Phase, split
   and trim are re-applied after a re-probe from patch 3 on, where v5
   waited until patch 4.  No comment, Kconfig help text or MAINTAINERS
   entry refers to the series any more, and the MAINTAINERS entry lists
   linux-sound.

 - The frames_per_urb, nurbs, urb_frames_min and panel_poll_ms
   parameters are 0444: they are read once at probe.

 - The design document describes the current stream model, the
   period-driven URBs and the SELECT behaviour.

Every patch builds in-tree on its own against next-20261002 with W=1
and no warnings.  Run against the generated patch files, checkpatch
--strict reports no errors, four warnings and one check, all known
false positives: 'ang' (the CORDIC angle) twice and BIT() for a signed
Q27 constant in the EQ patch, and the "does MAINTAINERS need
updating?" note on the two patches that add files, which patch 1's
MAINTAINERS entry covers.

Validation, on a Babyface Pro FS with the final tree (built
out-of-tree against 7.2.8 from the same sources):

 - regress.sh --mixer-restore --disconnect-test, with the sweep at
   periods 64 to 2048 on all nine rates, passes 59/59 on a quiet
   machine; the same sweep with both streams opened for mmap access
   passes 56/56.  A first read/write run, made while I was running
   checkpatch on the same machine, had one playback xrun at 88.2 kHz
   and a 64-frame period; that point passed 12 of 12 repeats in both
   access modes.

 - Each of patches 1-7 was also loaded on its own and streamed full
   duplex (read/write at 48 kHz, mmap at 192 kHz) with no xrun and
   nothing in the kernel log; the card shows 0, 96, 119, 133, 133, 143
   and 203 controls after patches 1 to 7.

 - The real jackd 1.9.22, started with "jackd -d alsa -d hw:BabyfacePro
   -r 48000 -p 256 -n 2", fails with the mmap message on the module
   before patch 1's change and starts with it: 12 capture and 12
   playback ports, 20 s at periods of 64, 128 and 256 frames without an
   xrun, and a client's tone comes back on the card's internal playback
   tap at the expected level.  PipeWire opens the card with mmap access
   too, playback and capture together at a quantum of 256 and 48 kHz,
   with no errors.

 - The URB sizing: a single PCM session renegotiated through nine
   period/buffer configurations (64:128 to 2048:4096, including 100:200
   and 1000:3000) without an xrun, with the URB size and count chosen
   as described.  David Fredman measured it and the delay on an
   original Babyface Pro; his figures are in the PRs on the project
   page.  On the Pro FS, snd_pcm_delay() on the internal playback tap
   agrees with the model at 48 kHz to a constant 14 frames at periods
   of 64, 256 and 1024 (the tap leaves out the converters); the analog
   loopback check of the 96 and 192 kHz capture estimates has not been
   run.

 - Earlier, with v5's load-time profile (frames_per_urb=32 nurbs=8),
   two things were seen that are not understood: once a session at
   192 kHz came up with the device completing no URB (the next session
   was fine), and once the unit stopped completing URBs altogether
   until it was power-cycled - a module reload, a USB re-enumeration
   and a host reboot did not bring it back.  Neither has happened again,
   including at a 32-frame period with the period-driven sizing.  The
   default 256-frame sizing has shown neither.

Known limitations:

 - USB autosuspend is not supported; it is disabled at probe.  S3
   suspend/resume works.

 - The SELECT selection of an IN pair cannot be read from the unit.
   alsactl restores what the driver last knew, which is wrong only if
   the selection was changed while the driver was not running.

 - A few protocol details remain open (documented in the source, not
   blocking): the preamp readback index semantics, a width
   strip-ownership edge case, whether DIM's scope follows TotalMix's
   Main Out setting, and the exact high-frequency warping of the EQ
   coefficients against the vendor curve.

Disclosure: as with previous versions, the reverse-engineering and
substantial portions of the kernel implementation were written with
heavy assistance from AI coding assistants.  All of it was verified by
hand on real hardware; the human authors remain responsible for the
result via Signed-off-by.

Thanks,
Ismaïl

Ismaïl Bahloul (8):
  ALSA: usb: add RME Babyface Pro driver core (probe, PCM stream)
  ALSA: usb: babyfacepro: add output masters and crosspoint routing
  ALSA: usb: babyfacepro: add mic preamp, phantom/pad and input trim
  ALSA: usb: babyfacepro: add routing flags and varispeed pitch
  ALSA: usb: babyfacepro: add S3 suspend/resume
  ALSA: usb: babyfacepro: add the front-panel poll and controls
  ALSA: usb: babyfacepro: add the hardware DSP EQ
  Documentation: sound: add the Babyface Pro proprietary-mode design doc

 Documentation/sound/cards/babyface-pro.rst |  193 +
 Documentation/sound/cards/index.rst        |    1 +
 MAINTAINERS                                |    6 +
 sound/usb/Kconfig                          |   17 +
 sound/usb/Makefile                         |    2 +-
 sound/usb/babyfacepro/Makefile             |    4 +
 sound/usb/babyfacepro/babyfacepro-ctl.c    | 3929 ++++++++++++++++++++
 sound/usb/babyfacepro/babyfacepro.c        | 2076 +++++++++++
 sound/usb/babyfacepro/babyfacepro.h        |  579 +++
 9 files changed, 6806 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/sound/cards/babyface-pro.rst
 create mode 100644 sound/usb/babyfacepro/Makefile
 create mode 100644 sound/usb/babyfacepro/babyfacepro-ctl.c
 create mode 100644 sound/usb/babyfacepro/babyfacepro.c
 create mode 100644 sound/usb/babyfacepro/babyfacepro.h

-- 
2.56.0


             reply	other threads:[~2026-10-03 19:42 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-03 19:41 Ismaïl Bahloul [this message]
2026-10-03 19:41 ` [RFC PATCH v6 1/8] ALSA: usb: add RME Babyface Pro driver core (probe, PCM stream) Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 2/8] ALSA: usb: babyfacepro: add output masters and crosspoint routing Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 3/8] ALSA: usb: babyfacepro: add mic preamp, phantom/pad and input trim Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 4/8] ALSA: usb: babyfacepro: add routing flags and varispeed pitch Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 5/8] ALSA: usb: babyfacepro: add S3 suspend/resume Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 6/8] ALSA: usb: babyfacepro: add the front-panel poll and controls Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 7/8] ALSA: usb: babyfacepro: add the hardware DSP EQ Ismaïl Bahloul
2026-10-03 19:41 ` [RFC PATCH v6 8/8] Documentation: sound: add the Babyface Pro proprietary-mode design doc Ismaïl Bahloul

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261003194137.86176-1-i.bahloul01@gmail.com \
    --to=i.bahloul01@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=rdunlap@infradead.org \
    --cc=skhan@linuxfoundation.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®