Linux Documentation
 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: [PATCH v7 0/8] ALSA: usb: add RME Babyface Pro driver (proprietary mode)
Date: Tue, 27 Oct 2026 12:31:31 +0100	[thread overview]
Message-ID: <20261027113140.134257-1-i.bahloul01@gmail.com> (raw)

Hi Takashi,

This is v7 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.
v7 keeps that split and folds in the fixes made since v6, and is
rebased onto next-20261026, the most recent snapshot at the time of
writing.

This is not an RFC.  The split you asked for in the v4 review has been
in place since v5, the open points at the end are documented and none
of them blocks a merge, so the series is submitted for merge rather
than for another design round.

Changes since v6:

 - Playback underruns (patch 1, David Fredman).  The playback handler
   clamped its copy to the frames the application had written, so
   hw_ptr could not pass appl_ptr.  An application that runs the stream
   free - dmix, on the hardware PCM it opens - therefore got a silent
   stream and hung.  The handler now copies the ring as it is and moves
   the pointer on by the whole URB, as a DMA engine would; the PCM
   core's xrun check and stop threshold handle an underrun.

 - Capture order (patch 1).  The twelve capture channels now follow
   the device's own word order: AN1-4, AS1/2, ADAT3-8.  AS1/2 is the
   first optical pair, so it carries ADAT 1/2 in ADAT mode and S/PDIF
   in S/PDIF mode.  The old map kept channels 0-9 in place and moved
   AS1/2 to 10/11; the identity map is one thing less to explain, and
   before mainline is the last window to change the order.  The tools
   in the development repository and the companion mixer application
   follow.

 - Output masters (patch 2, David Fredman).  The controls now count
   the 8-bit register's 0.5 dB steps over the front panel's range; the
   control value is the hardware step, the 16-bit companion register is
   derived from it, and the conversion table is gone.

 - Optical Out (patch 4).  A new "Optical Out Format" control switches
   the optical port between ADAT (default) and S/PDIF, bit 10 of the
   host settings word.

 - Crosspoint map (patch 2).  The matrix addressed the output pairs
   through a block table that shifted every pair but the first: a
   control labelled PH3/4 fed AS1/2, and so on, and the AN1/2-only
   features also wrote into AS1/2's submix.  The blocks are at
   0x0034 * pair in the canonical order and the table is gone; the
   separate "low map" is that first block, not a layer beside it.
   Measured on the unit with a loopback capture.

 - URBs in flight (patch 1).  At periods of 128 and 256 frames the
   period is split into two URBs and one and a half periods are kept in
   flight, which takes half a period off the round trip (554 to 490
   frames at 128 through PipeWire).  Soaked for ten minutes at both
   sizes, full duplex, with no xruns.

 - EQ (patch 7).  A band's alpha is sin(w0 / (2Q)), the way TotalMix
   computes it, not the cookbook's sin(w0) / (2Q): the two agree while
   w0 is small and part ways as it grows, which is the effective Q that
   shrinks above a few kHz in the measured response.

 - Front panel (patch 6).  The OUT wheel moved ADAT7/8 with Opt
   selected.  It moves AS1/2, the first optical pair, which is the same
   mixer output in ADAT and S/PDIF mode, so the target does not follow
   the format.

 - Re-probes (patches 2, 5, 6, David Fredman).  The driver no longer
   saves its mixer state at disconnect and restores it at the next
   probe: udev's alsactl restore overwrote it on every card add, so a
   re-probe now starts from the default mixer and alsactl restores the
   user's settings, as for any other card.  A resume that follows a
   device reset goes through reset_resume instead of a re-probe.  The
   front-panel SELECT selection is the exception - it is not readable -
   so values restored after a boot are used, while a re-probe of a unit
   already seen leaves the pairs unknown, because SELECT may have been
   pressed since the last store.

 - The ASCII separator comments are gone (all patches, David Fredman).

Every patch builds in-tree on its own against next-20261026 with W=1
and no warnings.  Run against the generated patch files, checkpatch
--strict reports no errors, four warnings and two checks, all known
false positives: 'ang' (the CORDIC angle) twice and BIT() for a signed
Q27 constant in the EQ patch, the "does MAINTAINERS need updating?"
note on the two patches that add files (the control-surface file in
patch 2 and the documentation in patch 8), and the CamelCase check on
the USB descriptor's bInterfaceNumber.

Validated on the unit with the final tree (out-of-tree against
7.3.0):

 - regress.sh --mixer-restore --disconnect-test passes 41/41: the
   full-duplex sweep of the nine rates at periods 256 to 2048 with no
   xruns, runtime renegotiation, 30 start/stop cycles, the mixer state
   restored across an unbind/rebind, and an unbind in the middle of a
   capture.  The mmap sweep passes 38/38.

 - The AS1/2 loopback is on capture ch4/5: the sweep's tap reads it at
   about -30 dBFS, and pcmlate follows 12 of its 13 clicks there.

 - pcmlate reports a stalled writer as a playback xrun at periods of
   256, 1024 and 2048 frames at 48 kHz, and a one-second tone through
   dmix plays and returns (the clamp was what hung it).

Known limitations, unchanged from v6:

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

 - 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.

 - The URB size and count are load-time parameters, though the size
   follows the period the application asks for.

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 |  218 ++
 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    | 3917 ++++++++++++++++++++
 sound/usb/babyfacepro/babyfacepro.c        | 1988 ++++++++++
 sound/usb/babyfacepro/babyfacepro.h        |  565 +++
 9 files changed, 6717 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-27 11:32 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27 11:31 Ismaïl Bahloul [this message]
2026-10-27 11:31 ` [PATCH v7 1/8] ALSA: usb: add RME Babyface Pro driver core (probe, PCM stream) Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 2/8] ALSA: usb: babyfacepro: add output masters and crosspoint routing Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 3/8] ALSA: usb: babyfacepro: add mic preamp, phantom/pad and input trim Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 4/8] ALSA: usb: babyfacepro: add routing flags and varispeed pitch Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 5/8] ALSA: usb: babyfacepro: add S3 suspend/resume Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 6/8] ALSA: usb: babyfacepro: add the front-panel poll and controls Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 7/8] ALSA: usb: babyfacepro: add the hardware DSP EQ Ismaïl Bahloul
2026-10-27 11:31 ` [PATCH v7 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=20261027113140.134257-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