Accessing the state of HS_DET

Hi,

I’m using the Linaro software stack with a board that is compatible to the DB410. The signal HS_DET (pad K14 on PM8916) is accessible in the pinout and is routed to the headphone jack. Can anyone explain how the information whether a headset is connected can be accessed from software? I’d like to control a power domain based on the state of that signal, but the ASoC platform driver does not export a control or anything.

Thanks!
Daniel

Hi Daniel,

The functionality you’re looking for is called “MBHC” and is part of the “CDC_A_CODEC_ANALOG” hardware block in PM8916. It seems like the driver for this block does not deal with the MBHC support as of today though.

Regards,
Bjorn

Ah, thanks for the pointer. Yes, from the public datasheet, this seems to be the thing I need. I wonder, however, how boards make use of this signal at all at the moment.

I’d add support for that myself, but I don’t have access to the datasheets. Can anyone provide me with the necessary information to make the implementation? Is there work being done on this already?

Thanks!

Do you mean how this should be presented in the software? Or can you elaborate/rephrase your “question”?

There is the public PM8916 register specification and there are support in the downstream kernels to use as reference. Is there any additional information that you have in mind?

I’m not aware of any efforts of supporting this functionality.

Okay, I must have missed that. Can you point me to a downstream kernel that implements this?

You can find the downstream mbhc driver here:

sound/soc/codecs/wcd-mbhc-v2.c - kernel/msm - Git at Google

This is instantiated from following driver:

sound/soc/codecs/msm8x16-wcd.c - kernel/msm - Git at Google

The upstream driver for this hardware block can be found in:

sound/soc/codecs/msm8916-wcd-analog.c

Regards,
Bjorn

Hi @zonque

The “downstream” kernel that @bamse is referring to is the Android kernel. The Android kernel supports all of the hardware features but is based on a very old kernel (3.10 or 3.18 I think). Reading the downstream kernel is a very good reference on how to do something, but is usually very difficult to directly port to the latest upstream kernels. Instructions to download it and rebuild it are here: https://developer.qualcomm.com/download/db410c/linux-android-software-build-and-installation-guide.pdf . Once your development system is set up you can download the BSP from here: https://developer.qualcomm.com/download/db410c/android_board_support_package_vla.br_.1.2.7-01010-8x16.0-4.zip , unzip the package and run the DB410c_build.sh script, it will download all of the Android source and rebuild the image for you.

The “upstream” kernel is available from the Linaro web site by running the commands

git clone -n working/qualcomm/kernel.git - Qualcomm Landing Team kernel
git checkout -b build-250 529c1db225629896d51b64a481b3760fd81a663a

Your ‘challenge’ is to understand the downstream kernel, and write a driver for the upstream kernel to operate the MBHC. There is some additional useful information in this document: https://developer.qualcomm.com/download/sd410/pm8916pm8916-1-power-management-ic-device-specification.pdf and https://developer.qualcomm.com/download/sd410/pm8916-hardware-register-description.pdf

Hope this helps

Full disclosure: I am an employee of Qualcomm Canada, any opinions I may have expressed in this or any other post may not reflect the opinions of my employer.

@zonque I started porting some of the code to Linaro’s kernel, and simplifying it on the way because it’s quite convoluted, but I had issues with buttons on some headsets. You really need both the documentation and the reference implementation to understand how it works.

I had to do other things for a while but I’ll soon get back to that, so you can get in touch with me if you want to team up.

Really happy to see that. And I am hoping you will be able to share your contributions, see https://github.com/96boards/documentation/blob/master/ConsumerEdition/DragonBoard-410c/Downloads/Contribute.md. Even better if you can get things upstream first.

Ah, that’s good to hear! You are referring to the non-public parts of the documentation I take it?

Just so that I understand - how is that functionality exposed then? Is it an ALSA control, a Linux input device or something proprietary that one can hook up in an ALSA/ASoC machine driver?

Yes, please let me know when you get back to it!

Thanks,
Daniel

I meant the hardware register description that @ljking mentionned.

It appears as a Linux input device, so you can watch the events happen with evtest for instance.

Ideally it will be upstreamed. Linaro and upstream versions of the driver are quite alike, except some structures that changed names, so upstreaming and porting it back to Linaro’s kernel seems reasonable.

I think I’ll get back to it next week or the week after that.

@zonque it took me a bit longer than expected but I’ve just sent a series of patches upstream [1] for the support of the jack detection. So for now it’s limited to the mechanical switch. I’m working on cleaning up headset buttons detection but I have inconsistent results with different headsets, and a variety of other issues that I need to address.

It should be fairly easy to backport this series to a 4.4 kernel, and some extra tweaking might be required in pm8916.dtsi for the interrupt name and perhaps the interrupt flag should be changed to IRQ_TYPE_EDGE_RISING (that’s what I have locally but I am not sure this is necessary to make it work).

Let me know if you have any issue!

[edit: Srini replied to me that he has a more complete patchset coming up in a couple of days]

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-July/123135.html

Wow, thanks a ton for working on this, @damienr!

The patches apply to the 4.9 tree I’m based on, with one trivial exception.

It will take me some weeks before we get to test this, but jack sensing is all I need for now. I’ll get back to you as soon as I have results.

Thanks,
Daniel