The FP6 sensor suite (QMC6308 magnetometer @ 0x2c, SPL07 barometer
@ 0x76, STK3BCx ALS/proximity @ 0x48) sits on an I2C bus wired to
TLMM gpio153/gpio154. Those pads are eGPIOs with no AP serial-engine
function: on the stock OS the bus is driven by an island QUP owned by
the Snapdragon Sensor Core on the ADSP. From the AP they are only
usable as software GPIOs, so describe the bus as i2c-gpio, and add the
QMC6308 magnetometer node: powered from the always-on vreg_l10b (per
the schematics), mount matrix from the vendor SSC registry
(volcano_qmc630x_0.json .orient: sensor x -> device +y, sensor y ->
device -x, z -> z), validated against Earth's field with a four-point
cardinal rotation.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The QST QMC6308 is a 3-axis AMR magnetometer on I2C, a single-supply
4-pin WLCSP part with no interrupt/DRDY pin, found e.g. in the
Fairphone 6. Its register map differs from the QMC5883L (chip ID at
0x00 instead of 0x0D, data at 0x01..0x06, and the range field living
in control register 2), so add a separate driver rather than extending
the QMC5883L driver.
Support raw X/Y/Z reads, output data rates 10/50/100/200 Hz, field
ranges +-30/12/8/2 Gauss, filter oversampling ratios (OSR1) 8/4/2/1,
the mount matrix, and runtime PM. The second-stage decimation filter
(OSR2) is left at its power-on default. The package has no DRDY pin,
so there is no trigger support.
Run measurements in the chip's periodic "normal" mode paced by the
DRDY flag rather than in its one-shot "single" mode: the datasheet
specifies no conversion time that could bound a one-shot wait, while
normal mode is paced by the specified output data rates, which also
keeps the sampling_frequency ABI meaningful.
Runtime PM puts the chip into its suspend mode after 500 ms without a
reading, dropping supply current from tens-to-hundreds of microamps to
2-3 uA (datasheet Table 2). The suspended chip retains its registers
and keeps responding on I2C, so resuming only rewrites the mode field
and discards one stale sample, and configuration changes can be
applied even while suspended. VDD is left enabled across runtime
suspend: the on-chip suspend draw is already negligible, and register
retention is what keeps the resume path trivial.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Mirror the driver as prepared for mainline (work/linux commit
917ea639925b, "ASoC: codecs: wcd9378: add TX/capture codec driver"),
per the carry-mirrors-upstream rule. On top of the previous carry
state this brings the maintainer-eye pre-review fixes:
- latch the per-ADC sys-usage bit and target SDCA function at
PRE_PMU; POST_PMD previously recomputed them from the live input
mux and could tear down the wrong function after a mux change
- clear the requested sys_usage_mask bit when no profile matches
- drop the unreachable -EACCES carve-out on the TX runtime-PM hold
(caused a usage-count underflow in unbind)
- mark the write-1-clear FUNC_STAT registers volatile
- drop the unused is_dapm parameter, the stale sys_usage write-skip
cache, the SDW_SCP_INT1_IMPL_DEF unmask and the PS0 re-request
hack; clamp DT channel-map reads
- name the SWRS_SCP_SDCA_INTRTYPE registers; trim the PS0-failure
debug dump; Kconfig imply + help text
One deviation from the mainline patch: v7.1.2 predates
sdw_slave_wait_for_init(), so the open-coded
wait_for_completion_timeout() stays here.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Measured acoustically on the FP6 with a fixed tone played through the
speakers: each TX gain code adds 1.5 dB (+6 dB per 4 codes, +30 dB over
the 0..20 range), not the 0.25 dB the TLV inherited from the wcd937x
driver family. With the correct scale, userspace volume mapping (e.g.
PulseAudio) can use the real analog range.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The SDCA function engine (the SmartMIC/SmartJACK/SmartAMP sequencer
machinery activated by the FUNC_ACT class-load) dies when the TX
SoundWire bus enters clock-stop. All its registers keep their values,
so a regcache sync on resume restores nothing visible - the PDE simply
never services power-state requests again: PDE11_ACT_PS stays in PS3,
SEQ_TXn_STAT stays at pwr_dn_rdy, and even the TXn_VALID_CFG_OVR /
TXn_SEQ_TRIGGER_OVR sequencer overrides and a TX0_SEQ_SOFT_RST pulse
are ignored. Re-toggling FUNC_ACT (a real 0->1 edge on the bus) does
not revive it either; only a full codec reset does. The result was
capture recording pure digital silence: the whole DPCM -> CDC-DMA ->
TX macro -> SoundWire transport ran, but the ADC never powered.
Hold a runtime PM reference on the TX slave for as long as the codec
is bound, so the bus never clock-stops. This matches the downstream
stack, which marks the TX SoundWire master 'qcom,is-always-on' - with
full documentation available, Qualcomm made the same trade-off.
Also perform the class-load activation with plain writes instead of
update_bits so the 0->1 activation edge always reaches the hardware
regardless of regcache state.
Verified on the FP6: from a fresh boot, repeated captures across what
were previously bus suspend/resume cycles now power the sequencer every
time (PDE11 reaches PS0) and record live mic signal instead of zeros.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Uncomment the Senary MI2S speaker dai-link. The sc8280xp machine driver
gained Senary MI2S support and the aw88261 power-up check is fixed (both
carried on this branch), so the link is functional: both AW88261 amps
load their ACF firmware and play.
This restores the enablement that was lost when the audio carries were
rebased from the v7.0.8 stack onto v7.1.2-milos: only the two driver
patches were carried over, leaving the sound card with zero dai-links
(the card registers but stays empty - no PCMs, no controls).
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The DAPM power-up sequence runs during snd_pcm prepare, but the BE
port graph is only started at trigger time. A codec that powers up
synchronously from a DAPM widget event and needs a running bit clock
at that point - such as aw88261 since commit caea99ac809d ("ASoC:
codecs: aw88261: remove async start") - can therefore never see a
live clock: its power-up check runs before the trigger and fails on
every stream start.
Start the graph at the end of prepare instead, mirroring what
q6afe_dai_prepare() does on the legacy stack, so the interface
clocks already run when DAPM powers up the codec. The FE side
already starts its own graph at prepare in q6apm_dai_prepare();
only the BE waited for trigger. The trigger-time start is kept as
a fallback, guarded by is_port_started.
Tested on the Fairphone (Gen. 6) - 2x aw88261 on Senary MI2S:
without this the amplifiers fail to power up with SYSST reporting
"no clock" on every stream start; with it they start synchronously,
including for the first short stream of the boot.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The v7.1.2-milos base predates two aw88261 changes this branch needs:
the hw_params format-negotiation series (Val Packett's work, in broonie
for-7.2) and our power-up SYSST fix. The Senary MI2S carry drives the
two AW88261 amps in S16_LE end to end, which relies on the amplifier
negotiating its format; without it the machine driver has to force
32-bit slots. The SYSST fix is also required: aw88261_dev_start()
otherwise fails "check sysst fail" on this firmware profile because it
demands SWS/BSTS while the amp is still muted.
Backport aw88261.c/.h wholesale to the mainline state (matching
work/linux tag audio-mainline-aw88261) so this branch tracks mainline
rather than the older milos base driver. Local carry only; milos
absorbs it on the next rebase past those commits.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Extend the clock-provider DAI fmt setup to Senary MI2S; without it
q6i2s_set_fmt() is never called, ws_src remains external and the DSP
does not drive the I2S clocks.
On the Fairphone (Gen. 6) the speaker amplifiers sit on this
interface; the board DTS enabling it is headed upstream separately
via linux-arm-msm.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The S3NRN4V (e.g. on the Fairphone 6, SM7635) is an S3FWRN5-family NFC
controller that needs different bring-up, selected with a new
samsung,s3nrn4v compatible:
- It ships with working firmware behind a bootloader protocol this
driver does not implement (GET_BOOTINFO times out), so the firmware
download step is skipped. Its RF registers are (re)loaded with the
proprietary DUAL_OPTION command (the HW and SW register blobs merged
into a single stream) instead of the START/SET/STOP_RFREG sequence.
- Its reference clock speed is configured with the single-byte FW_CFG
form, sent from the ->setup hook (after CORE_RESET, before CORE_INIT).
The selector value (0x11) is taken from the vendor configuration for
this part; its encoding is not documented.
- It gates its XI clock through a CLK_REQ line: the chip drives it high
when it needs the clock, notably to synthesise the 13.56 MHz poll
carrier. Left always-on, the free-running clock never lets the chip's
TX PLL lock on a fresh start and it cannot poll (it falls back to
listen only). Service the handshake when a clk-req GPIO is described,
gating the clock on it; without one the clock stays always-on.
The variant is carried as match data by both the OF and the I2C device
id tables so the two match paths agree, and the OF table is now
referenced unconditionally for its match data, so drop the
of_match_ptr()/__maybe_unused annotations from it.
The error policy differs between the two configuration steps on purpose:
a clock misconfiguration is fatal (a ->setup failure aborts CORE_INIT),
whereas an RF-register update failure is only warned about and bring-up
continues, since the chip falls back to the RF registers programmed in
its flash and NFC may still work.
Unlike the host-endian word read in the legacy rfreg path, the
DUAL_OPTION checksum is accumulated with get_unaligned_le32() and emitted
little-endian explicitly, so it is correct regardless of CPU endianness.
Existing S3FWRN5 / S3FWRN82 setups keep the firmware-download path and
the always-on clock, unchanged.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Add the Samsung S3NRN4V NFC + eSE controller on i2c1. Its XI clock is
provided by the RF_CLK2 PMIC buffer and gated through the controller's
CLK_REQ line on tlmm GPIO6.
The enable line is routed to the chip's power-down input, which is
asserted high to turn the chip off (the downstream driver treats VEN as
active-low on this design) -- hence GPIO_ACTIVE_HIGH, unlike the
exynos5433-tm2 wiring of the same driver. The pin is pulled up so the
chip stays off while the line is not driven.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Add the wcd9378 audio-codec parent node (reset gpio162, l7b/l8b/bob
supplies, 1.8 V micbias x3, rx/tx slave phandles), tx/rx port mappings
on the SoundWire slave nodes (ADC1/2/3 on device ports 1/2/3 all mapped
to master port 1, per the downstream volcano tx_swr_ch_map), the WCD
Capture dai-link on TX_CODEC_DMA_TX_3 and the capture audio-routing
(TX SWR_INPUTn inputs - the milos TX macro is a v9.2 variant, not the
SWR_ADCn naming qcm6490 uses).
The vreg_l8b regulator-always-on DTB hack is obsolete: the codec node
now holds vdd-buck.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Replace the transport-test skeleton with a functional driver modeled on
wcd937x: platform parent device (qcom,wcd9378-codec) as component master
over the two SoundWire slaves, owning reset GPIO, supplies and micbias
config; regmap (MAPLE cache, 32-bit paged SDCA addresses) on the TX
slave; capture DAI (index 1) with sdw stream plumbing; DAPM TX path
AMICn -> ADCn MUX -> TXn SEQUENCER -> ADCn_OUTPUT with the SDCA
SmartMIC power sequence (ITxx_USAGE mode, PDE11 PS0 request, HPF init
hold) and IT11_MICB-based refcounted micbias control; sys-usage profile
auto-selection; SCP bus-clock indication (base clk, busclock scale,
host-clk-div2) per the downstream capture-start sequence.
Verified on FP6: probes and binds without any manual per-boot hacks
(gpio162 reset, runtime PM force, l8b always-on all obsolete), sound
card registers, full DPCM/SoundWire/CDC-DMA transport carries data.
KNOWN ISSUE: the SmartMIC sequencer never leaves PWR_DN (PDE11_ACT_PS
stays PS3, SEQ_TX0_STAT=PWR_DN_RDY) although every register the
downstream driver writes has been replicated and verified on hardware
by bypassed readback - capture records digital silence. Investigation
notes in journal/mic.md.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Enable the RX (swr1) and TX (swr2) SoundWire controllers and describe
the two WCD9378 codec slave devices, as enumerated on hardware:
unique-id 4 on the RX bus, unique-id 3 on the TX bus, SoundWire id
sdw20217011000 (mfg 0x0217, part 0x0110). A firmware description is
required for the sdw core to bind a driver since dynamically enumerated
devices are visible but not bindable.
WIP: the codec node set is minimal (no port mappings, no codec parent
node yet); grows with the wcd9378 driver.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Bring-up skeleton for the Qualcomm WCD9378 codec (SoundWire dev id
0x0217:0x0110, one slave per RX/TX bus). Probes both slaves, maps the
SDCA control space (32-bit paged addresses) through regmap-sdw with
prop.paging_support set, and dumps the device identity registers on
ATTACHED as a transport self-test:
DEV_MANU_ID_0/1 = 0x17/0x02 (Qualcomm 0x0217)
DEV_PART_ID_0/1 = 0x10/0x01 (WCD9378 0x0110)
ANA_TX_CH1 0x20, ANA_MICB1 0x10 (downstream reset defaults)
The analog core is WCD937x register-compatible; full codec function
(TX/ADC path first) to be built on top of this. Not for upstream in
this form.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
The Qualcomm SoundWire controller driver ignored the paging fields of
struct sdw_msg, so any register access above the 16-bit address space
(e.g. the SDCA control space used by the WCD9378 codec) silently read
the low 15 bits only. The core already splits the address into
addr_page1/addr_page2 and sets msg->page; write the two SCP_AddrPage
registers through the command FIFO before the transfer, as the vendor
swr-mstr-ctrl driver does.
Verified on Fairphone 6 (SM7635): WCD9378 SDCA registers (0x40000000+)
read back their documented reset defaults; without this every paged
read returned zeros.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Configure the firmware-name and enable Iris so that hardware-accelerated
video decoding & encoding works.
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Add a node for the SPI-connected touchscreen, and its pinctrl.
WIP: Downstream touchscreen driver and bindings
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
10-bit DSC command mode is currently broken (2026-04-21). Keep it for
later given the panel works great also in 8-bit mode.
This reverts commit ea6afb55c1.
Configure the MDSS nodes for the phone and add the panel node.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Enable the NT37705 panel driver which is used on Fairphone (Gen. 6).
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Add support for the 2484x1116 AMOLED panel from BOE (BJ631JHM-T71-D900)
bundled with a NT37705 driver IC, as found on the Fairphone (Gen. 6)
smartphone.
The panel can also be configured in 10-bit (RGB101010) mode, however
currently it's configured in 8-bit (RGB888) since there's some issues in
the Qualcomm DPU driver when driving this panel in 10-bit.
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Novatek NT37705 is a display driver IC used to drive AMOLED DSI panels.
Describe it and the panel in the Fairphone (Gen. 6) (BJ631JHM-T71-D900
from BOE) using it.
Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Add GPU and GMU devicetree nodes for the Adreno 810 GPU found on
Qualcomm SM7635 (Milos) based devices.
The qcom,kaanapali-gxclkctl.h header can be reused here because
Milos uses the same driver and the GX_CLKCTL_GX_GDSC definition
is identical.
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
The GX GDSC control is handled through a dedicated clock controller,
and the enable/disable sequencing depends on correct rail voting.
The driver votes for the GX/GMxC rails and CX GDSC before toggling
the GX GDSC. Currently, during GMU runtime PM resume, rails remain
enabled due to upstream votes propagated via RPM-enabled devlinks
and explicit pm_runtime votes on GX GDSC.
This is not an expected behaviour of IFPC(Inter Frame Power Collapse)
requirements of GPU as GMU firmware is expected to control these rails,
except during the GPU/GMU recovery via the OS and that is where the GX
GDSC should be voting for the rails (GX/GMxC and CX GDSC) before
toggling the GX GDSC.
Thus, disable runtime PM after successfully registering the clock
controller.
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>