Summary
On MacBook Air M1 (J313), speakersafetyd panics immediately on garbage I/V sense data, so snd-soc-macaudio locks the speakers silent. Playback TDM is fine; capture (SDOUT / IV sense) is bit-shifted because tas2770 leaves TDM_CFG4 TX edge at the chip reset default (falling). Setting TX edge to rising makes IV sense valid and the daemon stays up.
Hardware / software
- Machine:
apple,j313 (MacBookAir10,1, M1 Air 2020)
- Kernel:
linux-asahi 7.1.13.asahi3-1 (7.1.13-3-1-ARCH)
speakersafetyd 2.0.1-1, asahi-audio 4.1-1
- Codecs:
ti,tas5770l / ti,tas2770 at i2c 1-0031 (Left) and 2-0034 (Right), bound to snd_soc_tas2770
DT sense slots (as expected):
- Left:
ti,imon-slot-no = 0, ti,vmon-slot-no = 2
- Right:
ti,imon-slot-no = 4, ti,vmon-slot-no = 6
Symptoms
speakersafetyd never stays running after boot. Typical panics:
Left: Negative power, bad ivsense data? (-4.68)
Left: Coil temperature limit exceeded (135.00 > 120)
Kernel then logs Speaker volumes locked: Main control not locked and analog output is silent even though PipeWire is playing to the j313 convolver / RawSpeakers.
The 135 °C trip happens within ~1s of a cold start (thermal model starts near 99 °C). That is not real coil heating; it is the model integrating garbage power.
What is not wrong
- Sense slots are programmed correctly (
TDM_CFG5/TDM_CFG6).
- Amps are active with ISENSE/VSENSE on (
PWR_CTRL = 0x00).
- Die temp via hwmon is ~31 °C, no latched faults.
- Playback path works: unlocking speakers briefly produced sound.
j313.conf channel map (is_chan/vs_chan 0/1 and 2/3, 4ch S16) is correct once SDOUT is aligned.
Register dump (while playing, speakers locked)
| Reg |
Left 1-0031 |
Right 2-0034 |
Meaning |
| 0x02 PWR_CTRL |
0x00 |
0x00 |
Active, I/V sense not powered down |
| 0x0A TDM_CFG0 |
0x08 |
0x08 |
96 kHz |
| 0x0C TDM_CFG2 |
0x1e |
0x1e |
32-bit slots |
| 0x0F TDM_CFG5 |
0x42 |
0x46 |
VSNS enable, slots 2 / 6 |
| 0x10 TDM_CFG6 |
0x40 |
0x44 |
ISNS enable, slots 0 / 4 |
| 0x0E TDM_CFG4 |
0x13 |
0x13 |
chip default: TX falling, offset 1, FILL |
tas2770_set_fmt() configures SDIN (RX). tas2770_codec_probe() sets IV TX slots in CFG5/CFG6 but does not program CFG4 TX edge, so SDOUT keeps the silicon reset value 0x13.
IV capture vs TX edge
arecord -D hw:AppleJ313,2 -c 4 -r 96000 -f S16_LE with speakers locked/silent:
| TDM_CFG4 |
Result |
0x13 (default, TX falling) |
Full-scale uncorrelated noise (RMS ~16k on S16), corr(ch0,ch1) ≈ 0, speakersafetyd-style power ≈ -0.14 W |
0x12 (same but TX rising) |
Real noise floor (RMS ~15–20), power ≈ 0 W |
0x03 (falling, no FILL) |
Still garbage / large negative power |
0x10 / 0x02 / 0x00 (rising) |
Quiet, like 0x12 |
So the failing bit is TDM_CFG4 bit 0 (TX_EDGE_FALLING). RX can use falling edge and still play; capture wants rising on this machine.
Workaround (confirmed)
i2cset -y -f 1 0x31 0x0E 0x12
i2cset -y -f 2 0x34 0x0E 0x12
systemctl restart speakersafetyd
After that, speakersafetyd stays running, volumes unlock, speakers work. CFG4 stays 0x12 across PCM open.
This is a userspace band-aid; it needs repeating after codec reset/probe (e.g. ExecStartPre on speakersafetyd.service).
Suggested kernel fix
In sound/soc/codecs/tas2770.c, program TDM TX edge/offset in tas2770_set_fmt() / probe so SDOUT matches Apple MCA capture (rising edge on J313), instead of leaving CFG4 at reset default. A DT property would be cleaner if other machines need falling.
Extra noise (probably unrelated)
First probe logs tas2770_i2c_probe: Failed to parse devicetree because SDZ supply is missing (supply SDZ not found, using dummy regulator); deferred probe then succeeds. IV slots are still set correctly after that.
Summary
On MacBook Air M1 (J313),
speakersafetydpanics immediately on garbage I/V sense data, sosnd-soc-macaudiolocks the speakers silent. Playback TDM is fine; capture (SDOUT / IV sense) is bit-shifted becausetas2770leaves TDM_CFG4 TX edge at the chip reset default (falling). Setting TX edge to rising makes IV sense valid and the daemon stays up.Hardware / software
apple,j313(MacBookAir10,1, M1 Air 2020)linux-asahi 7.1.13.asahi3-1(7.1.13-3-1-ARCH)speakersafetyd2.0.1-1,asahi-audio4.1-1ti,tas5770l/ti,tas2770at i2c1-0031(Left) and2-0034(Right), bound tosnd_soc_tas2770DT sense slots (as expected):
ti,imon-slot-no = 0,ti,vmon-slot-no = 2ti,imon-slot-no = 4,ti,vmon-slot-no = 6Symptoms
speakersafetydnever stays running after boot. Typical panics:Kernel then logs
Speaker volumes locked: Main control not lockedand analog output is silent even though PipeWire is playing to the j313 convolver / RawSpeakers.The 135 °C trip happens within ~1s of a cold start (thermal model starts near 99 °C). That is not real coil heating; it is the model integrating garbage power.
What is not wrong
TDM_CFG5/TDM_CFG6).PWR_CTRL = 0x00).j313.confchannel map (is_chan/vs_chan0/1 and 2/3, 4ch S16) is correct once SDOUT is aligned.Register dump (while playing, speakers locked)
1-00312-0034tas2770_set_fmt()configures SDIN (RX).tas2770_codec_probe()sets IV TX slots in CFG5/CFG6 but does not program CFG4 TX edge, so SDOUT keeps the silicon reset value0x13.IV capture vs TX edge
arecord -D hw:AppleJ313,2 -c 4 -r 96000 -f S16_LEwith speakers locked/silent:0x13(default, TX falling)corr(ch0,ch1) ≈ 0, speakersafetyd-style power ≈ -0.14 W0x12(same but TX rising)0x03(falling, no FILL)0x10/0x02/0x00(rising)0x12So the failing bit is TDM_CFG4 bit 0 (
TX_EDGE_FALLING). RX can use falling edge and still play; capture wants rising on this machine.Workaround (confirmed)
After that,
speakersafetydstays running, volumes unlock, speakers work. CFG4 stays0x12across PCM open.This is a userspace band-aid; it needs repeating after codec reset/probe (e.g.
ExecStartPreonspeakersafetyd.service).Suggested kernel fix
In
sound/soc/codecs/tas2770.c, program TDM TX edge/offset intas2770_set_fmt()/ probe so SDOUT matches Apple MCA capture (rising edge on J313), instead of leaving CFG4 at reset default. A DT property would be cleaner if other machines need falling.Extra noise (probably unrelated)
First probe logs
tas2770_i2c_probe: Failed to parse devicetreebecauseSDZsupply is missing (supply SDZ not found, using dummy regulator); deferred probe then succeeds. IV slots are still set correctly after that.