summaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig1
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/hda/hda_intel.c13
-rw-r--r--sound/pci/hda/patch_conexant.c16
-rw-r--r--sound/pci/hda/patch_realtek.c18
-rw-r--r--sound/pci/hda/patch_sigmatel.c68
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/via82xx.c59
8 files changed, 160 insertions, 23 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index fb5ee3cc396..75c602b5b13 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -259,7 +259,6 @@ config SND_CS5530
config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
- depends on X86 && !X86_64
select SND_PCM
select SND_AC97_CODEC
help
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index b458d208720..aaf4da68969 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec,
void *private_data;
snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
- if (pvoice == NULL || !pvoice->use)
+ if (!pvoice->use)
return;
snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
spin_lock_irq(&codec->voice_alloc);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c9ad182e1b4..6517f589d01 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -722,9 +722,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
chip->last_cmd[addr]);
chip->single_cmd = 1;
bus->response_reset = 0;
- /* re-initialize CORB/RIRB */
+ /* release CORB/RIRB */
azx_free_cmd_io(chip);
- azx_init_cmd_io(chip);
+ /* disable unsolicited responses */
+ azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
return -1;
}
@@ -865,7 +866,9 @@ static int azx_reset(struct azx *chip)
}
/* Accept unsolicited responses */
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);
+ if (!chip->single_cmd)
+ azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
+ ICH6_GCTL_UNSOL);
/* detect codecs */
if (!chip->codec_mask) {
@@ -980,7 +983,8 @@ static void azx_init_chip(struct azx *chip)
azx_int_enable(chip);
/* initialize the codec command I/O */
- azx_init_cmd_io(chip);
+ if (!chip->single_cmd)
+ azx_init_cmd_io(chip);
/* program the position buffer */
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
@@ -2674,6 +2678,7 @@ static struct pci_device_id azx_ids[] = {
{ 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 },
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 3fbbc8c01e7..905859d4f4d 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -110,6 +110,7 @@ struct conexant_spec {
unsigned int dell_automute;
unsigned int port_d_mode;
+ unsigned char ext_mic_bias;
};
static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -1927,6 +1928,11 @@ static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
#define CXT5066_SPDIF_OUT 0x21
+/* OLPC's microphone port is DC coupled for use with external sensors,
+ * therefore we use a 50% mic bias in order to center the input signal with
+ * the DC input range of the codec. */
+#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
+
static struct hda_channel_mode cxt5066_modes[1] = {
{ 2, NULL },
};
@@ -1980,9 +1986,10 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle input of built-in and mic jack appropriately */
static void cxt5066_automic(struct hda_codec *codec)
{
- static struct hda_verb ext_mic_present[] = {
+ struct conexant_spec *spec = codec->spec;
+ struct hda_verb ext_mic_present[] = {
/* enable external mic, port B */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
/* switch to external mic input */
{0x17, AC_VERB_SET_CONNECT_SEL, 0},
@@ -2235,7 +2242,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
/* Port B: external microphone */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS},
/* Port C: internal microphone */
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2325,6 +2332,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
CXT5066_LAPTOP),
SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
CXT5066_DELL_LAPTOP),
+ SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
{}
};
@@ -2352,6 +2360,7 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->input_mux = &cxt5066_capture_source;
spec->port_d_mode = PIN_HP;
+ spec->ext_mic_bias = PIN_VREF80;
spec->num_init_verbs = 1;
spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2383,6 +2392,7 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
spec->mixers[spec->num_mixers++] = cxt5066_mixers;
spec->port_d_mode = 0;
+ spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS;
/* no S/PDIF out */
spec->multiout.dig_out_nid = 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c08ca660dab..daf6975b0c2 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -965,6 +965,8 @@ static void alc_automute_pin(struct hda_codec *codec)
unsigned int nid = spec->autocfg.hp_pins[0];
int i;
+ if (!nid)
+ return;
pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -4682,9 +4684,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
spec->multiout.dig_out_nid = dig_nid;
else {
spec->multiout.slave_dig_outs = spec->slave_dig_outs;
- spec->slave_dig_outs[i - 1] = dig_nid;
- if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
+ if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
break;
+ spec->slave_dig_outs[i - 1] = dig_nid;
}
}
if (spec->autocfg.dig_in_pin)
@@ -6247,7 +6249,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
- SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
+ SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
@@ -9811,9 +9813,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
spec->multiout.dig_out_nid = dig_nid;
else {
spec->multiout.slave_dig_outs = spec->slave_dig_outs;
- spec->slave_dig_outs[i - 1] = dig_nid;
- if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
+ if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
break;
+ spec->slave_dig_outs[i - 1] = dig_nid;
}
}
if (spec->autocfg.dig_in_pin)
@@ -11458,6 +11460,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
+ SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
@@ -12602,7 +12605,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
ALC268_ACER_ASPIRE_ONE),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
- SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
+ SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
+ "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
/* almost compatible with toshiba but with optional digital outs;
* auto-probing seems working fine
*/
@@ -17374,7 +17378,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
/* create playback/capture controls for input pins */
#define alc662_auto_create_input_ctls \
- alc880_auto_create_input_ctls
+ alc882_auto_create_input_ctls
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t nid, int pin_type,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 66c0876bf73..8eb6508cd99 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/dmi.h>
#include <sound/core.h>
#include <sound/asoundef.h>
#include <sound/jack.h>
@@ -1693,6 +1694,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
"DFI LanParty", STAC_92HD71BXX_REF),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
"HP dv4-1222nr", STAC_HP_DV4_1222NR),
+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
+ "HP", STAC_HP_DV5),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
"HP", STAC_HP_DV5),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
@@ -4665,6 +4668,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
}
}
+static int hp_bseries_system(u32 subsystem_id)
+{
+ switch (subsystem_id) {
+ case 0x103c307e:
+ case 0x103c307f:
+ case 0x103c3080:
+ case 0x103c3081:
+ case 0x103c1722:
+ case 0x103c1723:
+ case 0x103c1724:
+ case 0x103c1725:
+ case 0x103c1726:
+ case 0x103c1727:
+ case 0x103c1728:
+ case 0x103c1729:
+ return 1;
+ }
+ return 0;
+}
+
#ifdef CONFIG_PROC_FS
static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid)
@@ -4754,6 +4777,11 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
else
spec->gpio_data |= spec->gpio_led; /* white */
+ if (hp_bseries_system(codec->subsystem_id)) {
+ /* LED state is inverted on these systems */
+ spec->gpio_data ^= spec->gpio_led;
+ }
+
stac_gpio_set(codec, spec->gpio_mask,
spec->gpio_dir,
spec->gpio_data);
@@ -5243,6 +5271,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
+ unsigned int pin_cfg;
int err = 0;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5426,6 +5455,45 @@ again:
break;
}
+ if (hp_bseries_system(codec->subsystem_id)) {
+ pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
+ if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
+ get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
+ get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
+ /* It was changed in the BIOS to just satisfy MS DTM.
+ * Lets turn it back into slaved HP
+ */
+ pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
+ | (AC_JACK_HP_OUT <<
+ AC_DEFCFG_DEVICE_SHIFT);
+ pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
+ | AC_DEFCFG_SEQUENCE)))
+ | 0x1f;
+ snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
+ }
+ }
+
+ if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
+ const struct dmi_device *dev = NULL;
+ while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
+ NULL, dev))) {
+ if (strcmp(dev->name, "HP_Mute_LED_1")) {
+ switch (codec->vendor_id) {
+ case 0x111d7608:
+ spec->gpio_led = 0x01;
+ break;
+ case 0x111d7600:
+ case 0x111d7601:
+ case 0x111d7602:
+ case 0x111d7603:
+ spec->gpio_led = 0x08;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
spec->gpio_mask |= spec->gpio_led;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 754867ed478..aac20fb4aad 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1950,6 +1950,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x104d,
+ .subdevice = 0x8144,
+ .name = "Sony",
+ .type = AC97_TUNE_INV_EAPD
+ },
+ {
+ .subvendor = 0x104d,
.subdevice = 0x8197,
.name = "Sony S1XP",
.type = AC97_TUNE_INV_EAPD
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 91683a34903..8a332d2f615 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -386,6 +386,7 @@ struct via82xx {
struct snd_pcm *pcms[2];
struct snd_rawmidi *rmidi;
+ struct snd_kcontrol *dxs_controls[4];
struct snd_ac97_bus *ac97_bus;
struct snd_ac97 *ac97;
@@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/*
- * open callback for playback on via686 and via823x DSX
+ * open callback for playback on via686
*/
-static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
+static int snd_via686_playback_open(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
@@ -1230,6 +1231,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
}
/*
+ * open callback for playback on via823x DXS
+ */
+static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev;
+ unsigned int stream;
+ int err;
+
+ viadev = &chip->devs[chip->playback_devno + substream->number];
+ if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+ return err;
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->playback_volume[stream][0] = 0;
+ chip->playback_volume[stream][1] = 0;
+ chip->dxs_controls[stream]->vd[0].access &=
+ ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return 0;
+}
+
+/*
* open callback for playback on via823x multi-channel
*/
static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
@@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
+static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
+{
+ struct via82xx *chip = snd_pcm_substream_chip(substream);
+ struct viadev *viadev = substream->runtime->private_data;
+ unsigned int stream;
+
+ stream = viadev->reg_offset / 0x10;
+ if (chip->dxs_controls[stream]) {
+ chip->dxs_controls[stream]->vd[0].access |=
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
+ &chip->dxs_controls[stream]->id);
+ }
+ return snd_via82xx_pcm_close(substream);
+}
+
/* via686 playback callbacks */
static struct snd_pcm_ops snd_via686_playback_ops = {
- .open = snd_via82xx_playback_open,
+ .open = snd_via686_playback_open,
.close = snd_via82xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
@@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
/* via823x DSX playback callbacks */
static struct snd_pcm_ops snd_via8233_playback_ops = {
- .open = snd_via82xx_playback_open,
- .close = snd_via82xx_pcm_close,
+ .open = snd_via8233_playback_open,
+ .close = snd_via8233_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
.hw_free = snd_via82xx_hw_free,
@@ -1709,8 +1752,9 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
.device = 0,
/* .subdevice set later */
.name = "PCM Playback Volume",
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
@@ -1948,6 +1992,7 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
err = snd_ctl_add(chip->card, kctl);
if (err < 0)
return err;
+ chip->dxs_controls[i] = kctl;
}
}
}