aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/oxygen/hifier.c11
-rw-r--r--sound/pci/oxygen/oxygen.c44
-rw-r--r--sound/pci/oxygen/oxygen.h17
-rw-r--r--sound/pci/oxygen/oxygen_io.c15
-rw-r--r--sound/pci/oxygen/oxygen_lib.c51
-rw-r--r--sound/pci/oxygen/virtuoso.c134
6 files changed, 179 insertions, 93 deletions
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index cc98bad9916a..84ef13183419 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -45,6 +45,7 @@ MODULE_PARM_DESC(enable, "enable card");
45static struct pci_device_id hifier_ids[] __devinitdata = { 45static struct pci_device_id hifier_ids[] __devinitdata = {
46 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, 46 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
47 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, 47 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
48 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
48 { } 49 { }
49}; 50};
50MODULE_DEVICE_TABLE(pci, hifier_ids); 51MODULE_DEVICE_TABLE(pci, hifier_ids);
@@ -172,6 +173,13 @@ static const struct oxygen_model model_hifier = {
172 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 173 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
173}; 174};
174 175
176static int __devinit get_hifier_model(struct oxygen *chip,
177 const struct pci_device_id *id)
178{
179 chip->model = model_hifier;
180 return 0;
181}
182
175static int __devinit hifier_probe(struct pci_dev *pci, 183static int __devinit hifier_probe(struct pci_dev *pci,
176 const struct pci_device_id *pci_id) 184 const struct pci_device_id *pci_id)
177{ 185{
@@ -184,7 +192,8 @@ static int __devinit hifier_probe(struct pci_dev *pci,
184 ++dev; 192 ++dev;
185 return -ENOENT; 193 return -ENOENT;
186 } 194 }
187 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, &model_hifier, 0); 195 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
196 hifier_ids, get_hifier_model);
188 if (err >= 0) 197 if (err >= 0)
189 ++dev; 198 ++dev;
190 return err; 199 return err;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 12b6c2137d50..f2c37f379d39 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -293,29 +293,10 @@ static void set_ak5385_params(struct oxygen *chip,
293 293
294static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 294static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
295 295
296static int generic_probe(struct oxygen *chip, unsigned long driver_data)
297{
298 if (driver_data == MODEL_MERIDIAN) {
299 chip->model.init = meridian_init;
300 chip->model.resume = meridian_resume;
301 chip->model.set_adc_params = set_ak5385_params;
302 chip->model.device_config = PLAYBACK_0_TO_I2S |
303 PLAYBACK_1_TO_SPDIF |
304 CAPTURE_0_FROM_I2S_2 |
305 CAPTURE_1_FROM_SPDIF;
306 }
307 if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) {
308 chip->model.misc_flags = OXYGEN_MISC_MIDI;
309 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
310 }
311 return 0;
312}
313
314static const struct oxygen_model model_generic = { 296static const struct oxygen_model model_generic = {
315 .shortname = "C-Media CMI8788", 297 .shortname = "C-Media CMI8788",
316 .longname = "C-Media Oxygen HD Audio", 298 .longname = "C-Media Oxygen HD Audio",
317 .chip = "CMI8788", 299 .chip = "CMI8788",
318 .probe = generic_probe,
319 .init = generic_init, 300 .init = generic_init,
320 .cleanup = generic_cleanup, 301 .cleanup = generic_cleanup,
321 .resume = generic_resume, 302 .resume = generic_resume,
@@ -340,6 +321,29 @@ static const struct oxygen_model model_generic = {
340 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 321 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
341}; 322};
342 323
324static int __devinit get_oxygen_model(struct oxygen *chip,
325 const struct pci_device_id *id)
326{
327 chip->model = model_generic;
328 switch (id->driver_data) {
329 case MODEL_MERIDIAN:
330 chip->model.init = meridian_init;
331 chip->model.resume = meridian_resume;
332 chip->model.set_adc_params = set_ak5385_params;
333 chip->model.device_config = PLAYBACK_0_TO_I2S |
334 PLAYBACK_1_TO_SPDIF |
335 CAPTURE_0_FROM_I2S_2 |
336 CAPTURE_1_FROM_SPDIF;
337 break;
338 }
339 if (id->driver_data == MODEL_MERIDIAN ||
340 id->driver_data == MODEL_HALO) {
341 chip->model.misc_flags = OXYGEN_MISC_MIDI;
342 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
343 }
344 return 0;
345}
346
343static int __devinit generic_oxygen_probe(struct pci_dev *pci, 347static int __devinit generic_oxygen_probe(struct pci_dev *pci,
344 const struct pci_device_id *pci_id) 348 const struct pci_device_id *pci_id)
345{ 349{
@@ -353,7 +357,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
353 return -ENOENT; 357 return -ENOENT;
354 } 358 }
355 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, 359 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
356 &model_generic, pci_id->driver_data); 360 oxygen_ids, get_oxygen_model);
357 if (err >= 0) 361 if (err >= 0)
358 ++dev; 362 ++dev;
359 return err; 363 return err;
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 268bff4f29d2..c500d48ea349 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -49,7 +49,13 @@ enum {
49 .subvendor = sv, \ 49 .subvendor = sv, \
50 .subdevice = sd 50 .subdevice = sd
51 51
52#define BROKEN_EEPROM_DRIVER_DATA ((unsigned long)-1)
53#define OXYGEN_PCI_SUBID_BROKEN_EEPROM \
54 OXYGEN_PCI_SUBID(PCI_VENDOR_ID_CMEDIA, 0x8788), \
55 .driver_data = BROKEN_EEPROM_DRIVER_DATA
56
52struct pci_dev; 57struct pci_dev;
58struct pci_device_id;
53struct snd_card; 59struct snd_card;
54struct snd_pcm_substream; 60struct snd_pcm_substream;
55struct snd_pcm_hardware; 61struct snd_pcm_hardware;
@@ -62,7 +68,6 @@ struct oxygen_model {
62 const char *shortname; 68 const char *shortname;
63 const char *longname; 69 const char *longname;
64 const char *chip; 70 const char *chip;
65 int (*probe)(struct oxygen *chip, unsigned long driver_data);
66 void (*init)(struct oxygen *chip); 71 void (*init)(struct oxygen *chip);
67 int (*control_filter)(struct snd_kcontrol_new *template); 72 int (*control_filter)(struct snd_kcontrol_new *template);
68 int (*mixer_init)(struct oxygen *chip); 73 int (*mixer_init)(struct oxygen *chip);
@@ -82,6 +87,7 @@ struct oxygen_model {
82 void (*ac97_switch)(struct oxygen *chip, 87 void (*ac97_switch)(struct oxygen *chip,
83 unsigned int reg, unsigned int mute); 88 unsigned int reg, unsigned int mute);
84 const unsigned int *dac_tlv; 89 const unsigned int *dac_tlv;
90 unsigned long private_data;
85 size_t model_data_size; 91 size_t model_data_size;
86 unsigned int device_config; 92 unsigned int device_config;
87 u8 dac_channels; 93 u8 dac_channels;
@@ -134,8 +140,11 @@ struct oxygen {
134 140
135int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 141int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
136 struct module *owner, 142 struct module *owner,
137 const struct oxygen_model *model, 143 const struct pci_device_id *ids,
138 unsigned long driver_data); 144 int (*get_model)(struct oxygen *chip,
145 const struct pci_device_id *id
146 )
147 );
139void oxygen_pci_remove(struct pci_dev *pci); 148void oxygen_pci_remove(struct pci_dev *pci);
140#ifdef CONFIG_PM 149#ifdef CONFIG_PM
141int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 150int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
@@ -180,6 +189,8 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
180void oxygen_reset_uart(struct oxygen *chip); 189void oxygen_reset_uart(struct oxygen *chip);
181void oxygen_write_uart(struct oxygen *chip, u8 data); 190void oxygen_write_uart(struct oxygen *chip, u8 data);
182 191
192u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index);
193
183static inline void oxygen_set_bits8(struct oxygen *chip, 194static inline void oxygen_set_bits8(struct oxygen *chip,
184 unsigned int reg, u8 value) 195 unsigned int reg, u8 value)
185{ 196{
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 3126c4b403dd..05f48ef1a442 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -254,3 +254,18 @@ void oxygen_write_uart(struct oxygen *chip, u8 data)
254 _write_uart(chip, 0, data); 254 _write_uart(chip, 0, data);
255} 255}
256EXPORT_SYMBOL(oxygen_write_uart); 256EXPORT_SYMBOL(oxygen_write_uart);
257
258u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index)
259{
260 unsigned int timeout;
261
262 oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
263 index | OXYGEN_EEPROM_DIR_READ);
264 for (timeout = 0; timeout < 100; ++timeout) {
265 udelay(1);
266 if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
267 & OXYGEN_EEPROM_BUSY))
268 break;
269 }
270 return oxygen_read16(chip, OXYGEN_EEPROM_DATA);
271}
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 516d94ad2bbb..d83c3a957323 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -244,6 +244,34 @@ static void oxygen_proc_init(struct oxygen *chip)
244#define oxygen_proc_init(chip) 244#define oxygen_proc_init(chip)
245#endif 245#endif
246 246
247static const struct pci_device_id *
248oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
249{
250 u16 subdevice;
251
252 /*
253 * Make sure the EEPROM pins are available, i.e., not used for SPI.
254 * (This function is called before we initialize or use SPI.)
255 */
256 oxygen_clear_bits8(chip, OXYGEN_FUNCTION,
257 OXYGEN_FUNCTION_ENABLE_SPI_4_5);
258 /*
259 * Read the subsystem device ID directly from the EEPROM, because the
260 * chip didn't if the first EEPROM word was overwritten.
261 */
262 subdevice = oxygen_read_eeprom(chip, 2);
263 /*
264 * We use only the subsystem device ID for searching because it is
265 * unique even without the subsystem vendor ID, which may have been
266 * overwritten in the EEPROM.
267 */
268 for (; ids->vendor; ++ids)
269 if (ids->subdevice == subdevice &&
270 ids->driver_data != BROKEN_EEPROM_DRIVER_DATA)
271 return ids;
272 return NULL;
273}
274
247static void oxygen_init(struct oxygen *chip) 275static void oxygen_init(struct oxygen *chip)
248{ 276{
249 unsigned int i; 277 unsigned int i;
@@ -455,11 +483,15 @@ static void oxygen_card_free(struct snd_card *card)
455 483
456int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 484int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
457 struct module *owner, 485 struct module *owner,
458 const struct oxygen_model *model, 486 const struct pci_device_id *ids,
459 unsigned long driver_data) 487 int (*get_model)(struct oxygen *chip,
488 const struct pci_device_id *id
489 )
490 )
460{ 491{
461 struct snd_card *card; 492 struct snd_card *card;
462 struct oxygen *chip; 493 struct oxygen *chip;
494 const struct pci_device_id *pci_id;
463 int err; 495 int err;
464 496
465 err = snd_card_create(index, id, owner, sizeof(*chip), &card); 497 err = snd_card_create(index, id, owner, sizeof(*chip), &card);
@@ -470,7 +502,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
470 chip->card = card; 502 chip->card = card;
471 chip->pci = pci; 503 chip->pci = pci;
472 chip->irq = -1; 504 chip->irq = -1;
473 chip->model = *model;
474 spin_lock_init(&chip->reg_lock); 505 spin_lock_init(&chip->reg_lock);
475 mutex_init(&chip->mutex); 506 mutex_init(&chip->mutex);
476 INIT_WORK(&chip->spdif_input_bits_work, 507 INIT_WORK(&chip->spdif_input_bits_work,
@@ -496,6 +527,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
496 } 527 }
497 chip->addr = pci_resource_start(pci, 0); 528 chip->addr = pci_resource_start(pci, 0);
498 529
530 pci_id = oxygen_search_pci_id(chip, ids);
531 if (!pci_id) {
532 err = -ENODEV;
533 goto err_pci_regions;
534 }
535 err = get_model(chip, pci_id);
536 if (err < 0)
537 goto err_pci_regions;
538
499 if (chip->model.model_data_size) { 539 if (chip->model.model_data_size) {
500 chip->model_data = kmalloc(chip->model.model_data_size, 540 chip->model_data = kmalloc(chip->model.model_data_size,
501 GFP_KERNEL); 541 GFP_KERNEL);
@@ -509,11 +549,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
509 snd_card_set_dev(card, &pci->dev); 549 snd_card_set_dev(card, &pci->dev);
510 card->private_free = oxygen_card_free; 550 card->private_free = oxygen_card_free;
511 551
512 if (chip->model.probe) {
513 err = chip->model.probe(chip, driver_data);
514 if (err < 0)
515 goto err_card;
516 }
517 oxygen_init(chip); 552 oxygen_init(chip);
518 chip->model.init(chip); 553 chip->model.init(chip);
519 554
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index c05f7e7bdb34..4ac49772da8c 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -160,6 +160,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
160 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, 160 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
161 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV }, 161 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV },
162 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, 162 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
163 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
163 { } 164 { }
164}; 165};
165MODULE_DEVICE_TABLE(pci, xonar_ids); 166MODULE_DEVICE_TABLE(pci, xonar_ids);
@@ -188,7 +189,6 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
188#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ 189#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
189 190
190struct xonar_data { 191struct xonar_data {
191 unsigned int model;
192 unsigned int anti_pop_delay; 192 unsigned int anti_pop_delay;
193 unsigned int dacs; 193 unsigned int dacs;
194 u16 output_enable_bit; 194 u16 output_enable_bit;
@@ -334,15 +334,9 @@ static void xonar_d2_init(struct oxygen *chip)
334 struct xonar_data *data = chip->model_data; 334 struct xonar_data *data = chip->model_data;
335 335
336 data->anti_pop_delay = 300; 336 data->anti_pop_delay = 300;
337 data->dacs = 4;
337 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 338 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
338 data->pcm1796_oversampling = PCM1796_OS_64; 339 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 340
347 pcm1796_init(chip); 341 pcm1796_init(chip);
348 342
@@ -355,6 +349,18 @@ static void xonar_d2_init(struct oxygen *chip)
355 snd_component_add(chip->card, "CS5381"); 349 snd_component_add(chip->card, "CS5381");
356} 350}
357 351
352static void xonar_d2x_init(struct oxygen *chip)
353{
354 struct xonar_data *data = chip->model_data;
355
356 data->ext_power_reg = OXYGEN_GPIO_DATA;
357 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
358 data->ext_power_bit = GPIO_D2X_EXT_POWER;
359 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
360
361 xonar_d2_init(chip);
362}
363
358static void update_cs4362a_volumes(struct oxygen *chip) 364static void update_cs4362a_volumes(struct oxygen *chip)
359{ 365{
360 u8 mute; 366 u8 mute;
@@ -422,11 +428,6 @@ static void xonar_d1_init(struct oxygen *chip)
422 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; 428 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
423 data->cs4362a_fm = CS4362A_FM_SINGLE | 429 data->cs4362a_fm = CS4362A_FM_SINGLE |
424 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 430 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 431
431 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 432 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
432 OXYGEN_2WIRE_LENGTH_8 | 433 OXYGEN_2WIRE_LENGTH_8 |
@@ -447,6 +448,17 @@ static void xonar_d1_init(struct oxygen *chip)
447 snd_component_add(chip->card, "CS5361"); 448 snd_component_add(chip->card, "CS5361");
448} 449}
449 450
451static void xonar_dx_init(struct oxygen *chip)
452{
453 struct xonar_data *data = chip->model_data;
454
455 data->ext_power_reg = OXYGEN_GPI_DATA;
456 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
457 data->ext_power_bit = GPI_DX_EXT_POWER;
458
459 xonar_d1_init(chip);
460}
461
450static void xonar_hdav_init(struct oxygen *chip) 462static void xonar_hdav_init(struct oxygen *chip)
451{ 463{
452 struct xonar_data *data = chip->model_data; 464 struct xonar_data *data = chip->model_data;
@@ -458,6 +470,7 @@ static void xonar_hdav_init(struct oxygen *chip)
458 OXYGEN_2WIRE_SPEED_FAST); 470 OXYGEN_2WIRE_SPEED_FAST);
459 471
460 data->anti_pop_delay = 100; 472 data->anti_pop_delay = 100;
473 data->dacs = chip->model.private_data == MODEL_HDAV_H6 ? 4 : 1;
461 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; 474 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
462 data->ext_power_reg = OXYGEN_GPI_DATA; 475 data->ext_power_reg = OXYGEN_GPI_DATA;
463 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 476 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
@@ -773,50 +786,9 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
773 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); 786 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
774} 787}
775 788
776static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data)
777{
778 static const char *const names[] = {
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}
815
816static const struct oxygen_model model_xonar_d2 = { 789static const struct oxygen_model model_xonar_d2 = {
817 .longname = "Asus Virtuoso 200", 790 .longname = "Asus Virtuoso 200",
818 .chip = "AV200", 791 .chip = "AV200",
819 .probe = xonar_model_probe,
820 .init = xonar_d2_init, 792 .init = xonar_d2_init,
821 .control_filter = xonar_d2_control_filter, 793 .control_filter = xonar_d2_control_filter,
822 .mixer_init = xonar_d2_mixer_init, 794 .mixer_init = xonar_d2_mixer_init,
@@ -848,7 +820,6 @@ static const struct oxygen_model model_xonar_d2 = {
848static const struct oxygen_model model_xonar_d1 = { 820static const struct oxygen_model model_xonar_d1 = {
849 .longname = "Asus Virtuoso 100", 821 .longname = "Asus Virtuoso 100",
850 .chip = "AV200", 822 .chip = "AV200",
851 .probe = xonar_model_probe,
852 .init = xonar_d1_init, 823 .init = xonar_d1_init,
853 .control_filter = xonar_d1_control_filter, 824 .control_filter = xonar_d1_control_filter,
854 .mixer_init = xonar_d1_mixer_init, 825 .mixer_init = xonar_d1_mixer_init,
@@ -876,7 +847,6 @@ static const struct oxygen_model model_xonar_d1 = {
876static const struct oxygen_model model_xonar_hdav = { 847static const struct oxygen_model model_xonar_hdav = {
877 .longname = "Asus Virtuoso 200", 848 .longname = "Asus Virtuoso 200",
878 .chip = "AV200", 849 .chip = "AV200",
879 .probe = xonar_model_probe,
880 .init = xonar_hdav_init, 850 .init = xonar_hdav_init,
881 .cleanup = xonar_hdav_cleanup, 851 .cleanup = xonar_hdav_cleanup,
882 .suspend = xonar_hdav_suspend, 852 .suspend = xonar_hdav_suspend,
@@ -902,8 +872,8 @@ static const struct oxygen_model model_xonar_hdav = {
902 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 872 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
903}; 873};
904 874
905static int __devinit xonar_probe(struct pci_dev *pci, 875static int __devinit get_xonar_model(struct oxygen *chip,
906 const struct pci_device_id *pci_id) 876 const struct pci_device_id *id)
907{ 877{
908 static const struct oxygen_model *const models[] = { 878 static const struct oxygen_model *const models[] = {
909 [MODEL_D1] = &model_xonar_d1, 879 [MODEL_D1] = &model_xonar_d1,
@@ -912,6 +882,50 @@ static int __devinit xonar_probe(struct pci_dev *pci,
912 [MODEL_D2X] = &model_xonar_d2, 882 [MODEL_D2X] = &model_xonar_d2,
913 [MODEL_HDAV] = &model_xonar_hdav, 883 [MODEL_HDAV] = &model_xonar_hdav,
914 }; 884 };
885 static const char *const names[] = {
886 [MODEL_D1] = "Xonar D1",
887 [MODEL_DX] = "Xonar DX",
888 [MODEL_D2] = "Xonar D2",
889 [MODEL_D2X] = "Xonar D2X",
890 [MODEL_HDAV] = "Xonar HDAV1.3",
891 [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
892 };
893 unsigned int model = id->driver_data;
894
895 if (model >= ARRAY_SIZE(models) || !models[model])
896 return -EINVAL;
897 chip->model = *models[model];
898
899 switch (model) {
900 case MODEL_D2X:
901 chip->model.init = xonar_d2x_init;
902 break;
903 case MODEL_DX:
904 chip->model.init = xonar_dx_init;
905 break;
906 case MODEL_HDAV:
907 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
908 GPIO_HDAV_DB_MASK);
909 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) &
910 GPIO_HDAV_DB_MASK) {
911 case GPIO_HDAV_DB_H6:
912 model = MODEL_HDAV_H6;
913 break;
914 case GPIO_HDAV_DB_XX:
915 snd_printk(KERN_ERR "unknown daughterboard\n");
916 return -ENODEV;
917 }
918 break;
919 }
920
921 chip->model.shortname = names[model];
922 chip->model.private_data = model;
923 return 0;
924}
925
926static int __devinit xonar_probe(struct pci_dev *pci,
927 const struct pci_device_id *pci_id)
928{
915 static int dev; 929 static int dev;
916 int err; 930 int err;
917 931
@@ -921,10 +935,8 @@ static int __devinit xonar_probe(struct pci_dev *pci,
921 ++dev; 935 ++dev;
922 return -ENOENT; 936 return -ENOENT;
923 } 937 }
924 BUG_ON(pci_id->driver_data >= ARRAY_SIZE(models));
925 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, 938 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
926 models[pci_id->driver_data], 939 xonar_ids, get_xonar_model);
927 pci_id->driver_data);
928 if (err >= 0) 940 if (err >= 0)
929 ++dev; 941 ++dev;
930 return err; 942 return err;