This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / sound / pci / cs4281.c
index d7e06b3..bf4f118 100644 (file)
@@ -495,7 +495,7 @@ struct snd_cs4281 {
        unsigned int midcr;
        unsigned int uartm;
 
-       struct gameport *gameport;
+       struct snd_cs4281_gameport *gameport;
 
 #ifdef CONFIG_PM
        u32 suspend_regs[SUSPEND_REGISTERS];
@@ -1238,29 +1238,38 @@ static void __devinit snd_cs4281_proc_init(cs4281_t * chip)
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 
+typedef struct snd_cs4281_gameport {
+       struct gameport info;
+       cs4281_t *chip;
+} cs4281_gameport_t;
+
 static void snd_cs4281_gameport_trigger(struct gameport *gameport)
 {
-       cs4281_t *chip = gameport_get_port_data(gameport);
-
-       snd_assert(chip, return);
+       cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport;
+       cs4281_t *chip;
+       snd_assert(gp, return);
+       chip = gp->chip;
        snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
 }
 
 static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
 {
-       cs4281_t *chip = gameport_get_port_data(gameport);
-
-       snd_assert(chip, return 0);
+       cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport;
+       cs4281_t *chip;
+       snd_assert(gp, return 0);
+       chip = gp->chip;
        return snd_cs4281_peekBA0(chip, BA0_JSPT);
 }
 
 #ifdef COOKED_MODE
 static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-       cs4281_t *chip = gameport_get_port_data(gameport);
+       cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport;
+       cs4281_t *chip;
        unsigned js1, js2, jst;
        
-       snd_assert(chip, return 0);
+       snd_assert(gp, return 0);
+       chip = gp->chip;
 
        js1 = snd_cs4281_peekBA0(chip, BA0_JSC1);
        js2 = snd_cs4281_peekBA0(chip, BA0_JSC2);
@@ -1273,12 +1282,10 @@ static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes,
        axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
        axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
 
-       for (jst = 0; jst < 4; ++jst)
-               if (axes[jst] == 0xFFFF) axes[jst] = -1;
+       for(jst=0;jst<4;++jst)
+               if(axes[jst]==0xFFFF) axes[jst] = -1;
        return 0;
 }
-#else
-#define snd_cs4281_gameport_cooked_read        NULL
 #endif
 
 static int snd_cs4281_gameport_open(struct gameport *gameport, int mode)
@@ -1296,43 +1303,31 @@ static int snd_cs4281_gameport_open(struct gameport *gameport, int mode)
        return 0;
 }
 
-static int __devinit snd_cs4281_create_gameport(cs4281_t *chip)
+static void __devinit snd_cs4281_gameport(cs4281_t *chip)
 {
-       struct gameport *gp;
-
-       chip->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "cs4281: cannot allocate memory for gameport\n");
-               return -ENOMEM;
+       cs4281_gameport_t *gp;
+       gp = kmalloc(sizeof(*gp), GFP_KERNEL);
+       if (! gp) {
+               snd_printk(KERN_ERR "cannot allocate gameport area\n");
+               return;
        }
-
-       gameport_set_name(gp, "CS4281 Gameport");
-       gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-       gameport_set_dev_parent(gp, &chip->pci->dev);
-       gp->open = snd_cs4281_gameport_open;
-       gp->read = snd_cs4281_gameport_read;
-       gp->trigger = snd_cs4281_gameport_trigger;
-       gp->cooked_read = snd_cs4281_gameport_cooked_read;
-       gameport_set_port_data(gp, chip);
+       memset(gp, 0, sizeof(*gp));
+       gp->info.open = snd_cs4281_gameport_open;
+       gp->info.read = snd_cs4281_gameport_read;
+       gp->info.trigger = snd_cs4281_gameport_trigger;
+#ifdef COOKED_MODE
+       gp->info.cooked_read = snd_cs4281_gameport_cooked_read;
+#endif
+       gp->chip = chip;
+       chip->gameport = gp;
 
        snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
        snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
-
-       gameport_register_port(gp);
-
-       return 0;
+       gameport_register_port(&gp->info);
 }
 
-static void snd_cs4281_free_gameport(cs4281_t *chip)
-{
-       if (chip->gameport) {
-               gameport_unregister_port(chip->gameport);
-               chip->gameport = NULL;
-       }
-}
 #else
-static inline int snd_cs4281_create_gameport(cs4281_t *chip) { return -ENOSYS; }
-static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
+#define snd_cs4281_gameport(chip) /*NOP*/
 #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
 
 
@@ -1342,8 +1337,12 @@ static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
 
 static int snd_cs4281_free(cs4281_t *chip)
 {
-       snd_cs4281_free_gameport(chip);
-
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+       if (chip->gameport) {
+               gameport_unregister_port(&chip->gameport->info);
+               kfree(chip->gameport);
+       }
+#endif
        if (chip->irq >= 0)
                synchronize_irq(chip->irq);
 
@@ -1377,8 +1376,8 @@ static int snd_cs4281_dev_free(snd_device_t *device)
 
 static int snd_cs4281_chip_init(cs4281_t *chip); /* defined below */
 #ifdef CONFIG_PM
-static int cs4281_suspend(snd_card_t *card, pm_message_t state);
-static int cs4281_resume(snd_card_t *card);
+static int cs4281_suspend(snd_card_t *card, unsigned int state);
+static int cs4281_resume(snd_card_t *card, unsigned int state);
 #endif
 
 static int __devinit snd_cs4281_create(snd_card_t * card,
@@ -1894,7 +1893,9 @@ static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *r
                        c = snd_cs4281_peekBA0(chip, BA0_MIDRP);
                        if ((chip->midcr & BA0_MIDCR_RIE) == 0)
                                continue;
+                       spin_unlock(&chip->reg_lock);
                        snd_rawmidi_receive(chip->midi_input, &c, 1);
+                       spin_lock(&chip->reg_lock);
                }
                while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_TBF) == 0) {
                        if ((chip->midcr & BA0_MIDCR_TIE) == 0)
@@ -1989,7 +1990,7 @@ static int __devinit snd_cs4281_probe(struct pci_dev *pci,
                snd_card_free(card);
                return err;
        }
-       snd_cs4281_create_gameport(chip);
+       snd_cs4281_gameport(chip);
        strcpy(card->driver, "CS4281");
        strcpy(card->shortname, "Cirrus Logic CS4281");
        sprintf(card->longname, "%s at 0x%lx, irq %d",
@@ -2036,7 +2037,7 @@ static int saved_regs[SUSPEND_REGISTERS] = {
 
 #define CLKCR1_CKRA                             0x00010000L
 
-static int cs4281_suspend(snd_card_t *card, pm_message_t state)
+static int cs4281_suspend(snd_card_t *card, unsigned int state)
 {
        cs4281_t *chip = card->pm_private_data;
        u32 ulCLK;
@@ -2078,10 +2079,11 @@ static int cs4281_suspend(snd_card_t *card, pm_message_t state)
        snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
        pci_disable_device(chip->pci);
+       snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        return 0;
 }
 
-static int cs4281_resume(snd_card_t *card)
+static int cs4281_resume(snd_card_t *card, unsigned int state)
 {
        cs4281_t *chip = card->pm_private_data;
        unsigned int i;
@@ -2110,6 +2112,7 @@ static int cs4281_resume(snd_card_t *card)
        ulCLK &= ~CLKCR1_CKRA;
        snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
+       snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }
 #endif /* CONFIG_PM */