int chip_version;
int max_channels;
- unsigned int has_dual_dac: 1;
unsigned int can_ac3_sw: 1;
unsigned int can_ac3_hw: 1;
unsigned int can_multi_ch: 1;
if (! detect) {
/* check reg 08h, bit 24-28 */
detect = snd_cmipci_read(cm, CM_REG_CHFORMAT) & CM_CHIP_MASK1;
- if (! detect) {
+ switch (detect) {
+ case 0:
cm->chip_version = 33;
- cm->max_channels = 2;
if (cm->do_soft_ac3)
cm->can_ac3_sw = 1;
else
cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- } else {
+ break;
+ case 1:
cm->chip_version = 37;
- cm->max_channels = 2;
cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
+ break;
+ default:
+ cm->chip_version = 39;
+ cm->can_ac3_hw = 1;
+ break;
}
+ cm->max_channels = 2;
} else {
- /* check reg 0Ch, bit 26 */
- if (detect & CM_CHIP_8768) {
- cm->chip_version = 68;
- cm->max_channels = 8;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
- } else if (detect & CM_CHIP_055) {
- cm->chip_version = 55;
- cm->max_channels = 6;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
- } else if (detect & CM_CHIP_039) {
+ if (detect & CM_CHIP_039) {
cm->chip_version = 39;
if (detect & CM_CHIP_039_6CH) /* 4 or 6 channels */
cm->max_channels = 6;
else
cm->max_channels = 4;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
+ } else if (detect & CM_CHIP_8768) {
+ cm->chip_version = 68;
+ cm->max_channels = 8;
} else {
- printk(KERN_ERR "chip %x version not supported\n", detect);
+ cm->chip_version = 55;
+ cm->max_channels = 6;
}
+ cm->can_ac3_hw = 1;
+ cm->can_multi_ch = 1;
}
}
if (!fm_port)
goto disable_fm;
- /* first try FM regs in PCI port range */
- iosynth = cm->iobase + CM_REG_FM_PCI;
- err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 1, &opl3);
+ if (cm->chip_version > 33) {
+ /* first try FM regs in PCI port range */
+ iosynth = cm->iobase + CM_REG_FM_PCI;
+ err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 1, &opl3);
+ } else {
+ err = -EIO;
+ }
if (err < 0) {
/* then try legacy ports */
val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
static struct snd_device_ops ops = {
.dev_free = snd_cmipci_dev_free,
};
- unsigned int val = 0;
+ unsigned int val;
long iomidi;
- int integrated_midi;
+ int integrated_midi = 0;
int pcm_index, pcm_spdif_index;
static struct pci_device_id intel_82437vx[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
break;
}
+ sprintf(card->shortname, "C-Media %s", card->driver);
+ if (cm->chip_version < 68) {
+ val = pci->device < 0x110 ? 8338 : 8738;
+ sprintf(card->longname,
+ "C-Media CMI%d (model %d) at 0x%lx, irq %i",
+ val, cm->chip_version, cm->iobase, cm->irq);
+ } else {
+ switch (snd_cmipci_read_b(cm, CM_REG_INT_HLDCLR + 3) & 0x03) {
+ case 0:
+ val = 8769;
+ break;
+ case 2:
+ val = 8762;
+ break;
+ default:
+ switch ((pci->subsystem_vendor << 16) |
+ pci->subsystem_device) {
+ case 0x13f69761:
+ case 0x584d3741:
+ case 0x584d3751:
+ case 0x584d3761:
+ case 0x584d3771:
+ case 0x72848384:
+ val = 8770;
+ break;
+ default:
+ val = 8768;
+ break;
+ }
+ }
+ sprintf(card->longname, "C-Media CMI%d at 0x%lx, irq %i",
+ val, cm->iobase, cm->irq);
+ }
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
snd_cmipci_free(cm);
return err;
}
- integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
- if (integrated_midi && mpu_port[dev] == 1)
- iomidi = cm->iobase + CM_REG_MPU_PCI;
- else {
+ val = 0;
+ if (cm->chip_version > 33 && mpu_port[dev] == 1) {
+ val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1);
+ if (val != 0x00 && val != 0xff) {
+ iomidi = cm->iobase + CM_REG_MPU_PCI;
+ integrated_midi = 1;
+ }
+ }
+ if (!integrated_midi) {
iomidi = mpu_port[dev];
switch (iomidi) {
case 0x320: val = CM_VMPU_320; break;
}
}
- if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
- return err;
+ if (cm->chip_version < 68) {
+ err = snd_cmipci_create_fm(cm, fm_port[dev]);
+ if (err < 0)
+ return err;
+ }
/* reset mixer */
snd_cmipci_mixer_write(cm, 0, 0);
if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
return err;
pcm_index++;
- if (cm->has_dual_dac) {
- if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
- return err;
- pcm_index++;
- }
+ if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
+ return err;
+ pcm_index++;
if (cm->can_ac3_hw || cm->can_ac3_sw) {
pcm_spdif_index = pcm_index;
if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
}
card->private_data = cm;
- sprintf(card->shortname, "C-Media PCI %s", card->driver);
- sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i",
- card->shortname,
- cm->chip_version,
- cm->iobase,
- cm->irq);
-
- //snd_printd("%s is detected\n", card->longname);
-
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;