[ARM] mfd: cpcap: Reduce audio dock pops
authorChris Fries <C.Fries@motorola.com>
Tue, 7 Dec 2010 18:26:32 +0000 (12:26 -0600)
committerIliyan Malchev <malchev@google.com>
Thu, 9 Dec 2010 20:19:20 +0000 (12:19 -0800)
Manage the audio dock and CPCAP Audio state tightly, to
avoid pops on the (amplified) docks.

Change-Id: Ie687b8fc19892eb1ea56f8aed2be78d2a4dcb334
Signed-off-by: Iliyan Malchev <malchev@google.com>
drivers/mfd/cpcap-whisper.c
drivers/mfd/tegra-cpcap-audio.c

index a5a46e43743dd9f080d3e32e545f1dffd85c9c7e..673871101a35f42bcaf7e4cbdd12cd4f875ae07b 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/spi/cpcap-regbits.h>
 #include <linux/spi/spi.h>
 
+void tegra_cpcap_audio_dock_state(bool connected);
 
 #define SENSE_USB_CLIENT    (CPCAP_BIT_ID_FLOAT_S  | \
                             CPCAP_BIT_VBUSVLD_S   | \
@@ -336,6 +337,7 @@ static void whisper_notify(struct cpcap_whisper_data *di, enum cpcap_accy accy)
                switch_set_state(&di->csdev, 0);
                memset(di->dock_id, 0, CPCAP_WHISPER_ID_SIZE);
                memset(di->dock_prop, 0, CPCAP_WHISPER_PROP_SIZE);
+               tegra_cpcap_audio_dock_state(false);
        }
 }
 
@@ -372,6 +374,7 @@ static void whisper_audio_check(struct cpcap_whisper_data *di)
 
        audio = (req.result[CPCAP_ADC_USB_ID] > ADC_AUDIO_THRES) ? 1 : 0;
        switch_set_state(&di->asdev, audio);
+       tegra_cpcap_audio_dock_state(!!audio);
 
        pr_info("%s: Audio cable %s present\n", __func__,
                (audio ? "is" : "not"));
index 1ba6c70d5f4f545746e221e9b809a9853f9f8b28..020592ab1af7a95614dcacc4e78afa8c2d429106 100644 (file)
@@ -43,6 +43,7 @@ static struct cpcap_audio_stream current_input = {
 };
 static int codec_rate;
 static int stdac_rate;
+static bool dock_connected;
 
 static int cpcap_audio_ctl_open(struct inode *inode, struct file *file)
 {
@@ -449,6 +450,21 @@ static struct miscdevice cpcap_audio_ctl = {
        .fops = &cpcap_audio_ctl_fops,
 };
 
+/* Couple the CPCAP and Dock audio state, to avoid pops */
+void tegra_cpcap_audio_dock_state(bool connected)
+{
+       pr_debug("%s: %s", __func__, connected ? "connected" : "disconnected");
+
+       mutex_lock(&cpcap_lock);
+       dock_connected = connected;
+       /* Borrow (unused) "ext output" to keep dock speaker amplifier on. */
+       pdata->state->ext_primary_speaker = dock_connected ?
+                       CPCAP_AUDIO_OUT_EMU_STEREO : CPCAP_AUDIO_OUT_NONE;
+       cpcap_audio_set_audio_state(pdata->state);
+       mutex_unlock(&cpcap_lock);
+}
+EXPORT_SYMBOL(tegra_cpcap_audio_dock_state);
+
 static int cpcap_audio_probe(struct platform_device *pdev)
 {
        int rc;