aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-02-19 02:42:44 -0500
committerTakashi Iwai <tiwai@suse.de>2009-02-19 04:22:25 -0500
commit30459d7b1843cbdea56ca120c8cac10dc5613e90 (patch)
tree47341d43931193917c28dab16eaf7e1a12b2b6d6 /sound/pci/oxygen/oxygen.c
parenta69bb3c3fe0881d986ec78e253cb8a6bb9c28230 (diff)
sound: oxygen: handle cards with broken EEPROM
Under as yet unknown circumstances, the first word of the sound card's EEPROM gets overwritten. When this has happened, we cannot rely on the subsystem IDs that the kernel reads from the PCI configuration registers. Instead, we read the IDs directly from the EEPROM and do the ID matching manually. Because the model-specific driver cannot determine the model before calling oxygen_pci_probe(), that function now gets a get_model() callback as parameter. The customizing of the model structure, which was formerly done by the probe() callback, also has moved into get_model(). Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r--sound/pci/oxygen/oxygen.c44
1 files changed, 24 insertions, 20 deletions
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;