Commit 87cb14a5 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/riptide' into for-linus

* topic/riptide:
  ALSA: riptide - Fix joystick resource handling
  ALSA: riptide - Code clean up
parents 4ad75433 db1005ec
...@@ -507,41 +507,19 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip); ...@@ -507,41 +507,19 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
*/ */
static struct pci_device_id snd_riptide_ids[] = { static struct pci_device_id snd_riptide_ids[] = {
{ { PCI_DEVICE(0x127a, 0x4310) },
.vendor = 0x127a,.device = 0x4310, { PCI_DEVICE(0x127a, 0x4320) },
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, { PCI_DEVICE(0x127a, 0x4330) },
}, { PCI_DEVICE(0x127a, 0x4340) },
{
.vendor = 0x127a,.device = 0x4320,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{
.vendor = 0x127a,.device = 0x4330,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{
.vendor = 0x127a,.device = 0x4340,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{0,}, {0,},
}; };
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = {
{ { PCI_DEVICE(0x127a, 0x4312) },
.vendor = 0x127a,.device = 0x4312, { PCI_DEVICE(0x127a, 0x4322) },
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, { PCI_DEVICE(0x127a, 0x4332) },
}, { PCI_DEVICE(0x127a, 0x4342) },
{
.vendor = 0x127a,.device = 0x4322,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{.vendor = 0x127a,.device = 0x4332,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{.vendor = 0x127a,.device = 0x4342,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
},
{0,}, {0,},
}; };
#endif #endif
...@@ -1209,26 +1187,11 @@ static int riptide_resume(struct pci_dev *pci) ...@@ -1209,26 +1187,11 @@ static int riptide_resume(struct pci_dev *pci)
} }
#endif #endif
static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
{ {
int timeout, tries; union firmware_version firmware = { .ret = CMDRET_ZERO };
union cmdret rptr = CMDRET_ZERO; int i, timeout, err;
union firmware_version firmware;
int i, j, err, has_firmware;
if (!cif)
return -EINVAL;
cif->cmdcnt = 0;
cif->cmdtime = 0;
cif->cmdtimemax = 0;
cif->cmdtimemin = 0xffffffff;
cif->errcnt = 0;
cif->is_reset = 0;
tries = RESET_TRIES;
has_firmware = 0;
while (has_firmware == 0 && tries-- > 0) {
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0); WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0);
WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0); WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0);
...@@ -1242,9 +1205,10 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) ...@@ -1242,9 +1205,10 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport)) if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport))
break; break;
} }
if (timeout == 0) { if (!timeout) {
snd_printk(KERN_ERR snd_printk(KERN_ERR
"Riptide: device not ready, audio status: 0x%x ready: %d gerr: %d\n", "Riptide: device not ready, audio status: 0x%x "
"ready: %d gerr: %d\n",
READ_AUDIO_STATUS(cif->hwport), READ_AUDIO_STATUS(cif->hwport),
IS_READY(cif->hwport), IS_GERR(cif->hwport)); IS_READY(cif->hwport), IS_GERR(cif->hwport));
return -EIO; return -EIO;
...@@ -1255,48 +1219,65 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) ...@@ -1255,48 +1219,65 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
IS_READY(cif->hwport), IS_GERR(cif->hwport)); IS_READY(cif->hwport), IS_GERR(cif->hwport));
} }
SEND_GETV(cif, &rptr); SEND_GETV(cif, &firmware.ret);
for (i = 0; i < 4; i++) snd_printdd("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n",
firmware.ret.retwords[i] = rptr.retwords[i];
snd_printdd
("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n",
firmware.firmware.ASIC, firmware.firmware.CODEC, firmware.firmware.ASIC, firmware.firmware.CODEC,
firmware.firmware.AUXDSP, firmware.firmware.PROG); firmware.firmware.AUXDSP, firmware.firmware.PROG);
for (j = 0; j < FIRMWARE_VERSIONS; j++) { for (i = 0; i < FIRMWARE_VERSIONS; i++) {
has_firmware = 1; if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
for (i = 0; i < 4; i++) {
if (firmware_versions[j].ret.retwords[i] !=
firmware.ret.retwords[i])
has_firmware = 0;
}
if (has_firmware)
break; break;
} }
if (i >= FIRMWARE_VERSIONS)
return 0; /* no match */
if (!chip)
return 1; /* OK */
if (chip != NULL && has_firmware == 0) {
snd_printdd("Writing Firmware\n"); snd_printdd("Writing Firmware\n");
if (!chip->fw_entry) { if (!chip->fw_entry) {
if ((err = err = request_firmware(&chip->fw_entry, "riptide.hex",
request_firmware(&chip->fw_entry, &chip->pci->dev);
"riptide.hex", if (err) {
&chip->pci->dev)) != 0) {
snd_printk(KERN_ERR snd_printk(KERN_ERR
"Riptide: Firmware not available %d\n", "Riptide: Firmware not available %d\n", err);
err);
return -EIO; return -EIO;
} }
} }
err = loadfirmware(cif, chip->fw_entry->data, err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size);
chip->fw_entry->size); if (err) {
if (err)
snd_printk(KERN_ERR snd_printk(KERN_ERR
"Riptide: Could not load firmware %d\n", "Riptide: Could not load firmware %d\n", err);
err); return err;
}
} }
chip->firmware = firmware;
return 1; /* OK */
}
static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
{
union cmdret rptr = CMDRET_ZERO;
int err, tries;
if (!cif)
return -EINVAL;
cif->cmdcnt = 0;
cif->cmdtime = 0;
cif->cmdtimemax = 0;
cif->cmdtimemin = 0xffffffff;
cif->errcnt = 0;
cif->is_reset = 0;
tries = RESET_TRIES;
do {
err = try_to_load_firmware(cif, chip);
if (err < 0)
return err;
} while (!err && --tries);
SEND_SACR(cif, 0, AC97_RESET); SEND_SACR(cif, 0, AC97_RESET);
SEND_RACR(cif, AC97_RESET, &rptr); SEND_RACR(cif, AC97_RESET, &rptr);
snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]); snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]);
...@@ -1337,11 +1318,6 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) ...@@ -1337,11 +1318,6 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
SET_AIE(cif->hwport); SET_AIE(cif->hwport);
SET_AIACK(cif->hwport); SET_AIACK(cif->hwport);
cif->is_reset = 1; cif->is_reset = 1;
if (chip) {
for (i = 0; i < 4; i++)
chip->firmware.ret.retwords[i] =
firmware.ret.retwords[i];
}
return 0; return 0;
} }
...@@ -2038,14 +2014,12 @@ static int __devinit snd_riptide_mixer(struct snd_riptide *chip) ...@@ -2038,14 +2014,12 @@ static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
} }
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
static int have_joystick;
static struct pci_dev *riptide_gameport_pci;
static struct gameport *riptide_gameport;
static int __devinit static int __devinit
snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
{ {
static int dev; static int dev;
struct gameport *gameport;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -2054,36 +2028,33 @@ snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -2054,36 +2028,33 @@ snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
return -ENOENT; return -ENOENT;
} }
if (joystick_port[dev]) { if (!joystick_port[dev++])
riptide_gameport = gameport_allocate_port(); return 0;
if (riptide_gameport) {
if (!request_region gameport = gameport_allocate_port();
(joystick_port[dev], 8, "Riptide gameport")) { if (!gameport)
return -ENOMEM;
if (!request_region(joystick_port[dev], 8, "Riptide gameport")) {
snd_printk(KERN_WARNING snd_printk(KERN_WARNING
"Riptide: cannot grab gameport 0x%x\n", "Riptide: cannot grab gameport 0x%x\n",
joystick_port[dev]); joystick_port[dev]);
gameport_free_port(riptide_gameport); gameport_free_port(gameport);
riptide_gameport = NULL; return -EBUSY;
} else {
riptide_gameport_pci = pci;
riptide_gameport->io = joystick_port[dev];
gameport_register_port(riptide_gameport);
}
}
} }
dev++;
gameport->io = joystick_port[dev];
gameport_register_port(gameport);
pci_set_drvdata(pci, gameport);
return 0; return 0;
} }
static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci) static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)
{ {
if (riptide_gameport) { struct gameport *gameport = pci_get_drvdata(pci);
if (riptide_gameport_pci == pci) { if (gameport) {
release_region(riptide_gameport->io, 8); release_region(gameport->io, 8);
riptide_gameport_pci = NULL; gameport_unregister_port(gameport);
gameport_unregister_port(riptide_gameport); pci_set_drvdata(pci, NULL);
riptide_gameport = NULL;
}
} }
} }
#endif #endif
...@@ -2094,8 +2065,8 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) ...@@ -2094,8 +2065,8 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
static int dev; static int dev;
struct snd_card *card; struct snd_card *card;
struct snd_riptide *chip; struct snd_riptide *chip;
unsigned short addr; unsigned short val;
int err = 0; int err;
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
...@@ -2107,60 +2078,63 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) ...@@ -2107,60 +2078,63 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
if (err < 0) if (err < 0)
return err; return err;
if ((err = snd_riptide_create(card, pci, &chip)) < 0) { err = snd_riptide_create(card, pci, &chip);
snd_card_free(card); if (err < 0)
return err; goto error;
}
card->private_data = chip; card->private_data = chip;
if ((err = snd_riptide_pcm(chip, 0, NULL)) < 0) { err = snd_riptide_pcm(chip, 0, NULL);
snd_card_free(card); if (err < 0)
return err; goto error;
} err = snd_riptide_mixer(chip);
if ((err = snd_riptide_mixer(chip)) < 0) { if (err < 0)
snd_card_free(card); goto error;
return err;
} val = LEGACY_ENABLE_ALL;
pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, LEGACY_ENABLE_ALL if (opl3_port[dev])
| (opl3_port[dev] ? LEGACY_ENABLE_FM : 0) val |= LEGACY_ENABLE_FM;
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
| (joystick_port[dev] ? LEGACY_ENABLE_GAMEPORT : if (joystick_port[dev])
0) val |= LEGACY_ENABLE_GAMEPORT;
#endif #endif
| (mpu_port[dev] if (mpu_port[dev])
? (LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU) : val |= LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU;
0) val |= (chip->irq << 4) & 0xf0;
| ((chip->irq << 4) & 0xF0)); pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, val);
if ((addr = mpu_port[dev]) != 0) { if (mpu_port[dev]) {
pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, addr); val = mpu_port[dev];
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val);
addr, 0, chip->irq, 0, err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,
&chip->rmidi)) < 0) val, 0, chip->irq, 0,
&chip->rmidi);
if (err < 0)
snd_printk(KERN_WARNING snd_printk(KERN_WARNING
"Riptide: Can't Allocate MPU at 0x%x\n", "Riptide: Can't Allocate MPU at 0x%x\n",
addr); val);
else else
chip->mpuaddr = addr; chip->mpuaddr = val;
} }
if ((addr = opl3_port[dev]) != 0) { if (opl3_port[dev]) {
pci_write_config_word(chip->pci, PCI_EXT_FM_Base, addr); val = opl3_port[dev];
if ((err = snd_opl3_create(card, addr, addr + 2, pci_write_config_word(chip->pci, PCI_EXT_FM_Base, val);
OPL3_HW_RIPTIDE, 0, err = snd_opl3_create(card, val, val + 2,
&chip->opl3)) < 0) OPL3_HW_RIPTIDE, 0, &chip->opl3);
if (err < 0)
snd_printk(KERN_WARNING snd_printk(KERN_WARNING
"Riptide: Can't Allocate OPL3 at 0x%x\n", "Riptide: Can't Allocate OPL3 at 0x%x\n",
addr); val);
else { else {
chip->opladdr = addr; chip->opladdr = val;
if ((err = err = snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL);
snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL)) < 0) if (err < 0)
snd_printk(KERN_WARNING snd_printk(KERN_WARNING
"Riptide: Can't Allocate OPL3-HWDEP\n"); "Riptide: Can't Allocate OPL3-HWDEP\n");
} }
} }
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
if ((addr = joystick_port[dev]) != 0) { if (joystick_port[dev]) {
pci_write_config_word(chip->pci, PCI_EXT_Game_Base, addr); val = joystick_port[dev];
chip->gameaddr = addr; pci_write_config_word(chip->pci, PCI_EXT_Game_Base, val);
chip->gameaddr = val;
} }
#endif #endif
...@@ -2178,13 +2152,16 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) ...@@ -2178,13 +2152,16 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
chip->opladdr); chip->opladdr);
#endif #endif
snd_riptide_proc_init(chip); snd_riptide_proc_init(chip);
if ((err = snd_card_register(card)) < 0) { err = snd_card_register(card);
snd_card_free(card); if (err < 0)
return err; goto error;
}
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
dev++; dev++;
return 0; return 0;
error:
snd_card_free(card);
return err;
} }
static void __devexit snd_card_riptide_remove(struct pci_dev *pci) static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
...@@ -2216,14 +2193,11 @@ static struct pci_driver joystick_driver = { ...@@ -2216,14 +2193,11 @@ static struct pci_driver joystick_driver = {
static int __init alsa_card_riptide_init(void) static int __init alsa_card_riptide_init(void)
{ {
int err; int err;
if ((err = pci_register_driver(&driver)) < 0) err = pci_register_driver(&driver);
if (err < 0)
return err; return err;
#if defined(SUPPORT_JOYSTICK) #if defined(SUPPORT_JOYSTICK)
if (pci_register_driver(&joystick_driver) < 0) { pci_register_driver(&joystick_driver);
have_joystick = 0;
snd_printk(KERN_INFO "no joystick found\n");
} else
have_joystick = 1;
#endif #endif
return 0; return 0;
} }
...@@ -2232,7 +2206,6 @@ static void __exit alsa_card_riptide_exit(void) ...@@ -2232,7 +2206,6 @@ static void __exit alsa_card_riptide_exit(void)
{ {
pci_unregister_driver(&driver); pci_unregister_driver(&driver);
#if defined(SUPPORT_JOYSTICK) #if defined(SUPPORT_JOYSTICK)
if (have_joystick)
pci_unregister_driver(&joystick_driver); pci_unregister_driver(&joystick_driver);
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment