mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'devel' of git.alsa-project.org:alsa-kernel into topic/misc
This commit is contained in:
@@ -394,6 +394,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
+ HZ/100);
|
||||
/* move new_hw_ptr according jiffies not pos variable */
|
||||
new_hw_ptr = old_hw_ptr;
|
||||
hw_base = delta;
|
||||
/* use loop to avoid checks for delta overflows */
|
||||
/* the delta value is small or zero in most cases */
|
||||
while (delta > 0) {
|
||||
@@ -403,8 +404,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
delta--;
|
||||
}
|
||||
/* align hw_base to buffer_size */
|
||||
hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
|
||||
delta = 0;
|
||||
hw_ptr_error(substream,
|
||||
"hw_ptr skipping! %s"
|
||||
"(pos=%ld, delta=%ld, period=%ld, "
|
||||
@@ -412,9 +411,12 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
in_interrupt ? "[Q] " : "",
|
||||
(long)pos, (long)hdelta,
|
||||
(long)runtime->period_size, jdelta,
|
||||
((hdelta * HZ) / runtime->rate), delta,
|
||||
((hdelta * HZ) / runtime->rate), hw_base,
|
||||
(unsigned long)old_hw_ptr,
|
||||
(unsigned long)new_hw_ptr);
|
||||
/* reset values to proper state */
|
||||
delta = 0;
|
||||
hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
|
||||
}
|
||||
no_jiffies_check:
|
||||
if (delta > runtime->period_size + runtime->period_size / 2) {
|
||||
|
||||
+22
-26
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
|
||||
struct hda_pincfg *pin;
|
||||
unsigned int oldcfg;
|
||||
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
|
||||
return -EINVAL;
|
||||
|
||||
oldcfg = snd_hda_codec_get_pincfg(codec, nid);
|
||||
pin = look_up_pincfg(codec, list, nid);
|
||||
if (!pin) {
|
||||
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_shutup_pins - Shut up all pins
|
||||
* @codec: the HDA codec
|
||||
*
|
||||
* Clear all pin controls to shup up before suspend for avoiding click noise.
|
||||
* The controls aren't cached so that they can be resumed properly.
|
||||
*/
|
||||
void snd_hda_shutup_pins(struct hda_codec *codec)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < codec->init_pins.used; i++) {
|
||||
struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
|
||||
/* use read here for syncing after issuing each verb */
|
||||
snd_hda_codec_read(codec, pin->nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
|
||||
|
||||
static void init_hda_cache(struct hda_cache_rec *cache,
|
||||
unsigned int record_size);
|
||||
static void free_hda_cache(struct hda_cache_rec *cache);
|
||||
@@ -3537,32 +3559,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
|
||||
|
||||
/**
|
||||
* snd_hda_add_nids - assign nids to controls from the array
|
||||
* @codec: the HDA codec
|
||||
* @kctl: struct snd_kcontrol
|
||||
* @index: index to kctl
|
||||
* @nids: the array of hda_nid_t
|
||||
* @size: count of hda_nid_t items
|
||||
*
|
||||
* This helper function assigns NIDs in the given array to a control element.
|
||||
*
|
||||
* Returns 0 if successful, or a negative error code.
|
||||
*/
|
||||
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
|
||||
unsigned int index, hda_nid_t *nids, unsigned int size)
|
||||
{
|
||||
int err;
|
||||
|
||||
for ( ; size > 0; size--, nids++) {
|
||||
err = snd_hda_add_nid(codec, kctl, index, *nids);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_add_nids);
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state);
|
||||
|
||||
@@ -898,6 +898,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int cfg);
|
||||
int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
|
||||
hda_nid_t nid, unsigned int cfg); /* for hwdep */
|
||||
void snd_hda_shutup_pins(struct hda_codec *codec);
|
||||
|
||||
/*
|
||||
* Mixer
|
||||
|
||||
@@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
|
||||
{ \
|
||||
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
|
||||
struct hda_codec *codec = hwdep->private_data; \
|
||||
char *after; \
|
||||
codec->type = simple_strtoul(buf, &after, 0); \
|
||||
unsigned long val; \
|
||||
int err = strict_strtoul(buf, 0, &val); \
|
||||
if (err < 0) \
|
||||
return err; \
|
||||
codec->type = val; \
|
||||
return count; \
|
||||
}
|
||||
|
||||
|
||||
+19
-32
@@ -356,6 +356,7 @@ struct azx_dev {
|
||||
*/
|
||||
unsigned char stream_tag; /* assigned stream */
|
||||
unsigned char index; /* stream index */
|
||||
int device; /* last device number assigned to */
|
||||
|
||||
unsigned int opened :1;
|
||||
unsigned int running :1;
|
||||
@@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip)
|
||||
*/
|
||||
|
||||
/* assign a stream for the PCM */
|
||||
static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
|
||||
static inline struct azx_dev *
|
||||
azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
|
||||
{
|
||||
int dev, i, nums;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
struct azx_dev *res = NULL;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
dev = chip->playback_index_offset;
|
||||
nums = chip->playback_streams;
|
||||
} else {
|
||||
@@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
|
||||
}
|
||||
for (i = 0; i < nums; i++, dev++)
|
||||
if (!chip->azx_dev[dev].opened) {
|
||||
chip->azx_dev[dev].opened = 1;
|
||||
return &chip->azx_dev[dev];
|
||||
res = &chip->azx_dev[dev];
|
||||
if (res->device == substream->pcm->device)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
if (res) {
|
||||
res->opened = 1;
|
||||
res->device = substream->pcm->device;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* release the assigned stream */
|
||||
@@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
|
||||
int err;
|
||||
|
||||
mutex_lock(&chip->open_mutex);
|
||||
azx_dev = azx_assign_device(chip, substream->stream);
|
||||
azx_dev = azx_assign_device(chip, substream);
|
||||
if (azx_dev == NULL) {
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return -EBUSY;
|
||||
@@ -2695,32 +2704,10 @@ static struct pci_device_id azx_ids[] = {
|
||||
/* ULI M5461 */
|
||||
{ PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
|
||||
/* NVIDIA MCP */
|
||||
{ PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
|
||||
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
||||
.class_mask = 0xffffff,
|
||||
.driver_data = AZX_DRIVER_NVIDIA },
|
||||
/* Teradici */
|
||||
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
|
||||
/* Creative X-Fi (CA0110-IBG) */
|
||||
|
||||
@@ -343,8 +343,6 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
|
||||
const struct snd_pci_quirk *tbl);
|
||||
int snd_hda_add_new_ctls(struct hda_codec *codec,
|
||||
struct snd_kcontrol_new *knew);
|
||||
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
|
||||
unsigned int index, hda_nid_t *nids, unsigned int size);
|
||||
|
||||
/*
|
||||
* unsolicited event handler
|
||||
|
||||
@@ -244,8 +244,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
|
||||
if (!kctl)
|
||||
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
|
||||
for (i = 0; kctl && i < kctl->count; i++) {
|
||||
err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
|
||||
spec->input_mux->num_items);
|
||||
err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -442,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ad198x_shutup(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_shutup_pins(codec);
|
||||
}
|
||||
|
||||
static void ad198x_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
@@ -455,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
|
||||
snd_array_free(&spec->kctls);
|
||||
}
|
||||
|
||||
static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
|
||||
hda_nid_t hp)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
|
||||
!spec->inv_eapd ? 0x00 : 0x02);
|
||||
snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
|
||||
!spec->inv_eapd ? 0x00 : 0x02);
|
||||
}
|
||||
|
||||
static void ad198x_power_eapd(struct hda_codec *codec)
|
||||
{
|
||||
/* We currently only handle front, HP */
|
||||
switch (codec->vendor_id) {
|
||||
case 0x11d41882:
|
||||
case 0x11d4882a:
|
||||
case 0x11d41884:
|
||||
case 0x11d41984:
|
||||
case 0x11d41883:
|
||||
case 0x11d4184a:
|
||||
case 0x11d4194a:
|
||||
case 0x11d4194b:
|
||||
ad198x_power_eapd_write(codec, 0x12, 0x11);
|
||||
break;
|
||||
case 0x11d41981:
|
||||
case 0x11d41983:
|
||||
ad198x_power_eapd_write(codec, 0x05, 0x06);
|
||||
break;
|
||||
case 0x11d41986:
|
||||
ad198x_power_eapd_write(codec, 0x1b, 0x1a);
|
||||
break;
|
||||
case 0x11d41988:
|
||||
case 0x11d4198b:
|
||||
case 0x11d4989a:
|
||||
case 0x11d4989b:
|
||||
ad198x_power_eapd_write(codec, 0x29, 0x22);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ad198x_free(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
@@ -462,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec)
|
||||
if (!spec)
|
||||
return;
|
||||
|
||||
ad198x_shutup(codec);
|
||||
ad198x_free_kctls(codec);
|
||||
kfree(spec);
|
||||
snd_hda_detach_beep_device(codec);
|
||||
}
|
||||
|
||||
#ifdef SND_HDA_NEEDS_RESUME
|
||||
static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
{
|
||||
ad198x_shutup(codec);
|
||||
ad198x_power_eapd(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad198x_resume(struct hda_codec *codec)
|
||||
{
|
||||
ad198x_init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct hda_codec_ops ad198x_patch_ops = {
|
||||
.build_controls = ad198x_build_controls,
|
||||
.build_pcms = ad198x_build_pcms,
|
||||
@@ -475,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
.check_power_status = ad198x_check_power_status,
|
||||
#endif
|
||||
#ifdef SND_HDA_NEEDS_RESUME
|
||||
.suspend = ad198x_suspend,
|
||||
.resume = ad198x_resume,
|
||||
#endif
|
||||
.reboot_notify = ad198x_shutup,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -753,6 +753,7 @@ static int build_input(struct hda_codec *codec)
|
||||
spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
int n;
|
||||
if (!spec->capture_bind[i])
|
||||
return -ENOMEM;
|
||||
kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
|
||||
@@ -762,10 +763,13 @@ static int build_input(struct hda_codec *codec)
|
||||
err = snd_hda_ctl_add(codec, 0, kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
|
||||
spec->num_inputs);
|
||||
if (err < 0)
|
||||
return err;
|
||||
for (n = 0; n < AUTO_PIN_LAST; n++) {
|
||||
if (!spec->adc_nid[n])
|
||||
continue;
|
||||
err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->num_inputs > 1 && !spec->mic_detect) {
|
||||
|
||||
@@ -345,8 +345,7 @@ static int cmi9880_build_controls(struct hda_codec *codec)
|
||||
/* assign Capture Source enums to NID */
|
||||
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
|
||||
for (i = 0; kctl && i < kctl->count; i++) {
|
||||
err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids,
|
||||
spec->input_mux->num_items);
|
||||
err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
+323
-61
File diff suppressed because it is too large
Load Diff
@@ -338,7 +338,7 @@ struct alc_spec {
|
||||
void (*init_hook)(struct hda_codec *codec);
|
||||
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
void (*power_hook)(struct hda_codec *codec, int power);
|
||||
void (*power_hook)(struct hda_codec *codec);
|
||||
#endif
|
||||
|
||||
/* for pin sensing */
|
||||
@@ -391,7 +391,7 @@ struct alc_config_preset {
|
||||
void (*init_hook)(struct hda_codec *);
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
struct hda_amp_list *loopbacks;
|
||||
void (*power_hook)(struct hda_codec *codec, int power);
|
||||
void (*power_hook)(struct hda_codec *codec);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1835,16 +1835,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
|
||||
spec->autocfg.speaker_pins[2] = 0x1b;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
static void alc889_power_eapd(struct hda_codec *codec, int power)
|
||||
{
|
||||
snd_hda_codec_write(codec, 0x14, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
|
||||
snd_hda_codec_write(codec, 0x15, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ALC880 3-stack model
|
||||
*
|
||||
@@ -2548,8 +2538,10 @@ static int alc_build_controls(struct hda_codec *codec)
|
||||
if (!kctl)
|
||||
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
|
||||
for (i = 0; kctl && i < kctl->count; i++) {
|
||||
err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
|
||||
spec->input_mux->num_items);
|
||||
hda_nid_t *nids = spec->capsrc_nids;
|
||||
if (!nids)
|
||||
nids = spec->adc_nids;
|
||||
err = snd_hda_add_nid(codec, kctl, i, nids[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@@ -3691,6 +3683,11 @@ static int alc_build_pcms(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void alc_shutup(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_shutup_pins(codec);
|
||||
}
|
||||
|
||||
static void alc_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
@@ -3711,17 +3708,47 @@ static void alc_free(struct hda_codec *codec)
|
||||
if (!spec)
|
||||
return;
|
||||
|
||||
alc_shutup(codec);
|
||||
alc_free_kctls(codec);
|
||||
kfree(spec);
|
||||
snd_hda_detach_beep_device(codec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
static void alc_power_eapd(struct hda_codec *codec)
|
||||
{
|
||||
/* We currently only handle front, HP */
|
||||
switch (codec->vendor_id) {
|
||||
case 0x10ec0260:
|
||||
snd_hda_codec_write(codec, 0x0f, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
snd_hda_codec_write(codec, 0x10, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
break;
|
||||
case 0x10ec0262:
|
||||
case 0x10ec0267:
|
||||
case 0x10ec0268:
|
||||
case 0x10ec0269:
|
||||
case 0x10ec0272:
|
||||
case 0x10ec0660:
|
||||
case 0x10ec0662:
|
||||
case 0x10ec0663:
|
||||
case 0x10ec0862:
|
||||
case 0x10ec0889:
|
||||
snd_hda_codec_write(codec, 0x14, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
snd_hda_codec_write(codec, 0x15, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int alc_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
alc_shutup(codec);
|
||||
if (spec && spec->power_hook)
|
||||
spec->power_hook(codec, 0);
|
||||
spec->power_hook(codec);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3729,16 +3756,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
#ifdef SND_HDA_NEEDS_RESUME
|
||||
static int alc_resume(struct hda_codec *codec)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
struct alc_spec *spec = codec->spec;
|
||||
#endif
|
||||
codec->patch_ops.init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
if (spec && spec->power_hook)
|
||||
spec->power_hook(codec, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3758,6 +3778,7 @@ static struct hda_codec_ops alc_patch_ops = {
|
||||
.suspend = alc_suspend,
|
||||
.check_power_status = alc_check_power_status,
|
||||
#endif
|
||||
.reboot_notify = alc_shutup,
|
||||
};
|
||||
|
||||
|
||||
@@ -9538,7 +9559,7 @@ static struct alc_config_preset alc882_presets[] = {
|
||||
.setup = alc889_acer_aspire_8930g_setup,
|
||||
.init_hook = alc_automute_amp,
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
.power_hook = alc889_power_eapd,
|
||||
.power_hook = alc_power_eapd,
|
||||
#endif
|
||||
},
|
||||
[ALC888_ACER_ASPIRE_7730G] = {
|
||||
@@ -14975,8 +14996,12 @@ static int patch_alc861(struct hda_codec *codec)
|
||||
spec->vmaster_nid = 0x03;
|
||||
|
||||
codec->patch_ops = alc_patch_ops;
|
||||
if (board_config == ALC861_AUTO)
|
||||
if (board_config == ALC861_AUTO) {
|
||||
spec->init_hook = alc861_auto_init;
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
spec->power_hook = alc_power_eapd;
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
if (!spec->loopback.amplist)
|
||||
spec->loopback.amplist = alc861_loopbacks;
|
||||
|
||||
@@ -4159,34 +4159,52 @@ static void stac92xx_power_down(struct hda_codec *codec)
|
||||
static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
|
||||
int enable);
|
||||
|
||||
static inline int get_int_hint(struct hda_codec *codec, const char *key,
|
||||
int *valp)
|
||||
{
|
||||
const char *p;
|
||||
p = snd_hda_get_hint(codec, key);
|
||||
if (p) {
|
||||
unsigned long val;
|
||||
if (!strict_strtoul(p, 0, &val)) {
|
||||
*valp = val;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* override some hints from the hwdep entry */
|
||||
static void stac_store_hints(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
const char *p;
|
||||
int val;
|
||||
|
||||
val = snd_hda_get_bool_hint(codec, "hp_detect");
|
||||
if (val >= 0)
|
||||
spec->hp_detect = val;
|
||||
p = snd_hda_get_hint(codec, "gpio_mask");
|
||||
if (p) {
|
||||
spec->gpio_mask = simple_strtoul(p, NULL, 0);
|
||||
if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
|
||||
spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
|
||||
spec->gpio_mask;
|
||||
}
|
||||
p = snd_hda_get_hint(codec, "gpio_dir");
|
||||
if (p)
|
||||
spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
|
||||
p = snd_hda_get_hint(codec, "gpio_data");
|
||||
if (p)
|
||||
spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
|
||||
p = snd_hda_get_hint(codec, "eapd_mask");
|
||||
if (p)
|
||||
spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
|
||||
if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
|
||||
spec->gpio_mask &= spec->gpio_mask;
|
||||
if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
|
||||
spec->gpio_dir &= spec->gpio_mask;
|
||||
if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
|
||||
spec->eapd_mask &= spec->gpio_mask;
|
||||
if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
|
||||
spec->gpio_mute &= spec->gpio_mask;
|
||||
val = snd_hda_get_bool_hint(codec, "eapd_switch");
|
||||
if (val >= 0)
|
||||
spec->eapd_switch = val;
|
||||
get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
|
||||
if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
|
||||
spec->gpio_mask |= spec->gpio_led;
|
||||
spec->gpio_dir |= spec->gpio_led;
|
||||
if (spec->gpio_led_polarity)
|
||||
spec->gpio_data |= spec->gpio_led;
|
||||
}
|
||||
}
|
||||
|
||||
static int stac92xx_init(struct hda_codec *codec)
|
||||
@@ -4371,18 +4389,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
|
||||
static void stac92xx_shutup(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
int i;
|
||||
hda_nid_t nid;
|
||||
|
||||
/* reset each pin before powering down DAC/ADC to avoid click noise */
|
||||
nid = codec->start_nid;
|
||||
for (i = 0; i < codec->num_nodes; i++, nid++) {
|
||||
unsigned int wcaps = get_wcaps(codec, nid);
|
||||
unsigned int wid_type = get_wcaps_type(wcaps);
|
||||
if (wid_type == AC_WID_PIN)
|
||||
snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
|
||||
}
|
||||
snd_hda_shutup_pins(codec);
|
||||
|
||||
if (spec->eapd_mask)
|
||||
stac_gpio_set(codec, spec->gpio_mask,
|
||||
@@ -5406,6 +5414,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HP dv7 bass switch - GPIO5 */
|
||||
#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
|
||||
static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
unsigned int gpio_data;
|
||||
|
||||
gpio_data = (spec->gpio_data & ~0x20) |
|
||||
(ucontrol->value.integer.value[0] ? 0x20 : 0);
|
||||
if (gpio_data == spec->gpio_data)
|
||||
return 0;
|
||||
spec->gpio_data = gpio_data;
|
||||
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.info = stac_hp_bass_gpio_info,
|
||||
.get = stac_hp_bass_gpio_get,
|
||||
.put = stac_hp_bass_gpio_put,
|
||||
};
|
||||
|
||||
static int stac_add_hp_bass_switch(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
||||
if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
|
||||
"Bass Speaker Playback Switch", 0))
|
||||
return -ENOMEM;
|
||||
|
||||
spec->gpio_mask |= 0x20;
|
||||
spec->gpio_dir |= 0x20;
|
||||
spec->gpio_data |= 0x20;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int patch_stac92hd71bxx(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec;
|
||||
@@ -5646,6 +5702,15 @@ again:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* enable bass on HP dv7 */
|
||||
if (spec->board_config == STAC_HP_DV5) {
|
||||
unsigned int cap;
|
||||
cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
|
||||
cap &= AC_GPIO_IO_COUNT;
|
||||
if (cap >= 6)
|
||||
stac_add_hp_bass_switch(codec);
|
||||
}
|
||||
|
||||
codec->proc_widget_hook = stac92hd7x_proc_hook;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1907,8 +1907,7 @@ static int via_build_controls(struct hda_codec *codec)
|
||||
/* assign Capture Source enums to NID */
|
||||
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
|
||||
for (i = 0; kctl && i < kctl->count; i++) {
|
||||
err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids,
|
||||
spec->input_mux->num_items);
|
||||
err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user