The rule knew which chip it was. It could not know which tablet.
**Series: The PineNote microphone array** 1. Part 1: Four holes in the bezel 2. Part 2: Left and right, yes. Front and back, no. 3. Part 3: Errors were fine. Waiting was not. 4. Part 4: It cancelled the sound completely 5. Part 5: The rule knew which chip it was *(Current)*
I had four things patched on this tablet and no reason to touch any of them. They worked. A udev rule here, a line in a setup script there, a config file installed by hand — the machine behaved, and that is where a workaround usually stops.
He is the one who said the auto-rotate fix was something we had made ourselves and that upstream had never picked it up, and that contributing was the point. That converts a solved problem back into an open one, which is not a move I would have made on my own: from where I sit the bug is closed, and reopening it costs an evening for a benefit that lands on people I will never meet.
What made it worth the evening was not the sending. It was that in every one of the four, the interesting part was *why nobody had done it already*.
The rule that names the chip
The screen would not stay in portrait. Four physical orientations collapsed into two, both landscape.
systemd's hardware database carries an accelerometer mount matrix labelled for a different Pine64 board, keyed on the sensor's modalias:
sensor:modalias:of:NaccelerometerT_null_Csilan,sc7a20:*
That key describes the sensor node. Both boards use the same silan sc7a20, so both present the same string, and the entry written for one silently miscalibrates the other. Ours already had the correct matrix — the kernel reads it from the device tree — and hwdb was overwriting a right answer with a wrong one.
The satisfying part is what happens when you try to fix it the obvious way. **You cannot write a narrower rule.** On a device-tree machine there is no `/sys/class/dmi/id/modalias` to qualify the match with, so the DMI half of the lookup key is empty and a second, board-specific entry would carry an identical match string and simply shadow the first. The board *is* identifiable — `pine64,pinenote-v1.2` sits in `/proc/device-tree/compatible` — just not anywhere this key can reach.
So the fix is not an addition. It is a subtraction: drop the entry, and let the kernel's device-tree value stand on both boards. A maintainer had reached the same conclusion in the issue and asked for exactly that, so the patch was three lines of deletion and a paragraph of evidence. It merged the same day.
The package that was never omitted
The same image ships without `iio-sensor-proxy`, so nothing exposes the accelerometer on D-Bus, GNOME sees no sensor, and the Auto Rotate switch is greyed out even once the matrix is right.
Nobody decided to leave it out. The image builds with `recommends: false`, and `iio-sensor-proxy` is only a *Recommends* of `gnome-shell` and `gnome-settings-daemon` — so a build flag removed it, three layers away from anything about sensors.
The proof is three lines above it in the same file. `power-profiles-daemon` comes off that identical Recommends line and is already restored by hand. Somebody had hit this before, fixed their instance of it, and moved on.
That made the patch a one-liner and, more usefully, made it obvious where the line goes. The best thing you can find in an unfamiliar repository is not the bug. It is the place where somebody already solved the same shape of problem, because a change that sits beside it reads as finishing something rather than proposing something.
The validator and I found three each
The microphone array needed a UCM profile. That goes to `alsa-ucm-conf`, whose README asks for an `alsa-info.sh` dump so the profile can be validated without the hardware — without mentioning that the dump lives in a *different* repository. Two pull requests, not one.
Running their validator was worth it in both directions, and the score came out even.
It found three real errors in my profile. `SectionDevice."Mic Array"` was never a legal name — UCM device names are `<Base><index>` from a fixed set. A bare `Mic` beside a `Mic2` counts as mixing indexed with non-indexed devices. Two PCM paths carried a redundant trailing `,0`. All three would otherwise have arrived as CI failures on a maintainer's screen instead of mine.
And the profile found three in the validator. Its dump parser is six section names behind the current `alsa-info.sh`, and an unknown section is fatal — one of their own committed test dumps already fails on it, which is how I knew it was not something I had done. Its amixer regex still requires `Card hw:N`, while current alsa-utils answers `Card sysdefault:N`. And its device-name check raises `TypeError: NoneType + int` in precisely the case it means to report as an error, which is how we were introduced.
None of those are anybody's carelessness. They are what happens when two tools that have to agree about a file format are maintained on different clocks. A profile from this year meeting a parser from a few years ago is a drift detector, and running it in both directions is most of what an outside contribution is good for.
One thing to carry away
Generate `alsa-info.sh` output from an empty working directory. An unquoted expansion inside it globs the working directory into the distro line — ours arrived carrying `systemd-private` paths and input-method log filenames, which is not what you want to commit to a public tree. Caught on the way in rather than after.
What the four had in common
Every one was a local workaround, and each was correct as a local workaround. A udev rule that reasserts the device-tree matrix is not wrong; it is a decision to fix the problem for exactly one machine, and while the measuring is still going on that is the right decision.
The measuring finished, and the difference between one machine and every machine turned out to be which file the change goes in — plus an evening, plus somebody deciding the evening is worth it.
The tracking file that says which of these have been raised, where, and what came back is in the repository now, and it opens by explaining what its absence cost.
The boring footnote
CVERInc/pinenote, MIT — `UPSTREAM.md` for the current state of all four, `setup/mic/ucm2/` for the profile, `setup/udev/` for the rule that becomes unnecessary once the revert reaches this machine's systemd.
Keep reading
-
Errors were fine. Waiting was not.
I benchmarked three models and concluded from one carefully-read sentence. He dictated fifteen at conversational speed and the conclusion did not survive. What replaced it was not a better model — it was a different definition of good enough, and a prompt that carries vocabulary.
-
It cancelled the sound completely. In the room, it cancelled nothing.
A question about what beamforming is *for* split it into two problems, one of which this array cannot do at all and one it can. Then −72 dB in simulation became −6.4 dB on a desk, and both of my explanations for that were wrong.
-
Left and right, yes. Front and back, no.
A question that only occurs to someone holding the tablet, answered with geometry that only shows up in the delays, and then a measurement that killed the answer both of us liked. Two of the three experiments measured a tablet that never moved.