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
