X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fcs4281.c;h=bf4f1180c69c247ee5c2ed0c239288adcc712315;hb=f1227cd3e0e73c48b93368800aa89f4341103a00;hp=d7e06b3caf973bae1af659f170dacbca38ccf438;hpb=340e2b1a4c74f653454348914c408420d5d3c28a;p=linux-2.6.git diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index d7e06b3ca..bf4f1180c 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -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 */