On Fri, Mar 25, 2011 at 09:03:36PM +0800, Arjan van de Ven wrote:
> On 3/24/2011 5:43 AM, Alan Cox wrote:
> >> This patch doesn't apply to your tree cleanly because there are some
> >> lines add by Arjan's patch tree. Should this patch better go to
> >> Arjan's patch tree?
> > Grumble.. can someone send me what is extra in Arjan's tree so we can
> > get this back straight and aligned.
> 
> actually the code in my tree was a bad hack put in place until the real 
> code went into your tree
> 
> I would not want that code in your tree at all....

Hi Arjan,

I've developed the new one according to Alan's suggestion (requesting a
gpio line, set the direction, and free it when it's unloaded.).

Would you please help to review this patch? Is it still a 'bad hack' in
your point of view?

Patch attached.

-- 
guanqun
>From bd249ff3390d2760887ec83ef86437dea0bcdb0b Mon Sep 17 00:00:00 2001
From: Lu Guanqun <[email protected]>
Date: Thu, 24 Mar 2011 22:28:56 +0800
Subject: [PATCH v4] sst: internal speaker needs setting a GPIO line

This patch originates from Jeff Cheng's patch to enable the internal speaker.

On Moorestown platform, internal speaker's power line is connected to a GPIO 
line,
so we need set it to 1 to enable the internal speaker, or set it to 0 to 
disable it.

When we set the output device, we power on or off the internal speaker on 
demand.

CC: "Koul, Vinod" <[email protected]>
CC: "Kp, Jeeja" <[email protected]>
Reviewed-by: Wu Fengguang <[email protected]>
Signed-off-by: Jeff Cheng <[email protected]>
Signed-off-by: Lu Guanqun <[email protected]>
Signed-off-by: Wang Xingchao <[email protected]>
---
 drivers/staging/intel_sst/intel_sst.h           |    2 ++
 drivers/staging/intel_sst/intelmid.c            |   15 +++++++++++++++
 drivers/staging/intel_sst/intelmid_v2_control.c |   21 ++++++++++++++++++++-
 3 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/intel_sst/intel_sst.h 
b/drivers/staging/intel_sst/intel_sst.h
index 986a3df..0d51842 100644
--- a/drivers/staging/intel_sst/intel_sst.h
+++ b/drivers/staging/intel_sst/intel_sst.h
@@ -120,6 +120,8 @@ struct snd_pmic_ops {
        unsigned int hw_dmic_map[MFLD_MAX_HW_CH];
        unsigned int available_dmics;
        int (*set_hw_dmic_route) (u8 index);
+
+       unsigned gpio_speaker_power_pin;
 };
 
 extern void sst_mad_send_jack_report(struct snd_jack *jack,
diff --git a/drivers/staging/intel_sst/intelmid.c 
b/drivers/staging/intel_sst/intelmid.c
index 3071904..66c786d 100644
--- a/drivers/staging/intel_sst/intelmid.c
+++ b/drivers/staging/intel_sst/intelmid.c
@@ -26,6 +26,7 @@
  */
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
@@ -918,6 +919,17 @@ int __devinit snd_intelmad_probe(struct platform_device 
*pdev)
                goto set_pvt_data;;
        }
 
+       if (intelmaddata->sstdrv_ops->scard_ops->gpio_speaker_power_pin) {
+               ret_val = gpio_request_one(intelmaddata->sstdrv_ops->
+                                             scard_ops->gpio_speaker_power_pin,
+                                          GPIOF_OUT_INIT_LOW,
+                                          "internal speaker power");
+               if (ret_val) {
+                       pr_err("sst: sst gpio request failed\n");
+                       goto set_pvt_data;
+               }
+       }
+
        pr_debug("sst:snd_intelmad_probe complete\n");
        return ret_val;
 
@@ -945,6 +957,9 @@ static int snd_intelmad_remove(struct platform_device *pdev)
        struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev);
 
        if (intelmaddata) {
+               if (intelmaddata->sstdrv_ops->scard_ops->gpio_speaker_power_pin)
+                       gpio_free(intelmaddata->sstdrv_ops->scard_ops->
+                                       gpio_speaker_power_pin);
                free_irq(intelmaddata->irq, intelmaddata);
                snd_card_free(intelmaddata->card);
        }
diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c 
b/drivers/staging/intel_sst/intelmid_v2_control.c
index 3ab10ca..f2785aa 100644
--- a/drivers/staging/intel_sst/intelmid_v2_control.c
+++ b/drivers/staging/intel_sst/intelmid_v2_control.c
@@ -26,6 +26,7 @@
  *  This file contains the control operations of vendor 3
  */
 
+#include <linux/gpio.h>
 #include <linux/pci.h>
 #include <linux/file.h>
 #include <sound/control.h>
@@ -209,6 +210,16 @@ static int nc_power_up_pb(unsigned int port)
 
        msleep(30);
 
+       /*
+        * There is a mismatch between Playback Sources and the enumerated
+        * values of output sources.  This mismatch causes ALSA upper to send
+        * Item 1 for Internal Speaker, but the expected enumeration is 2!  For
+        * now, treat MONO_EARPIECE and INTERNAL_SPKR identically and power up
+        * the needed resources
+        */
+       if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
+           snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)
+               gpio_set_value(snd_pmic_ops_nc.gpio_speaker_power_pin, 1);
        return nc_enable_audiodac(UNMUTE);
 
 }
@@ -270,7 +281,6 @@ static int nc_power_down(void)
        int retval = 0;
        struct sc_reg_access sc_access[5];
 
-
        if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
                retval = nc_init_card();
        if (retval)
@@ -280,6 +290,11 @@ static int nc_power_down(void)
 
        pr_debug("sst: powering dn nc_power_down ....\n");
 
+       if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
+           snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR) {
+               msleep(30);
+               gpio_set_value(snd_pmic_ops_nc.gpio_speaker_power_pin, 0);
+       }
        msleep(30);
 
        sc_access[0].reg_addr = DRVPOWERCTRL;
@@ -515,9 +530,12 @@ static int nc_set_selected_output_dev(u8 value)
        switch (value) {
        case STEREO_HEADPHONE:
                retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2);
+               gpio_set_value(snd_pmic_ops_nc.gpio_speaker_power_pin, 0);
                break;
+       case MONO_EARPIECE:
        case INTERNAL_SPKR:
                retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2);
+               gpio_set_value(snd_pmic_ops_nc.gpio_speaker_power_pin, 1);
                break;
        default:
                pr_err("sst: rcvd illegal request: %d\n", value);
@@ -1066,4 +1084,5 @@ struct snd_pmic_ops snd_pmic_ops_nc = {
        .power_down_pmic        =       nc_power_down,
        .pmic_irq_cb    =       nc_pmic_irq_cb,
        .pmic_jack_enable =     nc_jack_enable,
+       .gpio_speaker_power_pin =       64+16+2,
 };
-- 
1.7.2.3

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to