ALSA subsystem (17) ------Support Type-C headphone driver

Hello! Here is Kite's blog,

Welcome to communicate with me.


The headphone driver was explained before:
ALSA subsystem (16) ------ virtual headphone driver
Android audio subsystem (4) --- headphone plugging process

So it is inevitable that there are more Type-C headphones on the market now.
TYPEC

There are two common TYPE-C headphones:

  • One is to connect 3.5mm headphones through a TYPE-C to 3.5mm adapter cable, which is essentially an analog headset, and the signal is still through HPOUT.
  • One is the real TYPE-C earphones, which are all-in-one, and are essentially digital earphones. There is a DAC inside the earphones to convert digital signals into analog signals (some TYPE-C earphones are also integrated, without adapters, but they are counterfeit TYPE-C earphones, there is no DAC decoding chip inside, which is equivalent to a TYPE-C to 3.5mm+ analog earphone packaged inside) .

1. TYPE-C analog headphones through a 3.5mm adapter cable

It is relatively simple to simply convert HPOUT to USB (TYPE-C), just add a conversion chip, let's look at the hardware implementation:

USB_SWITCH
Among them, USB0-DP-USBC and USB0-DM-USBC are connected to the TYPE-C socket.
In this way, as long as you pull EN high and SEL low according to the truth table, the path is:
APB <-> DAC/ADC <-> HPOUTL/R <-> USB0-DP/M-USBC <-> TYPE-C interface is
inserted like this Typec earphones, if you use HPOUT for broadcasting, the earphones can hear the sound. Therefore, in theory, without any TYPE-C chip driver, configure IO to pull EN high and SEL low, and you can use TYPE-C analog headphones for broadcasting. You don’t need to write any drivers, it’s very simple~

but! ! ! !
able
How do we detect the insertion and removal of typec headphones?
So in fact, we will use a TYPE-C control chip to detect when the TYPE-C earphone is plugged in and identify what device is plugged in.
Here we use the wusb3801 typec control chip.
typec
The circuit is relatively simple, the driver code can be found on GitHub, just search for wusb3801, I will not post the code here.
Plugging in an earphone will trigger an INT interrupt, and the code will determine what earphone is plugged in, and then control the EN and SEL pins of the USB/AUDIO SWITCH chip for function selection.

2. Integrated TYPE-C digital earphones

For real TYPE-C headphones, which are actually digital headphones, the USB sound card is used, and the USB channel is selected. ( Need to confirm that CONFIG_SND_USB_AUDIO is turned on in the kernel. )
After inserting the TYPE-C earphone, through the USB-ID pin of the wusb3801 chip, the USB will switch to Host mode. At this time, if the TYPE-C is inserted, it will be registered as a USB sound card.
After I plug in the Huawei TYPE-C headset here, I will find that there is an extra sound card:

console:/ # cat /proc/asound/cards
0 [HEADSET ]: USB-Audio - HUAWEI USB-C HEADSET
bestechnic HUAWEI USB-C HEADSET at usb-sunxi-ohci-1, full speed

Then write data to this Huawei headset sound card, and you can hear the sound on the headset~

The last experiment was time to find a problem!
Theoretically, there is no difference between the front and back of the Type-C interface, both sides are the same, but in fact, using Type-C earphones, it is found that it is no problem to plug in the Type-C earphones (side A) and turn it over (side B). Type-C headphones, there will be a problem of data crosstalk between the left and right channels!

This is mainly due to the addition of the MIC/GND SWTICH chip.
mic
SBU1 and SBU2 are respectively connected to SBU1 and SBU2 of the Type-C socket.
typec

By default, SEL is low level. At this time, HPOUTFB is connected to SBU1, and HS_MIC is connected to SBU2.
When plugging in the front (A side), SBU1 corresponds to Type-C SBU1, and SBU2 corresponds to Type-C SBU2, which is no problem.
When plugged in reverse (side B), SBU1 corresponds to SBU2 of Type-C, and SBU2 corresponds to SBU1 of Type-C, so there is a problem of crosstalk between the left and right channels of the earphone.

Therefore, in theory, when plugging in reverse (side B), we need to pull up the SEL pin of the MIC/GND SWTICH chip, which is correct.

So how do we judge whether it is a positive insertion or a reverse insertion?
Rely on the mic!

This blog is well written: mic detection based on wm8994 under Android 4.x

First look at the difference between the earphones with mic and the earphones without mic, as shown in the figure below, the earphones without mic have 3 segments, and the earphones with mic have 4 segments. Comparing the actual products, it can be seen that the left and right channel segments of the two are different. The difference, the difference is that the headphones without mic combine the two sections of GND and MIC. Therefore, for headphones without mic, the two sections of GND and MIC are almost short-circuited (with a certain resistance), and mic detection is based on this principle.

headset

In order to realize recording, it is necessary to apply a certain bias voltage on the MIC section, that is, micbias. For headphones without mic, since MIC and GND are combined into one section, it is equivalent to grounding micbias, so a relatively large current will be generated. Some codecs support the current detection function. When the current exceeds a certain threshold, the corresponding register will be set to 1, so that the result can be queried.

We need to identify which is the MIC, rely on the MIC ADC value to judge whether it is front or back, and the driver will try to control the SEL pin to switch.

static void wait_and_detect_mic_gnd_state(struct sound_card_priv *priv)
{
    
    
	int reg_val;
	int threshold = 0x8;

	gpio_set_value(priv->mic_gnd_sw_gpio, 0);//尝试先拉低SEL
	reg_val = snd_soc_read(priv->codec, SUNXI_HMIC_STS);//读取ADC的值
	reg_val = (reg_val >> HMIC_DATA) & 0x1f;
	if (reg_val >= threshold) {
    
    //大于阈值,是mic
		return;//是mic,则直接返回,保留SEL为低电平
	} else {
    
    
		gpio_set_value(priv->mic_gnd_sw_gpio, 1);//否则拉高SEL
	}

	return;
}

Guess you like

Origin blog.csdn.net/Guet_Kite/article/details/117529642