User:AlexL/Fairphone 4 audio development documentation
Current progress on FP4 audio development
WIP
- Configure ALSA to use wcd9830 driver as microphone
- Add audio-rouing to sound in dtsi
- There is a difference regarding LPASS tx macro version, 9.0 (sm8250) vs. 9.2 (sm8450) has different dapm widgets and routing. sc7280 (fp5) seems to be 9.4 but in the driver it's 9.0, see remark there
- 9.2 SWR_INPUT0 routed "TX SMIC MUX0", "SWR_MIC0", "TX SWR_INPUT0"
- 9.0 SWR_INPUT0 routed "TX SMIC MUX0", "ADC0", "TX SWR_ADC0"
- There is a difference regarding LPASS tx macro version, 9.0 (sm8250) vs. 9.2 (sm8450) has different dapm widgets and routing. sc7280 (fp5) seems to be 9.4 but in the driver it's 9.0, see remark there
Question Mark
- LPASS reset missing
- qcom-soundwire 3230000.soundwire: Failed to get cgcr reset ctrl required for SW gating
- Removed swr_audio_cgcr for now from dtsi, as it is optional, but WCD does not come up (timeout)
- SM8250 lpass-audiocc does not provide a reset (why?))
Done
- Migrating code fragments from FP5 WCD9385
- wcd938x_codec, soundwire init problem
- soundwire config unclear (clocks, pin config)
- Added wcd9380 devicetree from fp5 with devicetree picker
- Changed some regulators to match Fairphone 4
- DIN-ports mismatch
- qcom-soundwire 3230000.soundwire: din-ports (3) mismatch with controller (6) ...
- Adjusted the number of ports
- Can be removed maybe as it is marked as deprecated
- seems ok now
- qcom-soundwire 3230000.soundwire: probe with driver qcom-soundwire failed with error -75 ... -> EOVERFLOW Value too large for defined data type -> so, a configuration value is wrong, but which?
- -> let's debug the qcom-soundwire loading
- Added debug messages for modprobe... qcom,ports-offset1 data is not long enough
- adde values from Android kona-port-config.h (kona is used by lagoon devicetree, kona = sm8250)
- seems ok now
- Soundwire devices for tx and rx get bound, but no further action
- IRQ handlers are wrong, add correct IRQ for swr0 and swr1
- Soundwire enumeration starts now and and finds a device
- Soundwire interface seems to be running now!
/home/user # ls -l /sys/bus/soundwire/devices/ total 0 lrwxrwxrwx 1 root root 0 Aug 23 02:44 sdw-master-2-0 -> ../../../devices/platform/soc@0/3210000.soundwire/sdw-master-2-0 lrwxrwxrwx 1 root root 0 Aug 23 02:44 sdw-master-3-0 -> ../../../devices/platform/soc@0/3230000.soundwire/sdw-master-3-0 lrwxrwxrwx 1 root root 0 Aug 23 02:44 sdw:2:0:0217:010d:00:4 -> ../../../devices/platform/soc@0/3210000.soundwire/sdw-master-2-0/sdw:2:0:0217:010d:00:4 lrwxrwxrwx 1 root root 0 Aug 23 02:44 sdw:3:0:0217:010d:00:3 -> ../../../devices/platform/soc@0/3230000.soundwire/sdw-master-3-0/sdw:3:0:0217:010d:00:3
- ALSA refuses to work when the WCD Capture dai-link is added
- q6routing 3000000.remoteproc:glink-edge:apr:service@8:routing: ASoC: Failed to add route MM_DL1(*) -> [MultiMedia1] -> HDMI Mixer (and more of those)
- These seem to be hardcoded routes inside sound/soc/qcom/qdsp6/q6routing.c, need to check out what this means...
- Behaviour is similar on Kernel 7.2.0
- Suspect that some needed audio widgets are missing MM_DL1, Multimedia Downlink 1
- SOLUTION: The loading order of "q6routing 3000000.remoteproc:glink-edge:apr:service@8:routing" and "q6asm-dai 3000000.remoteproc:glink-edge:apr:service@7:dais" was wrong, q6routing requires dapm widgets that get created by dais
- Moving the wcd-capture-dai-link from the separate dtsi-file to the sm7225-fairphone-fp4.dts resoluted the loading order
Code base
- https://github.com/sm6350-mainline/linux.git
- branch sm6350-7.0.y
- commit 0382354568b163a891d854ed77ed90c13173b374 (7.0.8 stable release)
- Patches: https://github.com/AlexLedis/linux/tree/sm6350-7.0.y
Soundwire config
Config of soundwire taken from Android (LineageOS), techpack/audio/asoc/kona-port.config.h
/*
* Add port configuration in the format
*{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl}
*/
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0},
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
};
static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
};
Converted format for dtsi:
rx:
qcom,ports-word-length = [ 01 07 04 FF FF FF FF FF ];
qcom,ports-sinterval-low = [ 03 1F 1F 07 00 FF FF FF ];
qcom,ports-offset1 = [ 00 00 0B 01 00 FF FF FF ];
qcom,ports-offset2 = [ 00 00 0B 00 00 FF FF FF ];
qcom,ports-lane-control = [ 01 00 00 00 00 FF FF FF ];
qcom,ports-block-pack-mode = [ FF 00 01 FF FF FF FF FF ];
qcom,ports-hstart = [ FF 03 FF FF FF FF FF FF ];
qcom,ports-hstop = [ FF 06 FF FF FF FF FF FF ];
qcom,ports-block-group-count = [ FF FF FF FF 00 FF FF FF ];
tx:
qcom,ports-word-length = [ FF FF FF FF FF FF FF FF ];
qcom,ports-sinterval-low = [ FF 03 03 03 03 FF FF FF ];
qcom,ports-offset1 = [ FF 01 02 01 00 FF FF FF ];
qcom,ports-offset2 = [ FF 00 00 00 00 FF FF FF ];
qcom,ports-lane-control = [ FF 00 00 00 00 FF FF FF ];
qcom,ports-block-pack-mode = [ FF FF FF FF FF FF FF FF ];
qcom,ports-hstart = [ FF FF FF FF FF FF FF FF ];
qcom,ports-hstop = [ FF FF FF FF FF FF FF FF ];
qcom,ports-block-group-count = [ FF FF FF FF FF FF FF FF ];
- sdw20217010d00 is a soundwire slave device (drivers/soundwire/slave.c)
- SDW Version 0x2
- Manufacturer 0x0217 -> Qualcomm Incorporated
- Part ID 0x010d -> WCD938x
- class ID 0x00
- Microphone codec driver
- sound/soc/codecs/wcd938x.c
- compatible = "qcom,wcd9380-codec"
Notes
- https://codeberg.org/AlexLedis/Linux-Devicetree-Picker-AL
- https://wiki.postmarketos.org/wiki/MSM8916_Mainlining#Audio
- https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/soundwire/qcom%2Csoundwire.yaml
- FP4 wcd WIP: https://github.com/z3ntu/linux/commits/sm6350-6.16.y-wip-audio-speaker-mic/
- FP5: https://github.com/sc7280-mainline/linux/commits/sc7280-7.1.y/
- FP5 wcd: https://github.com/sc7280-mainline/linux/commits/sc7280-6.14.y-wip-wcd/
- soundwire swr config can be adopted from android like here, kona sound, as defined in the Android source, kona = sm8250
- https://www.kernel.org/doc/html/latest/sound/soc/codec-to-codec.html
- https://www.kernel.org/doc/Documentation/devicetree/bindings/soc/qcom/qcom%2Capr-services.yaml
- https://www.youtube.com/watch?v=2ffZT7so6RE (LIS25 227 Overview of audio subsystem on Qualcomm devices)
Driver debugging notes
- Reload a driver manually (e.g soundwire_qcom)
- rmmod soundwire_qcom
- lsmod | grep soundwire_qcom
- modprobe soundwire_qcom
- Show failed deferred driver probe
- cat /sys/kernel/debug/devices_deferred
CONFIG_DYNAMIC_DEBUG=y CONFIG_DYNAMIC_DEBUG_CORE=y
- Enable kernel debug
- cat /proc/config.gz | gunzip | grep CONFIG_DYNAMIC_DEBUG
- Check debugfs
- mount | grep debugfs
Devictree cheat sheet
nodes:
node-name@unit-address:
Node names are free to choose!
The unit-address must match the first address specified in the reg property
compatible:
stringlist to help the operating system find a driver, list from specific to generic
recommended (!): "manufacturer,model"
model:
string that specifies the manufacturer’s model number of the device
recommended (!): "manufacturer,model"
phandle:
numerical identifier for a node, used to reference other nodes (better use labels!)
status:
"okay", "disabled", "reserved", "fail", "fail-sss" (Error code sss)
req:
Address of the node in the address space, arbitrary number of (address, length) pairs
If the parent node has #size-cells = 0, length is omitted
#address-cells and #size-cells:
#address-cells, number of <u32> cells used to encode the address field in a child node’s reg property
#size-cells, number of <u32> cells used to encode the size field in a child node’s reg property.
#<specifier>-cells:
defines the number of cells required to encode a specifier for a domain
#sound-dai-cells = < 0x1 >; -> sound-dai = < &wcd9385 0x1 > (1 phandle + 1 cell)
properties:
32-bit cells:
A 64-bit value is represented with two 32-bit cells. The first value contains the most significant bits of the integer.
Example: <0x11223344 0x55667788>
bytestring:
A bytestring is enclosed in square brackets [ ] with each byte represented by two hexadecimal digits. Spaces between each byte are optional.
Example: local-mac-address = [00 00 c2 3a 56 78];
Qualcom Audio Architecure
From: srinivas.kandagatla-AT-linaro.org Subject: [PATCH v3 00/25] ASoC: qcom: Add support to QDSP based Audio Date: Tue, 13 Feb 2018 16:58:12 +0000
This patchset aims to provide a very basic version of QCOM DSP based audio support which is available in downstream andriod kernels. This patchset only support Digital audio based for HDMI-RX and will add support to other features as we move on.
QDSP has both static and dynamic modules. static modules like AFE (Audio FrontEnd), ADM (Audio Device Manager), ASM(Audio Stream Manager) and CORE to provide this audio services. All these services use APR (Asynchronous Packet Router) protocol via smd/glink transport to communicate with Application processor. More details on each module is availble in there respective patch.
This patchset is tested on DB820c, with HDMI audio playback on top of mainline, also tested slimbus analog audio using wcd9355 with an additional small patch.
Here is block diagram to give a quick overview of the components
+---------+ +---------+ +---------+
| q6asm | |q6routing| | q6afe |
| fedai | <------> | mixers | <-----> | bedai |
+---------+ +---------+ +---------+
^ ^ ^
| | |
| +------------------+----------------+ |
| | | | |
v v v v v
+---------+ +---------+ +---------+
| q6ASM | | q6ADM | | q6AFE |
+---------+ +---------+ +---------+
^ ^ ^ ^
| | | CPU Side |
------+---------------------+-------------------+--------
| | |
| |APR(smd/glink) |
| | |
| +------------------+----------------+ |
| | | | |
+-----+--+-----------------------------------+--+-------
| | | | | QDSP Side |
v v v v v v
+---------+ +---------+ +---------+
| ASM | <------> | ADM | <-----> | AFE |
+---------+ +---------+ +---------+
^
|
+-------------------+
|
---------------------------+--------------------------
| Audio I/O |
v v
+--------------------------------------------------+
| Audio devices |
| CODEC | HDMI-TX | PCM | SLIMBUS | I2S |MI2S |...|
| |
+--------------------------------------------------+
ALSA Notes
- https://www.kernel.org/doc/html/latest/sound/index.html
- https://docs.kernel.org/sound/soc/dai.html (ASoC Digital Audio Interface (DAI))
- https://docs.kernel.org/sound/soc/dapm.html (Dynamic Audio Power Management for Portable Devices)
Important
- Make sure to name your corresponding cpu and codec playback and capture dai names ending with “Playback” and “Capture” respectively as dapm core will link and power those dais based on the name.
ALSA ASoC Overview
- ASoC Codec Class Driver
- hardware independent code
- snd_soc_dai_driver
- Codec DAI and PCM configuration
- Codec control IO - using RegMap API
- Mixers and audio controls
- Codec audio operations
- DAPM description
- DAPM event handler
- ASoC Platform Driver
- only target the SoC CPU and must have no board specific code
- DMA
- DAI
- Digital audio interface (DAI) description
- Digital audio interface configuration
- PCM’s description
- SYSCLK configuration
- Suspend and resume (optional)
- DSP
- DAPM graph
- Mixer controls
- DMA IO to/from DSP buffers (if applicable)
- Definition of DSP front end (FE) PCM devices.DAPM graph
- ASoC Machine Driver
- codec and platform specific code
- snd_soc_card
- probe()
- Machine DAI Configuration (glues all the codec and CPU DAIs together.)
ALSA Fairphone 4
- Machine Driver
- dtsi node: "sound: sound", file: sm6350.dtsi
- compatible: fairphone,fp4-sndcard ?!? should be more generic? e.g. qcom,sm8250-sndcard
- sound/soc/qcom/sm8250.c
- Clock?
- dtsi node: "q6afecc: clock-controller", file: sm6350.dtsi
- compatible: qcom,q6afe-clocks
- sound/soc/qcom/qdsp6/q6afe-clocks.c
- USB?
- dtsi node: q6usbdai: usbd
- compatible: qcom,q6usb
- Routing?
- dtsi node: q6routing: routing
- compatible: qcom,q6adm-routing
- DSP Core Service
- dtsi node: service@3
- compatible: qcom,q6core
- Audio Front End Service
- dtsi node: "q6afe: service@4", file: sm6350.dtsi
- dtsi node: "q6afedai: dais", file: sm6350.dtsi
- compatible: qcom,q6afe-dai
- sound/soc/qcom/qdsp6/q6afe-dai.c
- Audio Stream Manager Service
- dtsi node: q6asm: service@7
- compatible: qcom,q6asm
- Audio Device Manager Service
- dtsi node: q6adm: service@8
- compatible: qcom,q6adm