aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:17 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:17 -0400
commitb54fc8dd2c43888f2754505cca2b6e88604a8ffa (patch)
tree7613f3734b0b91c316438c2fd3814a5565e8593a
parent9fb5430c3d6e96a74fd4406dbe7608f36abb9987 (diff)
parent873591db59e66434fd0a484c92f69fc21100b33d (diff)
Merge branch 'topic/oxygen' into for-linus
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt2
-rw-r--r--sound/pci/Kconfig3
-rw-r--r--sound/pci/oxygen/hifier.c12
-rw-r--r--sound/pci/oxygen/oxygen.c114
-rw-r--r--sound/pci/oxygen/oxygen.h22
-rw-r--r--sound/pci/oxygen/oxygen_io.c31
-rw-r--r--sound/pci/oxygen/oxygen_lib.c100
-rw-r--r--sound/pci/oxygen/virtuoso.c339
8 files changed, 507 insertions, 116 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index c911c203d1f5..012858d2b119 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1859,7 +1859,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1859 ------------------- 1859 -------------------
1860 1860
1861 Module for sound cards based on the Asus AV100/AV200 chips, 1861 Module for sound cards based on the Asus AV100/AV200 chips,
1862 i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe). 1862 i.e., Xonar D1, DX, D2, D2X, HDAV1.3 (Deluxe), and Essence STX.
1863 1863
1864 This module supports autoprobe and multiple cards. 1864 This module supports autoprobe and multiple cards.
1865 1865
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 9387ab00a41b..ca25e6179d76 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -764,7 +764,8 @@ config SND_VIRTUOSO
764 select SND_OXYGEN_LIB 764 select SND_OXYGEN_LIB
765 help 765 help
766 Say Y here to include support for sound cards based on the 766 Say Y here to include support for sound cards based on the
767 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. 767 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, and
768 Essence STX.
768 Support for the HDAV1.3 (Deluxe) is very experimental. 769 Support for the HDAV1.3 (Deluxe) is very experimental.
769 770
770 To compile this driver as a module, choose M here: the module 771 To compile this driver as a module, choose M here: the module
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 1ab833f843eb..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);
@@ -151,7 +152,6 @@ static const struct oxygen_model model_hifier = {
151 .shortname = "C-Media CMI8787", 152 .shortname = "C-Media CMI8787",
152 .longname = "C-Media Oxygen HD Audio", 153 .longname = "C-Media Oxygen HD Audio",
153 .chip = "CMI8788", 154 .chip = "CMI8788",
154 .owner = THIS_MODULE,
155 .init = hifier_init, 155 .init = hifier_init,
156 .control_filter = hifier_control_filter, 156 .control_filter = hifier_control_filter,
157 .cleanup = hifier_cleanup, 157 .cleanup = hifier_cleanup,
@@ -173,6 +173,13 @@ static const struct oxygen_model model_hifier = {
173 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 173 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
174}; 174};
175 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
176static int __devinit hifier_probe(struct pci_dev *pci, 183static int __devinit hifier_probe(struct pci_dev *pci,
177 const struct pci_device_id *pci_id) 184 const struct pci_device_id *pci_id)
178{ 185{
@@ -185,7 +192,8 @@ static int __devinit hifier_probe(struct pci_dev *pci,
185 ++dev; 192 ++dev;
186 return -ENOENT; 193 return -ENOENT;
187 } 194 }
188 err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0); 195 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
196 hifier_ids, get_hifier_model);
189 if (err >= 0) 197 if (err >= 0)
190 ++dev; 198 ++dev;
191 return err; 199 return err;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index de999c6d6dd3..72db4c39007f 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * C-Media CMI8788 driver for C-Media's reference design and for the X-Meridian 2 * C-Media CMI8788 driver for C-Media's reference design and similar models
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
@@ -26,6 +26,7 @@
26 * 26 *
27 * GPIO 0 -> DFS0 of AK5385 27 * GPIO 0 -> DFS0 of AK5385
28 * GPIO 1 -> DFS1 of AK5385 28 * GPIO 1 -> DFS1 of AK5385
29 * GPIO 8 -> enable headphone amplifier on HT-Omega models
29 */ 30 */
30 31
31#include <linux/delay.h> 32#include <linux/delay.h>
@@ -61,7 +62,8 @@ MODULE_PARM_DESC(enable, "enable card");
61enum { 62enum {
62 MODEL_CMEDIA_REF, /* C-Media's reference design */ 63 MODEL_CMEDIA_REF, /* C-Media's reference design */
63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 64 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
64 MODEL_HALO, /* HT-Omega Claro halo */ 65 MODEL_CLARO, /* HT-Omega Claro */
66 MODEL_CLARO_HALO, /* HT-Omega Claro halo */
65}; 67};
66 68
67static struct pci_device_id oxygen_ids[] __devinitdata = { 69static struct pci_device_id oxygen_ids[] __devinitdata = {
@@ -74,8 +76,8 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
74 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 76 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
75 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
76 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 78 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
77 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, 79 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
78 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO }, 80 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
79 { } 81 { }
80}; 82};
81MODULE_DEVICE_TABLE(pci, oxygen_ids); 83MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -86,6 +88,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
86#define GPIO_AK5385_DFS_DOUBLE 0x0001 88#define GPIO_AK5385_DFS_DOUBLE 0x0001
87#define GPIO_AK5385_DFS_QUAD 0x0002 89#define GPIO_AK5385_DFS_QUAD 0x0002
88 90
91#define GPIO_CLARO_HP 0x0100
92
89struct generic_data { 93struct generic_data {
90 u8 ak4396_ctl2; 94 u8 ak4396_ctl2;
91 u16 saved_wm8785_registers[2]; 95 u16 saved_wm8785_registers[2];
@@ -196,10 +200,46 @@ static void meridian_init(struct oxygen *chip)
196 ak5385_init(chip); 200 ak5385_init(chip);
197} 201}
198 202
203static void claro_enable_hp(struct oxygen *chip)
204{
205 msleep(300);
206 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_HP);
207 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
208}
209
210static void claro_init(struct oxygen *chip)
211{
212 ak4396_init(chip);
213 wm8785_init(chip);
214 claro_enable_hp(chip);
215}
216
217static void claro_halo_init(struct oxygen *chip)
218{
219 ak4396_init(chip);
220 ak5385_init(chip);
221 claro_enable_hp(chip);
222}
223
199static void generic_cleanup(struct oxygen *chip) 224static void generic_cleanup(struct oxygen *chip)
200{ 225{
201} 226}
202 227
228static void claro_disable_hp(struct oxygen *chip)
229{
230 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
231}
232
233static void claro_cleanup(struct oxygen *chip)
234{
235 claro_disable_hp(chip);
236}
237
238static void claro_suspend(struct oxygen *chip)
239{
240 claro_disable_hp(chip);
241}
242
203static void generic_resume(struct oxygen *chip) 243static void generic_resume(struct oxygen *chip)
204{ 244{
205 ak4396_registers_init(chip); 245 ak4396_registers_init(chip);
@@ -211,6 +251,12 @@ static void meridian_resume(struct oxygen *chip)
211 ak4396_registers_init(chip); 251 ak4396_registers_init(chip);
212} 252}
213 253
254static void claro_resume(struct oxygen *chip)
255{
256 ak4396_registers_init(chip);
257 claro_enable_hp(chip);
258}
259
214static void set_ak4396_params(struct oxygen *chip, 260static void set_ak4396_params(struct oxygen *chip,
215 struct snd_pcm_hw_params *params) 261 struct snd_pcm_hw_params *params)
216{ 262{
@@ -293,30 +339,10 @@ static void set_ak5385_params(struct oxygen *chip,
293 339
294static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 340static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
295 341
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 = { 342static const struct oxygen_model model_generic = {
315 .shortname = "C-Media CMI8788", 343 .shortname = "C-Media CMI8788",
316 .longname = "C-Media Oxygen HD Audio", 344 .longname = "C-Media Oxygen HD Audio",
317 .chip = "CMI8788", 345 .chip = "CMI8788",
318 .owner = THIS_MODULE,
319 .probe = generic_probe,
320 .init = generic_init, 346 .init = generic_init,
321 .cleanup = generic_cleanup, 347 .cleanup = generic_cleanup,
322 .resume = generic_resume, 348 .resume = generic_resume,
@@ -341,6 +367,42 @@ static const struct oxygen_model model_generic = {
341 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 367 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
342}; 368};
343 369
370static int __devinit get_oxygen_model(struct oxygen *chip,
371 const struct pci_device_id *id)
372{
373 chip->model = model_generic;
374 switch (id->driver_data) {
375 case MODEL_MERIDIAN:
376 chip->model.init = meridian_init;
377 chip->model.resume = meridian_resume;
378 chip->model.set_adc_params = set_ak5385_params;
379 chip->model.device_config = PLAYBACK_0_TO_I2S |
380 PLAYBACK_1_TO_SPDIF |
381 CAPTURE_0_FROM_I2S_2 |
382 CAPTURE_1_FROM_SPDIF;
383 break;
384 case MODEL_CLARO:
385 chip->model.init = claro_init;
386 chip->model.cleanup = claro_cleanup;
387 chip->model.suspend = claro_suspend;
388 chip->model.resume = claro_resume;
389 break;
390 case MODEL_CLARO_HALO:
391 chip->model.init = claro_halo_init;
392 chip->model.cleanup = claro_cleanup;
393 chip->model.suspend = claro_suspend;
394 chip->model.resume = claro_resume;
395 chip->model.set_adc_params = set_ak5385_params;
396 break;
397 }
398 if (id->driver_data == MODEL_MERIDIAN ||
399 id->driver_data == MODEL_CLARO_HALO) {
400 chip->model.misc_flags = OXYGEN_MISC_MIDI;
401 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
402 }
403 return 0;
404}
405
344static int __devinit generic_oxygen_probe(struct pci_dev *pci, 406static int __devinit generic_oxygen_probe(struct pci_dev *pci,
345 const struct pci_device_id *pci_id) 407 const struct pci_device_id *pci_id)
346{ 408{
@@ -353,8 +415,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
353 ++dev; 415 ++dev;
354 return -ENOENT; 416 return -ENOENT;
355 } 417 }
356 err = oxygen_pci_probe(pci, index[dev], id[dev], 418 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
357 &model_generic, pci_id->driver_data); 419 oxygen_ids, get_oxygen_model);
358 if (err >= 0) 420 if (err >= 0)
359 ++dev; 421 ++dev;
360 return err; 422 return err;
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 19107c6307e5..bd615dbffadb 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -18,6 +18,8 @@
18 18
19#define OXYGEN_IO_SIZE 0x100 19#define OXYGEN_IO_SIZE 0x100
20 20
21#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
22
21/* model-specific configuration of outputs/inputs */ 23/* model-specific configuration of outputs/inputs */
22#define PLAYBACK_0_TO_I2S 0x0001 24#define PLAYBACK_0_TO_I2S 0x0001
23 /* PLAYBACK_0_TO_AC97_0 not implemented */ 25 /* PLAYBACK_0_TO_AC97_0 not implemented */
@@ -49,7 +51,13 @@ enum {
49 .subvendor = sv, \ 51 .subvendor = sv, \
50 .subdevice = sd 52 .subdevice = sd
51 53
54#define BROKEN_EEPROM_DRIVER_DATA ((unsigned long)-1)
55#define OXYGEN_PCI_SUBID_BROKEN_EEPROM \
56 OXYGEN_PCI_SUBID(PCI_VENDOR_ID_CMEDIA, 0x8788), \
57 .driver_data = BROKEN_EEPROM_DRIVER_DATA
58
52struct pci_dev; 59struct pci_dev;
60struct pci_device_id;
53struct snd_card; 61struct snd_card;
54struct snd_pcm_substream; 62struct snd_pcm_substream;
55struct snd_pcm_hardware; 63struct snd_pcm_hardware;
@@ -62,8 +70,6 @@ struct oxygen_model {
62 const char *shortname; 70 const char *shortname;
63 const char *longname; 71 const char *longname;
64 const char *chip; 72 const char *chip;
65 struct module *owner;
66 int (*probe)(struct oxygen *chip, unsigned long driver_data);
67 void (*init)(struct oxygen *chip); 73 void (*init)(struct oxygen *chip);
68 int (*control_filter)(struct snd_kcontrol_new *template); 74 int (*control_filter)(struct snd_kcontrol_new *template);
69 int (*mixer_init)(struct oxygen *chip); 75 int (*mixer_init)(struct oxygen *chip);
@@ -83,6 +89,7 @@ struct oxygen_model {
83 void (*ac97_switch)(struct oxygen *chip, 89 void (*ac97_switch)(struct oxygen *chip,
84 unsigned int reg, unsigned int mute); 90 unsigned int reg, unsigned int mute);
85 const unsigned int *dac_tlv; 91 const unsigned int *dac_tlv;
92 unsigned long private_data;
86 size_t model_data_size; 93 size_t model_data_size;
87 unsigned int device_config; 94 unsigned int device_config;
88 u8 dac_channels; 95 u8 dac_channels;
@@ -134,8 +141,12 @@ struct oxygen {
134/* oxygen_lib.c */ 141/* oxygen_lib.c */
135 142
136int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 143int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
137 const struct oxygen_model *model, 144 struct module *owner,
138 unsigned long driver_data); 145 const struct pci_device_id *ids,
146 int (*get_model)(struct oxygen *chip,
147 const struct pci_device_id *id
148 )
149 );
139void oxygen_pci_remove(struct pci_dev *pci); 150void oxygen_pci_remove(struct pci_dev *pci);
140#ifdef CONFIG_PM 151#ifdef CONFIG_PM
141int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 152int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
@@ -180,6 +191,9 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
180void oxygen_reset_uart(struct oxygen *chip); 191void oxygen_reset_uart(struct oxygen *chip);
181void oxygen_write_uart(struct oxygen *chip, u8 data); 192void oxygen_write_uart(struct oxygen *chip, u8 data);
182 193
194u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index);
195void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value);
196
183static inline void oxygen_set_bits8(struct oxygen *chip, 197static inline void oxygen_set_bits8(struct oxygen *chip,
184 unsigned int reg, u8 value) 198 unsigned int reg, u8 value)
185{ 199{
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 3126c4b403dd..c1eb923f2ac9 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -254,3 +254,34 @@ 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}
272
273void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value)
274{
275 unsigned int timeout;
276
277 oxygen_write16(chip, OXYGEN_EEPROM_DATA, value);
278 oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
279 index | OXYGEN_EEPROM_DIR_WRITE);
280 for (timeout = 0; timeout < 10; ++timeout) {
281 msleep(1);
282 if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
283 & OXYGEN_EEPROM_BUSY))
284 return;
285 }
286 snd_printk(KERN_ERR "EEPROM write timeout\n");
287}
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9c81e0b05113..312251d39696 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -34,6 +34,7 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
34MODULE_DESCRIPTION("C-Media CMI8788 helper library"); 34MODULE_DESCRIPTION("C-Media CMI8788 helper library");
35MODULE_LICENSE("GPL v2"); 35MODULE_LICENSE("GPL v2");
36 36
37#define DRIVER "oxygen"
37 38
38static inline int oxygen_uart_input_ready(struct oxygen *chip) 39static inline int oxygen_uart_input_ready(struct oxygen *chip)
39{ 40{
@@ -243,6 +244,62 @@ static void oxygen_proc_init(struct oxygen *chip)
243#define oxygen_proc_init(chip) 244#define oxygen_proc_init(chip)
244#endif 245#endif
245 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
275static void oxygen_restore_eeprom(struct oxygen *chip,
276 const struct pci_device_id *id)
277{
278 if (oxygen_read_eeprom(chip, 0) != OXYGEN_EEPROM_ID) {
279 /*
280 * This function gets called only when a known card model has
281 * been detected, i.e., we know there is a valid subsystem
282 * product ID at index 2 in the EEPROM. Therefore, we have
283 * been able to deduce the correct subsystem vendor ID, and
284 * this is enough information to restore the original EEPROM
285 * contents.
286 */
287 oxygen_write_eeprom(chip, 1, id->subvendor);
288 oxygen_write_eeprom(chip, 0, OXYGEN_EEPROM_ID);
289
290 oxygen_set_bits8(chip, OXYGEN_MISC,
291 OXYGEN_MISC_WRITE_PCI_SUBID);
292 pci_write_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID,
293 id->subvendor);
294 pci_write_config_word(chip->pci, PCI_SUBSYSTEM_ID,
295 id->subdevice);
296 oxygen_clear_bits8(chip, OXYGEN_MISC,
297 OXYGEN_MISC_WRITE_PCI_SUBID);
298
299 snd_printk(KERN_INFO "EEPROM ID restored\n");
300 }
301}
302
246static void oxygen_init(struct oxygen *chip) 303static void oxygen_init(struct oxygen *chip)
247{ 304{
248 unsigned int i; 305 unsigned int i;
@@ -446,21 +503,26 @@ static void oxygen_card_free(struct snd_card *card)
446 free_irq(chip->irq, chip); 503 free_irq(chip->irq, chip);
447 flush_scheduled_work(); 504 flush_scheduled_work();
448 chip->model.cleanup(chip); 505 chip->model.cleanup(chip);
506 kfree(chip->model_data);
449 mutex_destroy(&chip->mutex); 507 mutex_destroy(&chip->mutex);
450 pci_release_regions(chip->pci); 508 pci_release_regions(chip->pci);
451 pci_disable_device(chip->pci); 509 pci_disable_device(chip->pci);
452} 510}
453 511
454int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, 512int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
455 const struct oxygen_model *model, 513 struct module *owner,
456 unsigned long driver_data) 514 const struct pci_device_id *ids,
515 int (*get_model)(struct oxygen *chip,
516 const struct pci_device_id *id
517 )
518 )
457{ 519{
458 struct snd_card *card; 520 struct snd_card *card;
459 struct oxygen *chip; 521 struct oxygen *chip;
522 const struct pci_device_id *pci_id;
460 int err; 523 int err;
461 524
462 err = snd_card_create(index, id, model->owner, 525 err = snd_card_create(index, id, owner, sizeof(*chip), &card);
463 sizeof(*chip) + model->model_data_size, &card);
464 if (err < 0) 526 if (err < 0)
465 return err; 527 return err;
466 528
@@ -468,8 +530,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
468 chip->card = card; 530 chip->card = card;
469 chip->pci = pci; 531 chip->pci = pci;
470 chip->irq = -1; 532 chip->irq = -1;
471 chip->model = *model;
472 chip->model_data = chip + 1;
473 spin_lock_init(&chip->reg_lock); 533 spin_lock_init(&chip->reg_lock);
474 mutex_init(&chip->mutex); 534 mutex_init(&chip->mutex);
475 INIT_WORK(&chip->spdif_input_bits_work, 535 INIT_WORK(&chip->spdif_input_bits_work,
@@ -481,7 +541,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
481 if (err < 0) 541 if (err < 0)
482 goto err_card; 542 goto err_card;
483 543
484 err = pci_request_regions(pci, model->chip); 544 err = pci_request_regions(pci, DRIVER);
485 if (err < 0) { 545 if (err < 0) {
486 snd_printk(KERN_ERR "cannot reserve PCI resources\n"); 546 snd_printk(KERN_ERR "cannot reserve PCI resources\n");
487 goto err_pci_enable; 547 goto err_pci_enable;
@@ -495,20 +555,34 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
495 } 555 }
496 chip->addr = pci_resource_start(pci, 0); 556 chip->addr = pci_resource_start(pci, 0);
497 557
558 pci_id = oxygen_search_pci_id(chip, ids);
559 if (!pci_id) {
560 err = -ENODEV;
561 goto err_pci_regions;
562 }
563 oxygen_restore_eeprom(chip, pci_id);
564 err = get_model(chip, pci_id);
565 if (err < 0)
566 goto err_pci_regions;
567
568 if (chip->model.model_data_size) {
569 chip->model_data = kzalloc(chip->model.model_data_size,
570 GFP_KERNEL);
571 if (!chip->model_data) {
572 err = -ENOMEM;
573 goto err_pci_regions;
574 }
575 }
576
498 pci_set_master(pci); 577 pci_set_master(pci);
499 snd_card_set_dev(card, &pci->dev); 578 snd_card_set_dev(card, &pci->dev);
500 card->private_free = oxygen_card_free; 579 card->private_free = oxygen_card_free;
501 580
502 if (chip->model.probe) {
503 err = chip->model.probe(chip, driver_data);
504 if (err < 0)
505 goto err_card;
506 }
507 oxygen_init(chip); 581 oxygen_init(chip);
508 chip->model.init(chip); 582 chip->model.init(chip);
509 583
510 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED, 584 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
511 chip->model.chip, chip); 585 DRIVER, chip);
512 if (err < 0) { 586 if (err < 0) {
513 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq); 587 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
514 goto err_card; 588 goto err_card;
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;