Mic Detection Based on wm8994 in Android 4.x

Source: Internet
Author: User

Based on Android 4.4 and 4.2, codec used for detection is wm8994.

The mic detection in Android and Kernel is based on the headset detection. The specific process is as follows:

1) kernel uses Jack to detect pin interruption and detects that headphones are inserted.

2) read the codec register to determine whether the headset has mic

3) notify the Android upper layer through the InputEvent/UEvent Mechanism

For more information, see my previous article on plug-in and plug-in detection. This article is based on the UEvent mechanism, that is, the switch driver method.

1. mic Detection Principle

First, let's take a look at the differences between headphones with and without mic. For example, 3 for headphones without mic and 4 for headphones with mic, we can see that there is no difference between the two left-right channels. The difference is that the headphones without mic combine the two GND and MIC segments. Therefore, for headphones without mic, The GND and MIC segments are almost short-circuited (with a certain resistance), and the mic detection is based on this principle.


<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + signature + weight + Gy + weight + G9q8/weight + weight/weight + CjxwPiAgICAgICAgvt/M5bXEyejWw7/J0tSyzr + weight/K/brzu + weight/weight/ aOs0OjSqsrWtq/j6nbdvms05sb3tprc68jnz8kju1_vcd4kpha + PGJyPgo8L3A + CjxwcmUgY2xhc3M9 "brush: java; ">/* enable BIAS, MICBIAS1 and VMID in R01h */snd_soc_update_bits (codec, signature, signature | WM8994_BIAS_ENA | signature, wm8994_micbw.ena | signature | 1 <strong ); /* enable MICBIAS Current Detect */snd_soc_update_bits (codec, region, WM8994_MICD_ENA, reg);/* enable MICDETdeboune */snd_soc_update_bits (codec, region ); /* set MICDETthreshold */snd_soc_update_bits (codec, WM8994_MICBIAS, WM8994_MICD_THR_MASK, 0b100 <

Due to the binding of some registers and widgets, dapm disable the register when the widget powers down. Therefore, you need to modify the original code of codec:

1) In vmid_dereference, The MICBIAS and VMID registers should not be set back to 0, that is, the following line is canceled:

Snd_soc_update_bits (codec, WM8994_POWER_MANAGEMENT_1, WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0 );

2) For the widget corresponding to MICBIAS1, cancel the register bound to the original one. Modify the widget corresponding to MICBIAS in wm_hubs.c as follows:

SND_SOC_DAPM_SUPPLY ("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0 ),

-> SND_SOC_DAPM_SUPPLY ("MICBIAS1", SND_SOC_NOPM, 4, 0, NULL, 0 ),

3. Implementation in switch driver

The implementation of the switch driver is mentioned in the previous article. Here we can add the mic detection part based on the implemented switch driver.

As mentioned above, the interrupt processing function for plugging detection is generally processed as delayed work to prevent multiple interruptions during the plugging process. In the callback function of delayed work, the process is as follows:

1) read the GPIO level value. If it is a high (low) level, the headset is inserted. Whether it is high or low is related to the earphone detection mechanism, most of which are high-level inserts.

2) If the headset is detected to be inserted, read the Register on wm8994 codec for further judgment. The Code is as follows:


    mic = wm8994_reg_read(wm8994, WM8994_INTERRUPT_RAW_STATUS_2);    mic = (mic & WM8994_MIC2_DET_STS_MASK) >> WM8994_MIC2_DET_STS_SHIFT;    if(mic)          switch_set_state(&data->sdev, 2);  //no mic    else          switch_set_state(&data->sdev, 1);  //with mic


The biggest problem here is how to access the wm8994 register in the switch driver, that is, where to obtain the first parameter wm8994_reg_read above? Two methods are introduced here:

Register the switch device as a sub-device of the wm8994-core.c

It is necessary to first introduce the structure of the wm8994 driver. Since the control part of wm8994 (register settings) follows i2c, in linux kernel, wm8994 is first mounted under the i2c bus as an mfd device, is wm8994 core (corresponding file drivers/mfd/wm8994-core.c ). Under wm8994 core, several sub-devices (codec, gpio, and regulator) implement different functions.

Among them, codec (corresponding file sound/soc/codecs/wm8994.c) is a sub-Device of wm8994 core, and this sub-device is registered to ASOC. The other sub-devices (gpio and regulator) mentioned above are also some other applications of the wm8994 codec hardware. For example, codec can be used as a gpio or regulator device, kernel separately implements driver for these special applications.

I learned about the approximate structure of wm8994, here I borrowed the wm8994-regulator.c and gpio-wm8994.c access wm8994 register method, mount the switch device as a sub-device of the wm8994-core.c, the implementation code is as follows:


static struct mfd_cell wm8994_devs[] = {          {                   .name= "wm8994-codec",                   .num_resources= ARRAY_SIZE(wm8994_codec_resources),                   .resources= wm8994_codec_resources,          },           {                   .name= "wm8994-gpio",                   .num_resources= ARRAY_SIZE(wm8994_gpio_resources),                   .resources= wm8994_gpio_resources,                   .pm_runtime_no_callbacks= true,          },            /* hp detect switch driver*/          {                   .name= "xxx-hp-switch",          },};

In this way, the switch device is added to a sub-device of wm8994 core through wm8994_device_init-> mfd_add_devices. In the probe function of the switch driver, use the following statement:

Structwm8994 * wm8994 = dev_get_drvdata (pdev-> dev. parent );

You can obtain the wm8994 structure and call wm8994_reg_read to read the register.

? Register the switch device in wm8994 codecdriver

This method does not need to implement a separate switch driver. The entire detection process is integrated into the codec driver, which is equivalent to embedding the switch driver in the codec driver. The general process is as follows:

1) in the probe function of codec driver (sound/soc/codec/wm8994.c:

A) Call switch_dev_register to register a switch device.

B) applying for GPIO interruption

2) read the GPIO status and codec register in the interrupt processing function to determine whether the plug-in and mic exist. Use switch_set_state to set the current status.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.