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>
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>
When the clock controller is probed with 'use_rpm' enabled, the
runtime PM reference is currently released using pm_runtime_put(),
which may return before the runtime suspend has completed. When the
clock controller device is registered through this function, calling
pm_runtime_disable() immediately after pm_runtime_put() prevents
the runtime suspend from completing, leaving the clock controller
active and the HW rails in the ON state.
Use pm_runtime_put_sync() instead to ensure the runtime PM “putV
completes synchronously during probe. This does not have any functional
impact, but it guarantees that the device is fully runtime-suspended
before returning.
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
The GX GDSC represents a special GPU power domain that must not be
disabled during normal runtime PM flows. As per the GMU architecture,
GX GDSC should only be force-disabled during GMU/GPU recovery, where the
OS explicitly resets the GX power domain.
However, when managed by the generic GDSC runtime PM path, GX GDSC may be
disabled during GMU runtime suspend, resulting in warnings such as:
gx_clkctl_gx_gdsc status stuck at 'on'
and failures in gdsc_toggle_logic() during rpm suspend.
Use the newly added custom disable callback for gx_gdsc to ensure the
GDSC is toggled only in recovery scenarios, while preventing unintended
disable attempts during normal GMU runtime PM operations.
Reported-by: Pengyu Luo <mitltlatltl@gmail.com>
Closes: https://lore.kernel.org/all/CAH2e8h4Vp9fJYAUUbOmoHSKB25wakPBvmpwa62BTRqgRQbMWuw@mail.gmail.com/
Reported-by: Alexander Koskovich <akoskovich@pm.me>
Closes: https://lore.kernel.org/all/gwVAH2mJerU4dBInw8pKmOs5aQK55Q7W6q_UQAlLFCsEgX6eyvSgXAWbNNMqAX4WmPlYCKUSMhfkr5Jry4Ps5EqnxYZqEEDd3Whwv7ZXGlc=@pm.me/
Fixes: 5af11acae6 ("clk: qcom: Add a driver for SM8750 GPU clocks")
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
The GX GDSC is a special power domain that should only be disabled
by OS during GMU recovery. In all other scenarios, the GMU firmware
is responsible for handling its disable sequence, and OS must not
interfere.
During the resume_noirq() phase of system resume, the GenPD framework
enables all power domains and later disables them in the complete()
phase if there are no active votes from OS. This behavior can
incorrectly disable the GX GDSC while the GMU firmware is still using
it.
To prevent this, implement a custom disable callback for GX GDSC that
relies on GenPD’s synced_poweroff flag. The GMU driver sets this flag
only during recovery, allowing OS to explicitly disable GX GDSC in
hardware in that case. In all other situations, the disable callback
will avoid touching GX GDSC hardware.
Signed-off-by: Jagadeesh Kona <jagadeesh.kona@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Add a node for the GX clock controller, which provides a power domain to
consumers.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Jagadeesh Kona <jagadeesh.kona@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Configure and enable the node for IPA which enables mobile data on this
device.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Add the description of the IPA block in the Milos SoC.
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>
Add a node for the IMEM found on Milos, which contains pil-reloc-info
and the modem tables for IPA, among others.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>