aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/virtuoso.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
commitf541ae326fa120fa5c57433e4d9a133df212ce41 (patch)
treebdbd94ec72cfc601118051cb35e8617d55510177 /sound/pci/oxygen/virtuoso.c
parente255357764f92afcafafbd4879b222b8c752065a (diff)
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream Conflicts: arch/powerpc/kernel/Makefile arch/x86/ia32/ia32entry.S arch/x86/include/asm/hardirq.h arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h arch/x86/kernel/cpu/common.c arch/x86/kernel/irq.c arch/x86/kernel/syscall_table_32.S arch/x86/mm/iomap_32.c include/linux/sched.h kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'sound/pci/oxygen/virtuoso.c')
-rw-r--r--sound/pci/oxygen/virtuoso.c339
1 files changed, 270 insertions, 69 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 6c870c12a177..bc5ce11c8b14 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -112,6 +112,34 @@
112 * CS4362A: AD0 <- 0 112 * CS4362A: AD0 <- 0
113 */ 113 */
114 114
115/*
116 * Xonar Essence STX
117 * -----------------
118 *
119 * CMI8788:
120 *
121 * I²C <-> PCM1792A
122 *
123 * GPI 0 <- external power present
124 *
125 * GPIO 0 -> enable output to speakers
126 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
127 * GPIO 2 -> M0 of CS5381
128 * GPIO 3 -> M1 of CS5381
129 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
130 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
131 *
132 * PCM1792A:
133 *
134 * AD0 <- 0
135 *
136 * H6 daughterboard
137 * ----------------
138 *
139 * GPIO 4 <- 0
140 * GPIO 5 <- 0
141 */
142
115#include <linux/pci.h> 143#include <linux/pci.h>
116#include <linux/delay.h> 144#include <linux/delay.h>
117#include <linux/mutex.h> 145#include <linux/mutex.h>
@@ -152,6 +180,7 @@ enum {
152 MODEL_DX, 180 MODEL_DX,
153 MODEL_HDAV, /* without daughterboard */ 181 MODEL_HDAV, /* without daughterboard */
154 MODEL_HDAV_H6, /* with H6 daughterboard */ 182 MODEL_HDAV_H6, /* with H6 daughterboard */
183 MODEL_STX,
155}; 184};
156 185
157static struct pci_device_id xonar_ids[] __devinitdata = { 186static struct pci_device_id xonar_ids[] __devinitdata = {
@@ -160,6 +189,8 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
160 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, 189 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
161 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV }, 190 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV },
162 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, 191 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
192 { OXYGEN_PCI_SUBID(0x1043, 0x835c), .driver_data = MODEL_STX },
193 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
163 { } 194 { }
164}; 195};
165MODULE_DEVICE_TABLE(pci, xonar_ids); 196MODULE_DEVICE_TABLE(pci, xonar_ids);
@@ -183,12 +214,14 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
183#define GPIO_HDAV_DB_H6 0x0000 214#define GPIO_HDAV_DB_H6 0x0000
184#define GPIO_HDAV_DB_XX 0x0020 215#define GPIO_HDAV_DB_XX 0x0020
185 216
217#define GPIO_ST_HP_REAR 0x0002
218#define GPIO_ST_HP 0x0080
219
186#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */ 220#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */
187#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ 221#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
188#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ 222#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
189 223
190struct xonar_data { 224struct xonar_data {
191 unsigned int model;
192 unsigned int anti_pop_delay; 225 unsigned int anti_pop_delay;
193 unsigned int dacs; 226 unsigned int dacs;
194 u16 output_enable_bit; 227 u16 output_enable_bit;
@@ -334,15 +367,9 @@ static void xonar_d2_init(struct oxygen *chip)
334 struct xonar_data *data = chip->model_data; 367 struct xonar_data *data = chip->model_data;
335 368
336 data->anti_pop_delay = 300; 369 data->anti_pop_delay = 300;
370 data->dacs = 4;
337 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 371 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
338 data->pcm1796_oversampling = PCM1796_OS_64; 372 data->pcm1796_oversampling = PCM1796_OS_64;
339 if (data->model == MODEL_D2X) {
340 data->ext_power_reg = OXYGEN_GPIO_DATA;
341 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
342 data->ext_power_bit = GPIO_D2X_EXT_POWER;
343 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
344 GPIO_D2X_EXT_POWER);
345 }
346 373
347 pcm1796_init(chip); 374 pcm1796_init(chip);
348 375
@@ -355,6 +382,18 @@ static void xonar_d2_init(struct oxygen *chip)
355 snd_component_add(chip->card, "CS5381"); 382 snd_component_add(chip->card, "CS5381");
356} 383}
357 384
385static void xonar_d2x_init(struct oxygen *chip)
386{
387 struct xonar_data *data = chip->model_data;
388
389 data->ext_power_reg = OXYGEN_GPIO_DATA;
390 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
391 data->ext_power_bit = GPIO_D2X_EXT_POWER;
392 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
393
394 xonar_d2_init(chip);
395}
396
358static void update_cs4362a_volumes(struct oxygen *chip) 397static void update_cs4362a_volumes(struct oxygen *chip)
359{ 398{
360 u8 mute; 399 u8 mute;
@@ -422,11 +461,6 @@ static void xonar_d1_init(struct oxygen *chip)
422 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; 461 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
423 data->cs4362a_fm = CS4362A_FM_SINGLE | 462 data->cs4362a_fm = CS4362A_FM_SINGLE |
424 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 463 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
425 if (data->model == MODEL_DX) {
426 data->ext_power_reg = OXYGEN_GPI_DATA;
427 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
428 data->ext_power_bit = GPI_DX_EXT_POWER;
429 }
430 464
431 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 465 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
432 OXYGEN_2WIRE_LENGTH_8 | 466 OXYGEN_2WIRE_LENGTH_8 |
@@ -447,6 +481,17 @@ static void xonar_d1_init(struct oxygen *chip)
447 snd_component_add(chip->card, "CS5361"); 481 snd_component_add(chip->card, "CS5361");
448} 482}
449 483
484static void xonar_dx_init(struct oxygen *chip)
485{
486 struct xonar_data *data = chip->model_data;
487
488 data->ext_power_reg = OXYGEN_GPI_DATA;
489 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
490 data->ext_power_bit = GPI_DX_EXT_POWER;
491
492 xonar_d1_init(chip);
493}
494
450static void xonar_hdav_init(struct oxygen *chip) 495static void xonar_hdav_init(struct oxygen *chip)
451{ 496{
452 struct xonar_data *data = chip->model_data; 497 struct xonar_data *data = chip->model_data;
@@ -458,6 +503,7 @@ static void xonar_hdav_init(struct oxygen *chip)
458 OXYGEN_2WIRE_SPEED_FAST); 503 OXYGEN_2WIRE_SPEED_FAST);
459 504
460 data->anti_pop_delay = 100; 505 data->anti_pop_delay = 100;
506 data->dacs = chip->model.private_data == MODEL_HDAV_H6 ? 4 : 1;
461 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; 507 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
462 data->ext_power_reg = OXYGEN_GPI_DATA; 508 data->ext_power_reg = OXYGEN_GPI_DATA;
463 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 509 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
@@ -484,6 +530,36 @@ static void xonar_hdav_init(struct oxygen *chip)
484 snd_component_add(chip->card, "CS5381"); 530 snd_component_add(chip->card, "CS5381");
485} 531}
486 532
533static void xonar_stx_init(struct oxygen *chip)
534{
535 struct xonar_data *data = chip->model_data;
536
537 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
538 OXYGEN_2WIRE_LENGTH_8 |
539 OXYGEN_2WIRE_INTERRUPT_MASK |
540 OXYGEN_2WIRE_SPEED_FAST);
541
542 data->anti_pop_delay = 100;
543 data->dacs = 1;
544 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
545 data->ext_power_reg = OXYGEN_GPI_DATA;
546 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
547 data->ext_power_bit = GPI_DX_EXT_POWER;
548 data->pcm1796_oversampling = PCM1796_OS_64;
549
550 pcm1796_init(chip);
551
552 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
553 GPIO_DX_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
554 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
555 GPIO_DX_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
556
557 xonar_common_init(chip);
558
559 snd_component_add(chip->card, "PCM1792A");
560 snd_component_add(chip->card, "CS5381");
561}
562
487static void xonar_disable_output(struct oxygen *chip) 563static void xonar_disable_output(struct oxygen *chip)
488{ 564{
489 struct xonar_data *data = chip->model_data; 565 struct xonar_data *data = chip->model_data;
@@ -511,6 +587,11 @@ static void xonar_hdav_cleanup(struct oxygen *chip)
511 xonar_disable_output(chip); 587 xonar_disable_output(chip);
512} 588}
513 589
590static void xonar_st_cleanup(struct oxygen *chip)
591{
592 xonar_disable_output(chip);
593}
594
514static void xonar_d2_suspend(struct oxygen *chip) 595static void xonar_d2_suspend(struct oxygen *chip)
515{ 596{
516 xonar_d2_cleanup(chip); 597 xonar_d2_cleanup(chip);
@@ -527,6 +608,11 @@ static void xonar_hdav_suspend(struct oxygen *chip)
527 msleep(2); 608 msleep(2);
528} 609}
529 610
611static void xonar_st_suspend(struct oxygen *chip)
612{
613 xonar_st_cleanup(chip);
614}
615
530static void xonar_d2_resume(struct oxygen *chip) 616static void xonar_d2_resume(struct oxygen *chip)
531{ 617{
532 pcm1796_init(chip); 618 pcm1796_init(chip);
@@ -554,6 +640,12 @@ static void xonar_hdav_resume(struct oxygen *chip)
554 xonar_enable_output(chip); 640 xonar_enable_output(chip);
555} 641}
556 642
643static void xonar_st_resume(struct oxygen *chip)
644{
645 pcm1796_init(chip);
646 xonar_enable_output(chip);
647}
648
557static void xonar_hdav_pcm_hardware_filter(unsigned int channel, 649static void xonar_hdav_pcm_hardware_filter(unsigned int channel,
558 struct snd_pcm_hardware *hardware) 650 struct snd_pcm_hardware *hardware)
559{ 651{
@@ -733,6 +825,72 @@ static const struct snd_kcontrol_new front_panel_switch = {
733 .private_value = GPIO_DX_FRONT_PANEL, 825 .private_value = GPIO_DX_FRONT_PANEL,
734}; 826};
735 827
828static int st_output_switch_info(struct snd_kcontrol *ctl,
829 struct snd_ctl_elem_info *info)
830{
831 static const char *const names[3] = {
832 "Speakers", "Headphones", "FP Headphones"
833 };
834
835 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
836 info->count = 1;
837 info->value.enumerated.items = 3;
838 if (info->value.enumerated.item >= 3)
839 info->value.enumerated.item = 2;
840 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
841 return 0;
842}
843
844static int st_output_switch_get(struct snd_kcontrol *ctl,
845 struct snd_ctl_elem_value *value)
846{
847 struct oxygen *chip = ctl->private_data;
848 u16 gpio;
849
850 gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
851 if (!(gpio & GPIO_ST_HP))
852 value->value.enumerated.item[0] = 0;
853 else if (gpio & GPIO_ST_HP_REAR)
854 value->value.enumerated.item[0] = 1;
855 else
856 value->value.enumerated.item[0] = 2;
857 return 0;
858}
859
860
861static int st_output_switch_put(struct snd_kcontrol *ctl,
862 struct snd_ctl_elem_value *value)
863{
864 struct oxygen *chip = ctl->private_data;
865 u16 gpio_old, gpio;
866
867 mutex_lock(&chip->mutex);
868 gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
869 gpio = gpio_old;
870 switch (value->value.enumerated.item[0]) {
871 case 0:
872 gpio &= ~(GPIO_ST_HP | GPIO_ST_HP_REAR);
873 break;
874 case 1:
875 gpio |= GPIO_ST_HP | GPIO_ST_HP_REAR;
876 break;
877 case 2:
878 gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR;
879 break;
880 }
881 oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
882 mutex_unlock(&chip->mutex);
883 return gpio != gpio_old;
884}
885
886static const struct snd_kcontrol_new st_output_switch = {
887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888 .name = "Analog Output",
889 .info = st_output_switch_info,
890 .get = st_output_switch_get,
891 .put = st_output_switch_put,
892};
893
736static void xonar_line_mic_ac97_switch(struct oxygen *chip, 894static void xonar_line_mic_ac97_switch(struct oxygen *chip,
737 unsigned int reg, unsigned int mute) 895 unsigned int reg, unsigned int mute)
738{ 896{
@@ -745,8 +903,8 @@ static void xonar_line_mic_ac97_switch(struct oxygen *chip,
745 } 903 }
746} 904}
747 905
748static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0); 906static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0);
749static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0); 907static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
750 908
751static int xonar_d2_control_filter(struct snd_kcontrol_new *template) 909static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
752{ 910{
@@ -763,6 +921,15 @@ static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
763 return 0; 921 return 0;
764} 922}
765 923
924static int xonar_st_control_filter(struct snd_kcontrol_new *template)
925{
926 if (!strncmp(template->name, "CD Capture ", 11))
927 return 1; /* no CD input */
928 if (!strcmp(template->name, "Stereo Upmixing"))
929 return 1; /* stereo only - we don't need upmixing */
930 return 0;
931}
932
766static int xonar_d2_mixer_init(struct oxygen *chip) 933static int xonar_d2_mixer_init(struct oxygen *chip)
767{ 934{
768 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); 935 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
@@ -773,51 +940,14 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
773 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); 940 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
774} 941}
775 942
776static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data) 943static int xonar_st_mixer_init(struct oxygen *chip)
777{ 944{
778 static const char *const names[] = { 945 return snd_ctl_add(chip->card, snd_ctl_new1(&st_output_switch, chip));
779 [MODEL_D1] = "Xonar D1",
780 [MODEL_DX] = "Xonar DX",
781 [MODEL_D2] = "Xonar D2",
782 [MODEL_D2X] = "Xonar D2X",
783 [MODEL_HDAV] = "Xonar HDAV1.3",
784 [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
785 };
786 static const u8 dacs[] = {
787 [MODEL_D1] = 2,
788 [MODEL_DX] = 2,
789 [MODEL_D2] = 4,
790 [MODEL_D2X] = 4,
791 [MODEL_HDAV] = 1,
792 [MODEL_HDAV_H6] = 4,
793 };
794 struct xonar_data *data = chip->model_data;
795
796 data->model = driver_data;
797 if (data->model == MODEL_HDAV) {
798 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
799 GPIO_HDAV_DB_MASK);
800 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) &
801 GPIO_HDAV_DB_MASK) {
802 case GPIO_HDAV_DB_H6:
803 data->model = MODEL_HDAV_H6;
804 break;
805 case GPIO_HDAV_DB_XX:
806 snd_printk(KERN_ERR "unknown daughterboard\n");
807 return -ENODEV;
808 }
809 }
810
811 data->dacs = dacs[data->model];
812 chip->model.shortname = names[data->model];
813 return 0;
814} 946}
815 947
816static const struct oxygen_model model_xonar_d2 = { 948static const struct oxygen_model model_xonar_d2 = {
817 .longname = "Asus Virtuoso 200", 949 .longname = "Asus Virtuoso 200",
818 .chip = "AV200", 950 .chip = "AV200",
819 .owner = THIS_MODULE,
820 .probe = xonar_model_probe,
821 .init = xonar_d2_init, 951 .init = xonar_d2_init,
822 .control_filter = xonar_d2_control_filter, 952 .control_filter = xonar_d2_control_filter,
823 .mixer_init = xonar_d2_mixer_init, 953 .mixer_init = xonar_d2_mixer_init,
@@ -837,8 +967,8 @@ static const struct oxygen_model model_xonar_d2 = {
837 MIDI_OUTPUT | 967 MIDI_OUTPUT |
838 MIDI_INPUT, 968 MIDI_INPUT,
839 .dac_channels = 8, 969 .dac_channels = 8,
840 .dac_volume_min = 0x0f, 970 .dac_volume_min = 255 - 2*60,
841 .dac_volume_max = 0xff, 971 .dac_volume_max = 255,
842 .misc_flags = OXYGEN_MISC_MIDI, 972 .misc_flags = OXYGEN_MISC_MIDI,
843 .function_flags = OXYGEN_FUNCTION_SPI | 973 .function_flags = OXYGEN_FUNCTION_SPI |
844 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 974 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
@@ -849,8 +979,6 @@ static const struct oxygen_model model_xonar_d2 = {
849static const struct oxygen_model model_xonar_d1 = { 979static const struct oxygen_model model_xonar_d1 = {
850 .longname = "Asus Virtuoso 100", 980 .longname = "Asus Virtuoso 100",
851 .chip = "AV200", 981 .chip = "AV200",
852 .owner = THIS_MODULE,
853 .probe = xonar_model_probe,
854 .init = xonar_d1_init, 982 .init = xonar_d1_init,
855 .control_filter = xonar_d1_control_filter, 983 .control_filter = xonar_d1_control_filter,
856 .mixer_init = xonar_d1_mixer_init, 984 .mixer_init = xonar_d1_mixer_init,
@@ -868,7 +996,7 @@ static const struct oxygen_model model_xonar_d1 = {
868 PLAYBACK_1_TO_SPDIF | 996 PLAYBACK_1_TO_SPDIF |
869 CAPTURE_0_FROM_I2S_2, 997 CAPTURE_0_FROM_I2S_2,
870 .dac_channels = 8, 998 .dac_channels = 8,
871 .dac_volume_min = 0, 999 .dac_volume_min = 127 - 60,
872 .dac_volume_max = 127, 1000 .dac_volume_max = 127,
873 .function_flags = OXYGEN_FUNCTION_2WIRE, 1001 .function_flags = OXYGEN_FUNCTION_2WIRE,
874 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1002 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -878,8 +1006,6 @@ static const struct oxygen_model model_xonar_d1 = {
878static const struct oxygen_model model_xonar_hdav = { 1006static const struct oxygen_model model_xonar_hdav = {
879 .longname = "Asus Virtuoso 200", 1007 .longname = "Asus Virtuoso 200",
880 .chip = "AV200", 1008 .chip = "AV200",
881 .owner = THIS_MODULE,
882 .probe = xonar_model_probe,
883 .init = xonar_hdav_init, 1009 .init = xonar_hdav_init,
884 .cleanup = xonar_hdav_cleanup, 1010 .cleanup = xonar_hdav_cleanup,
885 .suspend = xonar_hdav_suspend, 1011 .suspend = xonar_hdav_suspend,
@@ -897,16 +1023,43 @@ static const struct oxygen_model model_xonar_hdav = {
897 PLAYBACK_1_TO_SPDIF | 1023 PLAYBACK_1_TO_SPDIF |
898 CAPTURE_0_FROM_I2S_2, 1024 CAPTURE_0_FROM_I2S_2,
899 .dac_channels = 8, 1025 .dac_channels = 8,
900 .dac_volume_min = 0x0f, 1026 .dac_volume_min = 255 - 2*60,
901 .dac_volume_max = 0xff, 1027 .dac_volume_max = 255,
902 .misc_flags = OXYGEN_MISC_MIDI, 1028 .misc_flags = OXYGEN_MISC_MIDI,
903 .function_flags = OXYGEN_FUNCTION_2WIRE, 1029 .function_flags = OXYGEN_FUNCTION_2WIRE,
904 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1030 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
905 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1031 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
906}; 1032};
907 1033
908static int __devinit xonar_probe(struct pci_dev *pci, 1034static const struct oxygen_model model_xonar_st = {
909 const struct pci_device_id *pci_id) 1035 .longname = "Asus Virtuoso 100",
1036 .chip = "AV200",
1037 .init = xonar_stx_init,
1038 .control_filter = xonar_st_control_filter,
1039 .mixer_init = xonar_st_mixer_init,
1040 .cleanup = xonar_st_cleanup,
1041 .suspend = xonar_st_suspend,
1042 .resume = xonar_st_resume,
1043 .set_dac_params = set_pcm1796_params,
1044 .set_adc_params = set_cs53x1_params,
1045 .update_dac_volume = update_pcm1796_volume,
1046 .update_dac_mute = update_pcm1796_mute,
1047 .ac97_switch = xonar_line_mic_ac97_switch,
1048 .dac_tlv = pcm1796_db_scale,
1049 .model_data_size = sizeof(struct xonar_data),
1050 .device_config = PLAYBACK_0_TO_I2S |
1051 PLAYBACK_1_TO_SPDIF |
1052 CAPTURE_0_FROM_I2S_2,
1053 .dac_channels = 2,
1054 .dac_volume_min = 255 - 2*60,
1055 .dac_volume_max = 255,
1056 .function_flags = OXYGEN_FUNCTION_2WIRE,
1057 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1058 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1059};
1060
1061static int __devinit get_xonar_model(struct oxygen *chip,
1062 const struct pci_device_id *id)
910{ 1063{
911 static const struct oxygen_model *const models[] = { 1064 static const struct oxygen_model *const models[] = {
912 [MODEL_D1] = &model_xonar_d1, 1065 [MODEL_D1] = &model_xonar_d1,
@@ -914,7 +1067,57 @@ static int __devinit xonar_probe(struct pci_dev *pci,
914 [MODEL_D2] = &model_xonar_d2, 1067 [MODEL_D2] = &model_xonar_d2,
915 [MODEL_D2X] = &model_xonar_d2, 1068 [MODEL_D2X] = &model_xonar_d2,
916 [MODEL_HDAV] = &model_xonar_hdav, 1069 [MODEL_HDAV] = &model_xonar_hdav,
1070 [MODEL_STX] = &model_xonar_st,
917 }; 1071 };
1072 static const char *const names[] = {
1073 [MODEL_D1] = "Xonar D1",
1074 [MODEL_DX] = "Xonar DX",
1075 [MODEL_D2] = "Xonar D2",
1076 [MODEL_D2X] = "Xonar D2X",
1077 [MODEL_HDAV] = "Xonar HDAV1.3",
1078 [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
1079 [MODEL_STX] = "Xonar Essence STX",
1080 };
1081 unsigned int model = id->driver_data;
1082
1083 if (model >= ARRAY_SIZE(models) || !models[model])
1084 return -EINVAL;
1085 chip->model = *models[model];
1086
1087 switch (model) {
1088 case MODEL_D2X:
1089 chip->model.init = xonar_d2x_init;
1090 break;
1091 case MODEL_DX:
1092 chip->model.init = xonar_dx_init;
1093 break;
1094 case MODEL_HDAV:
1095 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
1096 GPIO_HDAV_DB_MASK);
1097 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) &
1098 GPIO_HDAV_DB_MASK) {
1099 case GPIO_HDAV_DB_H6:
1100 model = MODEL_HDAV_H6;
1101 break;
1102 case GPIO_HDAV_DB_XX:
1103 snd_printk(KERN_ERR "unknown daughterboard\n");
1104 return -ENODEV;
1105 }
1106 break;
1107 case MODEL_STX:
1108 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
1109 GPIO_HDAV_DB_MASK);
1110 break;
1111 }
1112
1113 chip->model.shortname = names[model];
1114 chip->model.private_data = model;
1115 return 0;
1116}
1117
1118static int __devinit xonar_probe(struct pci_dev *pci,
1119 const struct pci_device_id *pci_id)
1120{
918 static int dev; 1121 static int dev;
919 int err; 1122 int err;
920 1123
@@ -924,10 +1127,8 @@ static int __devinit xonar_probe(struct pci_dev *pci,
924 ++dev; 1127 ++dev;
925 return -ENOENT; 1128 return -ENOENT;
926 } 1129 }
927 BUG_ON(pci_id->driver_data >= ARRAY_SIZE(models)); 1130 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
928 err = oxygen_pci_probe(pci, index[dev], id[dev], 1131 xonar_ids, get_xonar_model);
929 models[pci_id->driver_data],
930 pci_id->driver_data);
931 if (err >= 0) 1132 if (err >= 0)
932 ++dev; 1133 ++dev;
933 return err; 1134 return err;