mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Merge "ASoC: wcd: add notifier between codec and mbhc"
This commit is contained in:
commit
c3c9a38b28
4 changed files with 210 additions and 101 deletions
|
@ -118,11 +118,6 @@ enum {
|
|||
BAND_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
ON_DEMAND_MICBIAS = 0,
|
||||
ON_DEMAND_SUPPLIES_MAX,
|
||||
};
|
||||
|
||||
struct hpf_work {
|
||||
struct msm8x16_wcd_priv *msm8x16_wcd;
|
||||
u32 decimator;
|
||||
|
@ -132,33 +127,10 @@ struct hpf_work {
|
|||
|
||||
static struct hpf_work tx_hpf_work[NUM_DECIMATORS];
|
||||
|
||||
struct on_demand_supply {
|
||||
struct regulator *supply;
|
||||
atomic_t ref;
|
||||
};
|
||||
|
||||
static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
|
||||
"cdc-vdd-mic-bias",
|
||||
};
|
||||
|
||||
struct msm8x16_wcd_priv {
|
||||
struct snd_soc_codec *codec;
|
||||
u16 pmic_rev;
|
||||
u32 adc_count;
|
||||
u32 rx_bias_count;
|
||||
s32 dmic_1_2_clk_cnt;
|
||||
u32 mute_mask;
|
||||
bool mclk_enabled;
|
||||
bool clock_active;
|
||||
bool config_mode_active;
|
||||
bool spk_boost_set;
|
||||
bool ear_pa_boost_set;
|
||||
bool dec_active[NUM_DECIMATORS];
|
||||
struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
|
||||
/* mbhc module */
|
||||
struct wcd_mbhc mbhc;
|
||||
};
|
||||
|
||||
static unsigned long rx_digital_gain_reg[] = {
|
||||
MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
|
||||
MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL,
|
||||
|
@ -208,6 +180,31 @@ static const struct wcd_mbhc_cb mbhc_cb = {
|
|||
.enable_mb_source = msm8x16_wcd_enable_ext_mb_source,
|
||||
};
|
||||
|
||||
int msm8x16_unregister_notifier(struct snd_soc_codec *codec,
|
||||
struct notifier_block *nblock)
|
||||
{
|
||||
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
return blocking_notifier_chain_unregister(&msm8x16_wcd->notifier,
|
||||
nblock);
|
||||
}
|
||||
|
||||
int msm8x16_register_notifier(struct snd_soc_codec *codec,
|
||||
struct notifier_block *nblock)
|
||||
{
|
||||
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
return blocking_notifier_chain_register(&msm8x16_wcd->notifier, nblock);
|
||||
}
|
||||
|
||||
void msm8x16_notifier_call(struct snd_soc_codec *codec,
|
||||
const enum wcd_notify_event event)
|
||||
{
|
||||
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
pr_debug("%s: notifier call event %d\n", __func__, event);
|
||||
blocking_notifier_call_chain(&msm8x16_wcd->notifier, event, codec);
|
||||
}
|
||||
|
||||
static int get_spmi_msm8x16_wcd_device_info(u16 *reg,
|
||||
struct msm8x16_wcd_spmi **msm8x16_wcd)
|
||||
|
@ -1838,6 +1835,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
|
|||
snd_soc_update_bits(codec, micb_int_reg, 0x08, 0x08);
|
||||
else if (strnstr(w->name, internal3_text, 30))
|
||||
snd_soc_update_bits(codec, micb_int_reg, 0x01, 0x01);
|
||||
msm8x16_notifier_call(codec, WCD_EVENT_PRE_MICBIAS_2_ON);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (strnstr(w->name, internal1_text, 30)) {
|
||||
|
@ -1851,6 +1849,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
|
||||
0x45, 0x01);
|
||||
msm8x16_notifier_call(codec, WCD_EVENT_PRE_MICBIAS_2_OFF);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -3234,6 +3233,8 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
|
|||
on_demand_supply_name[ON_DEMAND_MICBIAS]);
|
||||
atomic_set(&msm8x16_wcd_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, 0);
|
||||
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&msm8x16_wcd_priv->notifier);
|
||||
|
||||
wcd_mbhc_init(&msm8x16_wcd_priv->mbhc, codec, &mbhc_cb, &intr_ids,
|
||||
false);
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#define MCLK_SUS_RSC 2
|
||||
#define MCLK_SUS_NO_ACT 3
|
||||
|
||||
#define NUM_DECIMATORS 2
|
||||
|
||||
extern const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE];
|
||||
extern const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE];
|
||||
extern const u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE];
|
||||
|
@ -105,6 +107,26 @@ enum {
|
|||
MSM8X16_WCD_NUM_IRQS,
|
||||
};
|
||||
|
||||
enum wcd_notify_event {
|
||||
WCD_EVENT_INVALID,
|
||||
/* events for micbias ON and OFF */
|
||||
WCD_EVENT_PRE_MICBIAS_2_OFF,
|
||||
WCD_EVENT_POST_MICBIAS_2_OFF,
|
||||
WCD_EVENT_PRE_MICBIAS_2_ON,
|
||||
WCD_EVENT_POST_MICBIAS_2_ON,
|
||||
/* events for PA ON and OFF */
|
||||
WCD_EVENT_PRE_HPHL_PA_ON,
|
||||
WCD_EVENT_POST_HPHL_PA_OFF,
|
||||
WCD_EVENT_PRE_HPHR_PA_ON,
|
||||
WCD_EVENT_POST_HPHR_PA_OFF,
|
||||
WCD_EVENT_LAST,
|
||||
};
|
||||
|
||||
enum {
|
||||
ON_DEMAND_MICBIAS = 0,
|
||||
ON_DEMAND_SUPPLIES_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* The delay list is per codec HW specification.
|
||||
* Please add delay in the list in the future instead
|
||||
|
@ -172,6 +194,31 @@ struct msm8x16_wcd {
|
|||
char __iomem *dig_base;
|
||||
};
|
||||
|
||||
struct on_demand_supply {
|
||||
struct regulator *supply;
|
||||
atomic_t ref;
|
||||
};
|
||||
|
||||
struct msm8x16_wcd_priv {
|
||||
struct snd_soc_codec *codec;
|
||||
u16 pmic_rev;
|
||||
u32 adc_count;
|
||||
u32 rx_bias_count;
|
||||
s32 dmic_1_2_clk_cnt;
|
||||
u32 mute_mask;
|
||||
bool mclk_enabled;
|
||||
bool clock_active;
|
||||
bool config_mode_active;
|
||||
bool spk_boost_set;
|
||||
bool ear_pa_boost_set;
|
||||
bool dec_active[NUM_DECIMATORS];
|
||||
struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
|
||||
/* mbhc module */
|
||||
struct wcd_mbhc mbhc;
|
||||
struct blocking_notifier_head notifier;
|
||||
|
||||
};
|
||||
|
||||
extern int msm8x16_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
|
||||
bool dapm);
|
||||
|
||||
|
@ -180,5 +227,11 @@ extern int msm8x16_wcd_hs_detect(struct snd_soc_codec *codec,
|
|||
|
||||
extern void msm8x16_wcd_hs_detect_exit(struct snd_soc_codec *codec);
|
||||
|
||||
extern int msm8x16_register_notifier(struct snd_soc_codec *codec,
|
||||
struct notifier_block *nblock);
|
||||
|
||||
extern int msm8x16_unregister_notifier(struct snd_soc_codec *codec,
|
||||
struct notifier_block *nblock);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "wcd9xxx-mbhc.h"
|
||||
#include "msm8x16_wcd_registers.h"
|
||||
#include "msm8916-wcd-irq.h"
|
||||
#include "msm8x16-wcd.h"
|
||||
|
||||
#define WCD_MBHC_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
|
||||
SND_JACK_OC_HPHR | SND_JACK_LINEOUT | \
|
||||
|
@ -43,6 +44,7 @@
|
|||
SND_JACK_BTN_4)
|
||||
#define OCP_ATTEMPT 1
|
||||
#define HS_DETECT_PLUG_TIME_MS (3 * 1000)
|
||||
#define SPECIAL_HS_DETECT_TIME_MS (2 * 1000)
|
||||
#define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250
|
||||
|
||||
#define WCD_MBHC_RSC_LOCK(mbhc) \
|
||||
|
@ -64,6 +66,49 @@
|
|||
"%s: BCL should have acquired\n", __func__); \
|
||||
}
|
||||
|
||||
static int wcd_event_notify(struct notifier_block *self, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
struct snd_soc_codec *codec = (struct snd_soc_codec *)data;
|
||||
struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
|
||||
struct wcd_mbhc *mbhc = &msm8x16_wcd->mbhc;
|
||||
enum wcd_notify_event event = (enum wcd_notify_event)val;
|
||||
|
||||
pr_debug("%s: event %d\n", __func__, event);
|
||||
switch (event) {
|
||||
/* MICBIAS usage change */
|
||||
case WCD_EVENT_PRE_MICBIAS_2_ON:
|
||||
if (mbhc->micbias_enable) {
|
||||
snd_soc_write(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0xC0);
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x18, 0x10);
|
||||
}
|
||||
/* Disable current source if micbias enabled */
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL,
|
||||
0xB0, 0x80);
|
||||
break;
|
||||
/* MICBIAS usage change */
|
||||
case WCD_EVENT_PRE_MICBIAS_2_OFF:
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x18, 0x00);
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0x20);
|
||||
/* Enable current source again for polling */
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL,
|
||||
0xB0, 0xB0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc)
|
||||
{
|
||||
struct wcd_mbhc_btn_detect_cfg *btn_det;
|
||||
|
@ -425,13 +470,8 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
~WCD_MBHC_JACK_BUTTON_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set micbias back to 1.8V if accessory was special
|
||||
* headset and thus micbias was increased to 2.8V
|
||||
*/
|
||||
if (mbhc->micbias_enable)
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0x20);
|
||||
mbhc->micbias_enable = false;
|
||||
|
||||
mbhc->zl = mbhc->zr = 0;
|
||||
mbhc->is_hs_inserted = false;
|
||||
|
@ -461,11 +501,8 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
jack_type == SND_JACK_LINEOUT) &&
|
||||
(mbhc->hph_status && mbhc->hph_status != jack_type)) {
|
||||
|
||||
if (mbhc->micbias_enable &&
|
||||
mbhc->hph_status == SND_JACK_HEADSET)
|
||||
snd_soc_write(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0x20);
|
||||
if (mbhc->micbias_enable)
|
||||
mbhc->micbias_enable = false;
|
||||
|
||||
mbhc->zl = mbhc->zr = 0;
|
||||
mbhc->is_hs_inserted = false;
|
||||
|
@ -560,6 +597,69 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc,
|
|||
pr_debug("%s: leave\n", __func__);
|
||||
}
|
||||
|
||||
static bool wcd_is_special_headset(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
u16 result2;
|
||||
struct snd_soc_codec *codec = mbhc->codec;
|
||||
int delay = 0;
|
||||
bool ret = false;
|
||||
s16 reg;
|
||||
|
||||
/*
|
||||
* Enable micbias if not already enabled
|
||||
* and disable current source if using micbias
|
||||
*/
|
||||
reg = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL,
|
||||
0xB0, 0x80);
|
||||
/* Enable micbias if not already enabled */
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x80, 0x80);
|
||||
pr_debug("%s: special headset, start register writes\n", __func__);
|
||||
result2 = snd_soc_read(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT);
|
||||
while (result2 & 0x01) {
|
||||
if (wcd_swch_level_remove(mbhc)) {
|
||||
pr_debug("%s: Switch level is low\n", __func__);
|
||||
break;
|
||||
}
|
||||
delay = delay + 50;
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_CTL,
|
||||
0x60, 0x60);
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0xC0);
|
||||
/* Wait for 50msec for MICBIAS to settle down */
|
||||
msleep(50);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x18, 0x10);
|
||||
/* Wait for 50msec for FSM to update result values */
|
||||
msleep(50);
|
||||
result2 = snd_soc_read(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT);
|
||||
if (!(result2 & 0x01))
|
||||
pr_debug("%s: Special headset detected in %d msecs\n",
|
||||
__func__, (delay * 2));
|
||||
if (delay == SPECIAL_HS_DETECT_TIME_MS) {
|
||||
pr_debug("%s: Spl headset didnt get detect in 4 sec\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(result2 & 0x01)) {
|
||||
pr_debug("%s: Headset with threshold found\n", __func__);
|
||||
mbhc->micbias_enable = true;
|
||||
ret = true;
|
||||
}
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_CTL, 0x60, 0x00);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x80, 0x00);
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, reg);
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL, 0x20);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x18, 0x00);
|
||||
|
||||
pr_debug("%s: leave\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wcd_correct_swch_plug(struct work_struct *work)
|
||||
{
|
||||
struct wcd_mbhc *mbhc;
|
||||
|
@ -568,7 +668,6 @@ static void wcd_correct_swch_plug(struct work_struct *work)
|
|||
unsigned long timeout;
|
||||
u16 result1, result2;
|
||||
bool wrk_complete = false;
|
||||
int delay = 0;
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
|
||||
|
@ -626,71 +725,15 @@ static void wcd_correct_swch_plug(struct work_struct *work)
|
|||
plug_type = MBHC_PLUG_TYPE_INVALID;
|
||||
|
||||
if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH) {
|
||||
/* Enable external voltage source to micbias if present */
|
||||
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
|
||||
mbhc->mbhc_cb->enable_mb_source(codec, true);
|
||||
|
||||
/* Enable micbias if not already enabled*/
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x80, 0x80);
|
||||
pr_debug("DEBUG special headset, start register writes");
|
||||
|
||||
result2 = snd_soc_read(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT);
|
||||
while (result2 & 0x01) {
|
||||
if (wcd_swch_level_remove(mbhc)) {
|
||||
pr_debug("%s: Switch level is low ", __func__);
|
||||
break;
|
||||
}
|
||||
delay = delay + 50;
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_1_CTL,
|
||||
0x60, 0x60);
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0xC0);
|
||||
/*
|
||||
* Special headset needs micbias voltage above 2.4,
|
||||
* it is taking time for micbias to rampup and
|
||||
* for result2 to change.This delay is also dependent
|
||||
* on type of headset.
|
||||
*/
|
||||
msleep(delay);
|
||||
snd_soc_update_bits(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x18, 0x10);
|
||||
msleep(50);
|
||||
result2 = snd_soc_read(codec,
|
||||
MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT);
|
||||
if (!(result2 & 0x01))
|
||||
pr_debug("spl headset detected in %d msecs",
|
||||
delay);
|
||||
if (delay == 2000) {
|
||||
pr_debug("spl headset not detected in 2 sec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result1 && !(result2 & 0x01)) {
|
||||
pr_debug("%s: Headset with threshold found\n",
|
||||
__func__);
|
||||
if (wcd_is_special_headset(mbhc)) {
|
||||
pr_debug("%s: Special headset found %d\n",
|
||||
__func__, plug_type);
|
||||
plug_type = MBHC_PLUG_TYPE_HEADSET;
|
||||
mbhc->micbias_enable = true;
|
||||
goto report;
|
||||
}
|
||||
/* Disable autozero and put micbias back to 1.8V */
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x18, 0x00);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_CTL,
|
||||
0x60, 0x00);
|
||||
snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
|
||||
0x80, 0x00);
|
||||
if (!mbhc->micbias_enable)
|
||||
snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
|
||||
0x20);
|
||||
|
||||
/* Disable external voltage source to micbias if present */
|
||||
if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
|
||||
mbhc->mbhc_cb->enable_mb_source(codec, false);
|
||||
}
|
||||
|
||||
report:
|
||||
wcd_mbhc_find_plug_and_report(mbhc, plug_type);
|
||||
exit:
|
||||
/* Disable external voltage source to micbias if present */
|
||||
|
@ -1280,6 +1323,14 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
|
|||
|
||||
}
|
||||
|
||||
/* Register event notifier */
|
||||
mbhc->nblock.notifier_call = wcd_event_notify;
|
||||
ret = msm8x16_register_notifier(codec, &mbhc->nblock);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register notifier %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&mbhc->wait_btn_press);
|
||||
mutex_init(&mbhc->codec_resource_lock);
|
||||
|
||||
|
@ -1352,6 +1403,7 @@ err_btn_release_irq:
|
|||
err_btn_press_irq:
|
||||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
|
||||
err_mbhc_sw_irq:
|
||||
msm8x16_unregister_notifier(codec, &mbhc->nblock);
|
||||
mutex_destroy(&mbhc->codec_resource_lock);
|
||||
err:
|
||||
pr_debug("%s: leave ret %d\n", __func__, ret);
|
||||
|
@ -1361,6 +1413,7 @@ EXPORT_SYMBOL(wcd_mbhc_init);
|
|||
|
||||
void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
struct snd_soc_codec *codec = mbhc->codec;
|
||||
|
||||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
|
||||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc);
|
||||
|
@ -1368,6 +1421,7 @@ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
|
|||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->mbhc_hs_ins_rem_intr, mbhc);
|
||||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->hph_left_ocp, mbhc);
|
||||
wcd9xxx_spmi_free_irq(mbhc->intr_ids->hph_right_ocp, mbhc);
|
||||
msm8x16_unregister_notifier(codec, &mbhc->nblock);
|
||||
mutex_destroy(&mbhc->codec_resource_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(wcd_mbhc_deinit);
|
||||
|
|
|
@ -104,6 +104,7 @@ struct wcd_mbhc {
|
|||
|
||||
/* Work to correct accessory type */
|
||||
struct work_struct correct_plug_swch;
|
||||
struct notifier_block nblock;
|
||||
};
|
||||
|
||||
#define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \
|
||||
|
|
Loading…
Reference in a new issue