My Librem mini comes with a an audio jack in the front into which I can
plug the same headphones-with-micro as used typically on phones.
This works fine to the extent that I can hear the audio out and it can
grab the audio from the microphone, but what about the buttons
(typically used to increase/decrease volume and stop/play music)?
How can I capture those events to make them do something useful?
Maybe we live in different worlds, but in my world, almost all headphones come combined with a microphone and with 3 buttons. When I plug them into my LineageOS smartphone, those buttons let me control the volume as well as start/play the music.
I lived without a smartphone until somewhat recently, but AFAIK these “headphones with mic and 3 buttons” have been standard for ages and still come bundled with many smartphones (and they live on in the Bluetooth world, just without the jack and cable).
Are those phone controls specific to each OS, though?
The behavior attached to each button is controlled by software, of course, and can be application-specific, AFAIK. Other than that, I don’t know what the hardware-level “protocol” looks like, but I haven’t noticed any incompatibilities (nor mention of "only works with " or "designed for " in advertisements or packages), so I assume it’s been standardized by now.
First of all of course the codec needs to support this, i.e. the impedance sensing and converting this into some unsolicited events to the HDA. Then the HDA needs to pick that up and generate some form of input events for that.
Many devices use Realtek ALC* codecs these days, also the Librem Mini and the Lbrem 14 does have one too. Only some of them actually support this type of impedance sensing and decoding.
The other problem is that this is, I think, not implemented in the Linux HDA sound drivers yet. And kind of worse is that also most devices do not configure this in the BIOS. In most devices, I also just learned this while digging through the HDA stuff for the Librem 14, the codec get initialized by so called ‘verbs’ by the BIOS. The codecs are scary complex these days and allow a very high degree of flexibility to route and process signals. The verbs tell the codec what is attached to which input or output - analogue mic, digital mic, headphones, speakers etc. The verbs also specify which unsolicited events the codec shall be allowed to send back to the HDA controller in the main CPU. And it seems most of the time in PC like devices like these verbs are setup just for the most straight forward things - mic input, speakers, headphones and that’s it.
So while it may technically be possible to support these buttons found on many cable headsets the infrastructure does not seem to be there, I’m afraid. I would also think that this, since it there most of the time, would be cool to support. But I can tell you from kind of painful experience right now that this is a non trivial effort and takes man many hours of hard work.
That being said, if someone would like to help to implement that, please get in touch with me and I’ll gladly see how we can support such effort (with information about our hardware etc.).
Thanks Nicole, very helpful.
So, IIUC it would require changes both in the kernel sound drivers and in the BIOS (tho from what I read at https://www.kernel.org/doc/html/v4.17/sound/hd-audio/notes.html, the driver can override the BIOS’s config of the codec, so maybe the BIOS doesn’t need to be changed (tho in our case we can change it easily, AFAIK))?
Your message doesn’t make it clear whether the Librem mini hardware (i.e. its ALC* codec) does indeed support this feature, in theory. Can you confirm that it does?
If you are desperate to have that kind of functionality then maybe a USB dongle can do the trick. I know my USB to 3.5mm audio has a volume control on it (on the actual USB dongle) and that the volume control is correctly handled by Linux. (From memory, on the Linux side, as is usual with USB devices, it can present multiple interfaces, including in this case audio control i.e. on top of audio in and audio out.) However you would have to do your research that the USB dongle supported the control on the 3.5mm side.