aboutsummaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-09-04 08:08:42 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-09-04 08:08:42 -0700
commit7203781c98ad9147564d327de6f6513ad8fc0f4e (patch)
tree5c29a2a04a626bf08a0d56fd8a0068b3c92ad284 /sound/pci
parent671eef85a3e885dff4ce210d8774ad50a91d5967 (diff)
parentaf2e1f276ff08f17192411ea3b71c13a758dfe12 (diff)
Merge branch 'x86/cpu' into x86/core
Conflicts: arch/x86/kernel/cpu/feature_names.c include/asm-x86/cpufeature.h
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig2
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_realtek.c51
-rw-r--r--sound/pci/oxygen/virtuoso.c73
4 files changed, 113 insertions, 22 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index f7d95b224a9..31f52d3fc21 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -845,7 +845,7 @@ config SND_VIRTUOSO
select SND_OXYGEN_LIB
help
Say Y here to include support for sound cards based on the
- Asus AV100/AV200 chips, i.e., Xonar D2, DX and D2X.
+ Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X.
To compile this driver as a module, choose M here: the module
will be called snd-virtuoso.
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a73d6ca0a90..1c53e337ecb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -278,6 +278,9 @@ enum {
/* Defines for Nvidia HDA support */
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
+#define NVIDIA_HDA_ISTRM_COH 0x4d
+#define NVIDIA_HDA_OSTRM_COH 0x4c
+#define NVIDIA_HDA_ENABLE_COHBIT 0x01
/* Defines for Intel SCH HDA snoop control */
#define INTEL_SCH_HDA_DEVC 0x78
@@ -900,6 +903,12 @@ static void azx_init_pci(struct azx *chip)
update_pci_byte(chip->pci,
NVIDIA_HDA_TRANSREG_ADDR,
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_ISTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_OSTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
break;
case AZX_DRIVER_SCH:
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index add4e87e0b2..909f1c101c9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -952,7 +952,7 @@ do_sku:
tmp | 0x2010);
break;
case 0x10ec0888:
- alc888_coef_init(codec);
+ /*alc888_coef_init(codec);*/ /* called in alc_init() */
break;
case 0x10ec0267:
case 0x10ec0268:
@@ -2439,6 +2439,8 @@ static int alc_init(struct hda_codec *codec)
unsigned int i;
alc_fix_pll(codec);
+ if (codec->vendor_id == 0x10ec0888)
+ alc888_coef_init(codec);
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -6437,6 +6439,39 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
}
}
+static void alc882_auto_init_input_src(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ const struct hda_input_mux *imux = spec->input_mux;
+ int c;
+
+ for (c = 0; c < spec->num_adc_nids; c++) {
+ hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
+ hda_nid_t nid = spec->capsrc_nids[c];
+ int conns, mute, idx, item;
+
+ conns = snd_hda_get_connections(codec, nid, conn_list,
+ ARRAY_SIZE(conn_list));
+ if (conns < 0)
+ continue;
+ for (idx = 0; idx < conns; idx++) {
+ /* if the current connection is the selected one,
+ * unmute it as default - otherwise mute it
+ */
+ mute = AMP_IN_MUTE(idx);
+ for (item = 0; item < imux->num_items; item++) {
+ if (imux->items[item].index == idx) {
+ if (spec->cur_mux[c] == item)
+ mute = AMP_IN_UNMUTE(idx);
+ break;
+ }
+ }
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, mute);
+ }
+ }
+}
+
/* add mic boosts if needed */
static int alc_auto_add_mic_boost(struct hda_codec *codec)
{
@@ -6491,6 +6526,7 @@ static void alc882_auto_init(struct hda_codec *codec)
alc882_auto_init_multi_out(codec);
alc882_auto_init_hp_out(codec);
alc882_auto_init_analog_input(codec);
+ alc882_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -8285,6 +8321,8 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc883_auto_init_input_src alc882_auto_init_input_src
+
/* almost identical with ALC880 parser... */
static int alc883_parse_auto_config(struct hda_codec *codec)
{
@@ -8315,6 +8353,7 @@ static void alc883_auto_init(struct hda_codec *codec)
alc883_auto_init_multi_out(codec);
alc883_auto_init_hp_out(codec);
alc883_auto_init_analog_input(codec);
+ alc883_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -8389,8 +8428,6 @@ static int patch_alc883(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC883_AUTO)
spec->init_hook = alc883_auto_init;
- else if (codec->vendor_id == 0x10ec0888)
- spec->init_hook = alc888_coef_init;
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
@@ -9663,6 +9700,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
#define alc262_auto_init_multi_out alc882_auto_init_multi_out
#define alc262_auto_init_hp_out alc882_auto_init_hp_out
#define alc262_auto_init_analog_input alc882_auto_init_analog_input
+#define alc262_auto_init_input_src alc882_auto_init_input_src
/* init callback for auto-configuration model -- overriding the default init */
@@ -9672,6 +9710,7 @@ static void alc262_auto_init(struct hda_codec *codec)
alc262_auto_init_multi_out(codec);
alc262_auto_init_hp_out(codec);
alc262_auto_init_analog_input(codec);
+ alc262_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -13330,6 +13369,8 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc861vd_auto_init_input_src alc882_auto_init_input_src
+
#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
@@ -13512,6 +13553,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc861vd_auto_init_multi_out(codec);
alc861vd_auto_init_hp_out(codec);
alc861vd_auto_init_analog_input(codec);
+ alc861vd_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -14677,6 +14719,8 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc662_auto_init_input_src alc882_auto_init_input_src
+
static int alc662_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -14733,6 +14777,7 @@ static void alc662_auto_init(struct hda_codec *codec)
alc662_auto_init_multi_out(codec);
alc662_auto_init_hp_out(codec);
alc662_auto_init_analog_input(codec);
+ alc662_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 9a2c16bf94e..01d7b75f918 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -36,15 +36,15 @@
*/
/*
- * Xonar DX
- * --------
+ * Xonar D1/DX
+ * -----------
*
* CMI8788:
*
* I²C <-> CS4398 (front)
* <-> CS4362A (surround, center/LFE, back)
*
- * GPI 0 <- external power present
+ * GPI 0 <- external power present (DX only)
*
* GPIO 0 -> enable output to speakers
* GPIO 1 -> enable front panel I/O
@@ -96,6 +96,7 @@ MODULE_PARM_DESC(enable, "enable card");
enum {
MODEL_D2,
MODEL_D2X,
+ MODEL_D1,
MODEL_DX,
};
@@ -103,6 +104,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
{ OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
{ OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
{ OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
+ { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
{ }
};
MODULE_DEVICE_TABLE(pci, xonar_ids);
@@ -313,15 +315,12 @@ static void cs43xx_init(struct oxygen *chip)
cs4362a_write(chip, 0x01, CS4362A_CPEN);
}
-static void xonar_dx_init(struct oxygen *chip)
+static void xonar_d1_init(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
data->anti_pop_delay = 800;
data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
- data->ext_power_reg = OXYGEN_GPI_DATA;
- data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->ext_power_bit = GPI_DX_EXT_POWER;
data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
data->cs4362a_fm = CS4362A_FM_SINGLE |
CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
@@ -345,6 +344,16 @@ static void xonar_dx_init(struct oxygen *chip)
snd_component_add(chip->card, "CS5361");
}
+static void xonar_dx_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+
+ data->ext_power_reg = OXYGEN_GPI_DATA;
+ data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
+ data->ext_power_bit = GPI_DX_EXT_POWER;
+ xonar_d1_init(chip);
+}
+
static void xonar_cleanup(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
@@ -352,7 +361,7 @@ static void xonar_cleanup(struct oxygen *chip)
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
}
-static void xonar_dx_cleanup(struct oxygen *chip)
+static void xonar_d1_cleanup(struct oxygen *chip)
{
xonar_cleanup(chip);
cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
@@ -365,7 +374,7 @@ static void xonar_d2_resume(struct oxygen *chip)
xonar_enable_output(chip);
}
-static void xonar_dx_resume(struct oxygen *chip)
+static void xonar_d1_resume(struct oxygen *chip)
{
cs43xx_init(chip);
xonar_enable_output(chip);
@@ -513,7 +522,7 @@ static const struct snd_kcontrol_new front_panel_switch = {
.put = front_panel_put,
};
-static void xonar_dx_ac97_switch(struct oxygen *chip,
+static void xonar_d1_ac97_switch(struct oxygen *chip,
unsigned int reg, unsigned int mute)
{
if (reg == AC97_LINE) {
@@ -536,7 +545,7 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
return 0;
}
-static int xonar_dx_control_filter(struct snd_kcontrol_new *template)
+static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
{
if (!strncmp(template->name, "CD Capture ", 11))
return 1; /* no CD input */
@@ -548,7 +557,7 @@ static int xonar_mixer_init(struct oxygen *chip)
return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
}
-static int xonar_dx_mixer_init(struct oxygen *chip)
+static int xonar_d1_mixer_init(struct oxygen *chip)
{
return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
}
@@ -615,23 +624,51 @@ static const struct oxygen_model xonar_models[] = {
.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
},
+ [MODEL_D1] = {
+ .shortname = "Xonar D1",
+ .longname = "Asus Virtuoso 100",
+ .chip = "AV200",
+ .owner = THIS_MODULE,
+ .init = xonar_d1_init,
+ .control_filter = xonar_d1_control_filter,
+ .mixer_init = xonar_d1_mixer_init,
+ .cleanup = xonar_d1_cleanup,
+ .suspend = xonar_d1_cleanup,
+ .resume = xonar_d1_resume,
+ .set_dac_params = set_cs43xx_params,
+ .set_adc_params = set_cs53x1_params,
+ .update_dac_volume = update_cs43xx_volume,
+ .update_dac_mute = update_cs43xx_mute,
+ .ac97_switch = xonar_d1_ac97_switch,
+ .dac_tlv = cs4362a_db_scale,
+ .model_data_size = sizeof(struct xonar_data),
+ .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2,
+ .dac_channels = 8,
+ .dac_volume_min = 0,
+ .dac_volume_max = 127,
+ .function_flags = OXYGEN_FUNCTION_2WIRE,
+ .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ },
[MODEL_DX] = {
.shortname = "Xonar DX",
.longname = "Asus Virtuoso 100",
.chip = "AV200",
.owner = THIS_MODULE,
.init = xonar_dx_init,
- .control_filter = xonar_dx_control_filter,
- .mixer_init = xonar_dx_mixer_init,
- .cleanup = xonar_dx_cleanup,
- .suspend = xonar_dx_cleanup,
- .resume = xonar_dx_resume,
+ .control_filter = xonar_d1_control_filter,
+ .mixer_init = xonar_d1_mixer_init,
+ .cleanup = xonar_d1_cleanup,
+ .suspend = xonar_d1_cleanup,
+ .resume = xonar_d1_resume,
.set_dac_params = set_cs43xx_params,
.set_adc_params = set_cs53x1_params,
.update_dac_volume = update_cs43xx_volume,
.update_dac_mute = update_cs43xx_mute,
.gpio_changed = xonar_gpio_changed,
- .ac97_switch = xonar_dx_ac97_switch,
+ .ac97_switch = xonar_d1_ac97_switch,
.dac_tlv = cs4362a_db_scale,
.model_data_size = sizeof(struct xonar_data),
.pcm_dev_cfg = PLAYBACK_0_TO_I2S |