static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
static int dual_codec[SNDRV_CARDS]; /* dual codec */
-static int boot_devs;
-module_param_array(index, int, boot_devs, 0444);
+module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for CS4281 soundcard.");
-module_param_array(id, charp, boot_devs, 0444);
+module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for CS4281 soundcard.");
-module_param_array(enable, bool, boot_devs, 0444);
+module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable CS4281 soundcard.");
-module_param_array(dual_codec, bool, boot_devs, 0444);
+module_param_array(dual_codec, bool, NULL, 0444);
MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled).");
/*
struct snd_cs4281 {
int irq;
- unsigned long ba0; /* virtual (accessible) address */
- unsigned long ba1; /* virtual (accessible) address */
+ void __iomem *ba0; /* virtual (accessible) address */
+ void __iomem *ba1; /* virtual (accessible) address */
unsigned long ba0_addr;
unsigned long ba1_addr;
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
if (chip->ba0)
- iounmap((void *) chip->ba0);
+ iounmap(chip->ba0);
if (chip->ba1)
- iounmap((void *) chip->ba1);
+ iounmap(chip->ba1);
pci_release_regions(chip->pci);
+ pci_disable_device(chip->pci);
kfree(chip);
return 0;
if ((err = pci_enable_device(pci)) < 0)
return err;
chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
+ if (chip == NULL) {
+ pci_disable_device(pci);
return -ENOMEM;
+ }
spin_lock_init(&chip->reg_lock);
chip->card = card;
chip->pci = pci;
if ((err = pci_request_regions(pci, "CS4281")) < 0) {
kfree(chip);
+ pci_disable_device(pci);
return err;
}
chip->ba0_addr = pci_resource_start(pci, 0);
}
chip->irq = pci->irq;
- chip->ba0 = (unsigned long) ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
- chip->ba1 = (unsigned long) ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
+ chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
+ chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
if (!chip->ba0 || !chip->ba1) {
snd_cs4281_free(chip);
return -ENOMEM;
return tmp;
}
- snd_cs4281_proc_init(chip);
-
- snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
-
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_cs4281_free(chip);
return err;
}
+ snd_cs4281_proc_init(chip);
+
+ snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
+
snd_card_set_dev(card, &pci->dev);
*rchip = chip;
}
+/*
+ * OPL3 command
+ */
+static void snd_cs4281_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+{
+ unsigned long flags;
+ cs4281_t *chip = opl3->private_data;
+ void __iomem *port;
+
+ if (cmd & OPL3_RIGHT)
+ port = chip->ba0 + BA0_B1AP; /* right port */
+ else
+ port = chip->ba0 + BA0_B0AP; /* left port */
+
+ spin_lock_irqsave(&opl3->reg_lock, flags);
+
+ writel((unsigned int)cmd, port);
+ udelay(10);
+
+ writel((unsigned int)val, port + 4);
+ udelay(30);
+
+ spin_unlock_irqrestore(&opl3->reg_lock, flags);
+}
+
static int __devinit snd_cs4281_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
snd_card_free(card);
return err;
}
- if ((err = snd_opl3_create(card,
- (chip->ba0 + BA0_B0AP) >> 2,
- (chip->ba0 + BA0_B1AP) >> 2,
- OPL3_HW_OPL3_CS4281, 1, &opl3)) < 0) {
+ if ((err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3)) < 0) {
snd_card_free(card);
return err;
}
+ opl3->private_data = chip;
+ opl3->command = snd_cs4281_opl3_command;
+ snd_opl3_init(opl3);
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
snd_card_free(card);
return err;
ulCLK &= ~CLKCR1_CKRA;
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ pci_disable_device(chip->pci);
return 0;
}
u32 ulCLK;
pci_enable_device(chip->pci);
+ pci_set_master(chip->pci);
ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
ulCLK |= CLKCR1_CKRA;
ulCLK &= ~CLKCR1_CKRA;
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif /* CONFIG_PM */