Commit 2124f8da authored by Lu Guanqun's avatar Lu Guanqun Committed by Greg Kroah-Hartman

intel_sst: internal speaker needs setting a GPIO line

On Moorestown platform, internal speaker's power line is connected to a GPIO
line, so we need to enable or disable it properly.
Reviewed-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Signed-off-by: default avatarJeff Cheng <jeff_cheng@wistron.com>
Signed-off-by: default avatarLu Guanqun <guanqun.lu@intel.com>
Signed-off-by: default avatarWang Xingchao <xingchao.wang@intel.com>
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b8df15b2
...@@ -120,6 +120,8 @@ struct snd_pmic_ops { ...@@ -120,6 +120,8 @@ struct snd_pmic_ops {
unsigned int hw_dmic_map[MFLD_MAX_HW_CH]; unsigned int hw_dmic_map[MFLD_MAX_HW_CH];
unsigned int available_dmics; unsigned int available_dmics;
int (*set_hw_dmic_route) (u8 index); int (*set_hw_dmic_route) (u8 index);
int gpio_amp;
}; };
extern void sst_mad_send_jack_report(struct snd_jack *jack, extern void sst_mad_send_jack_report(struct snd_jack *jack,
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/initval.h> #include <sound/initval.h>
#include <linux/gpio.h>
#include "intel_sst.h" #include "intel_sst.h"
#include "intel_sst_ioctl.h" #include "intel_sst_ioctl.h"
#include "intel_sst_fw_ipc.h" #include "intel_sst_fw_ipc.h"
...@@ -920,14 +921,20 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) ...@@ -920,14 +921,20 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev)
ret_val = snd_intelmad_create(intelmaddata, card); ret_val = snd_intelmad_create(intelmaddata, card);
if (ret_val) { if (ret_val) {
pr_err("snd_intelmad_create failed\n"); pr_err("snd_intelmad_create failed\n");
goto set_pvt_data;; goto set_pvt_data;
} }
card->private_data = &intelmaddata; card->private_data = &intelmaddata;
snd_card_set_dev(card, &pdev->dev); snd_card_set_dev(card, &pdev->dev);
ret_val = snd_card_register(card); ret_val = snd_card_register(card);
if (ret_val) { if (ret_val) {
pr_err("snd_card_register failed\n"); pr_err("snd_card_register failed\n");
goto set_pvt_data;; goto set_pvt_data;
}
if (pdev->dev.platform_data) {
int gpio_amp = *(int *)pdev->dev.platform_data;
if (gpio_request_one(gpio_amp, GPIOF_OUT_INIT_LOW, "amp power"))
gpio_amp = 0;
intelmaddata->sstdrv_ops->scard_ops->gpio_amp = gpio_amp;
} }
pr_debug("snd_intelmad_probe complete\n"); pr_debug("snd_intelmad_probe complete\n");
...@@ -957,6 +964,8 @@ static int snd_intelmad_remove(struct platform_device *pdev) ...@@ -957,6 +964,8 @@ static int snd_intelmad_remove(struct platform_device *pdev)
struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev); struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev);
if (intelmaddata) { if (intelmaddata) {
if (intelmaddata->sstdrv_ops->scard_ops->gpio_amp)
gpio_free(intelmaddata->sstdrv_ops->scard_ops->gpio_amp);
free_irq(intelmaddata->irq, intelmaddata); free_irq(intelmaddata->irq, intelmaddata);
snd_card_free(intelmaddata->card); snd_card_free(intelmaddata->card);
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/gpio.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/file.h> #include <linux/file.h>
#include <sound/control.h> #include <sound/control.h>
...@@ -86,6 +87,12 @@ enum reg_v3 { ...@@ -86,6 +87,12 @@ enum reg_v3 {
AUXDBNC = 0x12f, AUXDBNC = 0x12f,
}; };
static void nc_set_amp_power(int power)
{
if (snd_pmic_ops_nc.gpio_amp)
gpio_set_value(snd_pmic_ops_nc.gpio_amp, power);
}
/**** /****
* nc_init_card - initialize the sound card * nc_init_card - initialize the sound card
* *
...@@ -212,6 +219,16 @@ static int nc_power_up_pb(unsigned int port) ...@@ -212,6 +219,16 @@ static int nc_power_up_pb(unsigned int port)
msleep(30); 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)
nc_set_amp_power(1);
return nc_enable_audiodac(UNMUTE); return nc_enable_audiodac(UNMUTE);
} }
...@@ -273,7 +290,6 @@ static int nc_power_down(void) ...@@ -273,7 +290,6 @@ static int nc_power_down(void)
int retval = 0; int retval = 0;
struct sc_reg_access sc_access[5]; struct sc_reg_access sc_access[5];
if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT) if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
retval = nc_init_card(); retval = nc_init_card();
if (retval) if (retval)
...@@ -283,6 +299,10 @@ static int nc_power_down(void) ...@@ -283,6 +299,10 @@ static int nc_power_down(void)
pr_debug("powering dn nc_power_down ....\n"); pr_debug("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)
nc_set_amp_power(0);
msleep(30); msleep(30);
sc_access[0].reg_addr = DRVPOWERCTRL; sc_access[0].reg_addr = DRVPOWERCTRL;
...@@ -518,9 +538,12 @@ static int nc_set_selected_output_dev(u8 value) ...@@ -518,9 +538,12 @@ static int nc_set_selected_output_dev(u8 value)
switch (value) { switch (value) {
case STEREO_HEADPHONE: case STEREO_HEADPHONE:
retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2); retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2);
nc_set_amp_power(0);
break; break;
case MONO_EARPIECE:
case INTERNAL_SPKR: case INTERNAL_SPKR:
retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2); retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2);
nc_set_amp_power(1);
break; break;
default: default:
pr_err("rcvd illegal request: %d\n", value); pr_err("rcvd illegal request: %d\n", value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment