Merge "ASoC: wcd9xxx: register available conditions to resource manager"
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 6909ba7..9a19d9a 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -4058,6 +4058,9 @@
}
wcd9xxx_disable_irq(codec->control_data, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
+ wcd9xxx_regmgr_cond_register(resmgr, 1 << WCD9XXX_COND_HPH_MIC |
+ 1 << WCD9XXX_COND_HPH);
+
pr_debug("%s: leave ret %d\n", __func__, ret);
return ret;
@@ -4083,6 +4086,9 @@
{
void *cdata = mbhc->codec->control_data;
+ wcd9xxx_regmgr_cond_deregister(mbhc->resmgr, 1 << WCD9XXX_COND_HPH_MIC |
+ 1 << WCD9XXX_COND_HPH);
+
wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_RELEASE, mbhc);
wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_POTENTIAL, mbhc);
wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.c b/sound/soc/codecs/wcd9xxx-resmgr.c
index be11e53..9633cc0 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr.c
@@ -652,15 +652,17 @@
return rc;
}
-void wcd9xxx_resmgr_cond_trigger_cond(struct wcd9xxx_resmgr *resmgr,
- enum wcd9xxx_resmgr_cond cond)
+static void wcd9xxx_resmgr_cond_trigger_cond(struct wcd9xxx_resmgr *resmgr,
+ enum wcd9xxx_resmgr_cond cond)
{
struct list_head *l;
struct wcd9xxx_resmgr_cond_entry *e;
bool set;
pr_debug("%s: enter\n", __func__);
- set = !!test_bit(cond, &resmgr->cond_flags);
+ /* update bit if cond isn't available or cond is set */
+ set = !test_bit(cond, &resmgr->cond_avail_flags) ||
+ !!test_bit(cond, &resmgr->cond_flags);
list_for_each(l, &resmgr->update_bit_cond_h) {
e = list_entry(l, struct wcd9xxx_resmgr_cond_entry, list);
if (e->cond == cond)
@@ -672,6 +674,44 @@
pr_debug("%s: leave\n", __func__);
}
+/*
+ * wcd9xxx_regmgr_cond_register : notify resmgr conditions in the condbits are
+ * avaliable and notified.
+ * condbits : contains bitmask of enum wcd9xxx_resmgr_cond
+ */
+void wcd9xxx_regmgr_cond_register(struct wcd9xxx_resmgr *resmgr,
+ unsigned long condbits)
+{
+ unsigned int cond;
+
+ for_each_set_bit(cond, &condbits, BITS_PER_BYTE * sizeof(condbits)) {
+ mutex_lock(&resmgr->update_bit_cond_lock);
+ WARN(test_bit(cond, &resmgr->cond_avail_flags),
+ "Condition 0x%0x is already registered\n", cond);
+ set_bit(cond, &resmgr->cond_avail_flags);
+ wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+ mutex_unlock(&resmgr->update_bit_cond_lock);
+ pr_debug("%s: Condition 0x%x is registered\n", __func__, cond);
+ }
+}
+
+void wcd9xxx_regmgr_cond_deregister(struct wcd9xxx_resmgr *resmgr,
+ unsigned long condbits)
+{
+ unsigned int cond;
+
+ for_each_set_bit(cond, &condbits, BITS_PER_BYTE * sizeof(condbits)) {
+ mutex_lock(&resmgr->update_bit_cond_lock);
+ WARN(!test_bit(cond, &resmgr->cond_avail_flags),
+ "Condition 0x%0x isn't registered\n", cond);
+ clear_bit(cond, &resmgr->cond_avail_flags);
+ wcd9xxx_resmgr_cond_trigger_cond(resmgr, cond);
+ mutex_unlock(&resmgr->update_bit_cond_lock);
+ pr_debug("%s: Condition 0x%x is deregistered\n", __func__,
+ cond);
+ }
+}
+
void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
enum wcd9xxx_resmgr_cond cond, bool set)
{
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.h b/sound/soc/codecs/wcd9xxx-resmgr.h
index aaf7317..e6a8f5d 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.h
+++ b/sound/soc/codecs/wcd9xxx-resmgr.h
@@ -134,6 +134,7 @@
struct wcd9xxx_mbhc *mbhc;
unsigned long cond_flags;
+ unsigned long cond_avail_flags;
struct list_head update_bit_cond_h;
struct mutex update_bit_cond_lock;
@@ -227,6 +228,10 @@
WCD9XXX_COND_HPH = 0x01, /* Headphone */
WCD9XXX_COND_HPH_MIC = 0x02, /* Microphone on the headset */
};
+void wcd9xxx_regmgr_cond_register(struct wcd9xxx_resmgr *resmgr,
+ unsigned long condbits);
+void wcd9xxx_regmgr_cond_deregister(struct wcd9xxx_resmgr *resmgr,
+ unsigned long condbits);
int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
enum wcd9xxx_resmgr_cond cond,
unsigned short reg, int shift,