diff options
Diffstat (limited to 'sound/pci/riptide/riptide.c')
| -rw-r--r-- | sound/pci/riptide/riptide.c | 347 | 
1 files changed, 160 insertions, 187 deletions
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index e51a5ef1954..235a71e5ac8 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -507,41 +507,19 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);   */  static struct pci_device_id snd_riptide_ids[] = { -	{ -	 .vendor = 0x127a,.device = 0x4310, -	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, -	 }, -	{ -	 .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, -	 }, +	{ PCI_DEVICE(0x127a, 0x4310) }, +	{ PCI_DEVICE(0x127a, 0x4320) }, +	{ PCI_DEVICE(0x127a, 0x4330) }, +	{ PCI_DEVICE(0x127a, 0x4340) },  	{0,},  };  #ifdef SUPPORT_JOYSTICK  static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { -	{ -	 .vendor = 0x127a,.device = 0x4312, -	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID, -	 }, -	{ -	 .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, -	 }, +	{ PCI_DEVICE(0x127a, 0x4312) }, +	{ PCI_DEVICE(0x127a, 0x4322) }, +	{ PCI_DEVICE(0x127a, 0x4332) }, +	{ PCI_DEVICE(0x127a, 0x4342) },  	{0,},  };  #endif @@ -1209,12 +1187,79 @@ static int riptide_resume(struct pci_dev *pci)  }  #endif +static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip) +{ +	union firmware_version firmware = { .ret = CMDRET_ZERO }; +	int i, timeout, err; + +	for (i = 0; i < 2; i++) { +		WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0); +		WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0); +	} +	SET_GRESET(cif->hwport); +	udelay(100); +	UNSET_GRESET(cif->hwport); +	udelay(100); + +	for (timeout = 100000; --timeout; udelay(10)) { +		if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport)) +			break; +	} +	if (!timeout) { +		snd_printk(KERN_ERR +			   "Riptide: device not ready, audio status: 0x%x " +			   "ready: %d gerr: %d\n", +			   READ_AUDIO_STATUS(cif->hwport), +			   IS_READY(cif->hwport), IS_GERR(cif->hwport)); +		return -EIO; +	} else { +		snd_printdd +			("Riptide: audio status: 0x%x ready: %d gerr: %d\n", +			 READ_AUDIO_STATUS(cif->hwport), +			 IS_READY(cif->hwport), IS_GERR(cif->hwport)); +	} + +	SEND_GETV(cif, &firmware.ret); +	snd_printdd("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n", +		    firmware.firmware.ASIC, firmware.firmware.CODEC, +		    firmware.firmware.AUXDSP, firmware.firmware.PROG); + +	for (i = 0; i < FIRMWARE_VERSIONS; i++) { +		if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) +			break; +	} +	if (i >= FIRMWARE_VERSIONS) +		return 0; /* no match */ + +	if (!chip) +		return 1; /* OK */ + +	snd_printdd("Writing Firmware\n"); +	if (!chip->fw_entry) { +		err = request_firmware(&chip->fw_entry, "riptide.hex", +				       &chip->pci->dev); +		if (err) { +			snd_printk(KERN_ERR +				   "Riptide: Firmware not available %d\n", err); +			return -EIO; +		} +	} +	err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size); +	if (err) { +		snd_printk(KERN_ERR +			   "Riptide: Could not load firmware %d\n", err); +		return err; +	} + +	chip->firmware = firmware; + +	return 1; /* OK */ +} +  static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)  { -	int timeout, tries;  	union cmdret rptr = CMDRET_ZERO; -	union firmware_version firmware; -	int i, j, err, has_firmware; +	int err, tries;  	if (!cif)  		return -EINVAL; @@ -1227,75 +1272,11 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)  	cif->is_reset = 0;  	tries = RESET_TRIES; -	has_firmware = 0; -	while (has_firmware == 0 && tries-- > 0) { -		for (i = 0; i < 2; i++) { -			WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0); -			WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0); -		} -		SET_GRESET(cif->hwport); -		udelay(100); -		UNSET_GRESET(cif->hwport); -		udelay(100); - -		for (timeout = 100000; --timeout; udelay(10)) { -			if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport)) -				break; -		} -		if (timeout == 0) { -			snd_printk(KERN_ERR -				   "Riptide: device not ready, audio status: 0x%x ready: %d gerr: %d\n", -				   READ_AUDIO_STATUS(cif->hwport), -				   IS_READY(cif->hwport), IS_GERR(cif->hwport)); -			return -EIO; -		} else { -			snd_printdd -			    ("Riptide: audio status: 0x%x ready: %d gerr: %d\n", -			     READ_AUDIO_STATUS(cif->hwport), -			     IS_READY(cif->hwport), IS_GERR(cif->hwport)); -		} - -		SEND_GETV(cif, &rptr); -		for (i = 0; i < 4; i++) -			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.AUXDSP, firmware.firmware.PROG); - -		for (j = 0; j < FIRMWARE_VERSIONS; j++) { -			has_firmware = 1; -			for (i = 0; i < 4; i++) { -				if (firmware_versions[j].ret.retwords[i] != -				    firmware.ret.retwords[i]) -					has_firmware = 0; -			} -			if (has_firmware) -				break; -		} - -		if (chip != NULL && has_firmware == 0) { -			snd_printdd("Writing Firmware\n"); -			if (!chip->fw_entry) { -				if ((err = -				     request_firmware(&chip->fw_entry, -						      "riptide.hex", -						      &chip->pci->dev)) != 0) { -					snd_printk(KERN_ERR -						   "Riptide: Firmware not available %d\n", -						   err); -					return -EIO; -				} -			} -			err = loadfirmware(cif, chip->fw_entry->data, -					   chip->fw_entry->size); -			if (err) -				snd_printk(KERN_ERR -					   "Riptide: Could not load firmware %d\n", -					   err); -		} -	} +	do { +		err = try_to_load_firmware(cif, chip); +		if (err < 0) +			return err; +	} while (!err && --tries);  	SEND_SACR(cif, 0, AC97_RESET);  	SEND_RACR(cif, AC97_RESET, &rptr); @@ -1337,11 +1318,6 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)  	SET_AIE(cif->hwport);  	SET_AIACK(cif->hwport);  	cif->is_reset = 1; -	if (chip) { -		for (i = 0; i < 4; i++) -			chip->firmware.ret.retwords[i] = -			    firmware.ret.retwords[i]; -	}  	return 0;  } @@ -2038,14 +2014,12 @@ static int __devinit snd_riptide_mixer(struct snd_riptide *chip)  }  #ifdef SUPPORT_JOYSTICK -static int have_joystick; -static struct pci_dev *riptide_gameport_pci; -static struct gameport *riptide_gameport;  static int __devinit  snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)  {  	static int dev; +	struct gameport *gameport;  	if (dev >= SNDRV_CARDS)  		return -ENODEV; @@ -2054,36 +2028,33 @@ snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)  		return -ENOENT;  	} -	if (joystick_port[dev]) { -		riptide_gameport = gameport_allocate_port(); -		if (riptide_gameport) { -			if (!request_region -			    (joystick_port[dev], 8, "Riptide gameport")) { -				snd_printk(KERN_WARNING -					   "Riptide: cannot grab gameport 0x%x\n", -					   joystick_port[dev]); -				gameport_free_port(riptide_gameport); -				riptide_gameport = NULL; -			} else { -				riptide_gameport_pci = pci; -				riptide_gameport->io = joystick_port[dev]; -				gameport_register_port(riptide_gameport); -			} -		} +	if (!joystick_port[dev++]) +		return 0; + +	gameport = gameport_allocate_port(); +	if (!gameport) +		return -ENOMEM; +	if (!request_region(joystick_port[dev], 8, "Riptide gameport")) { +		snd_printk(KERN_WARNING +			   "Riptide: cannot grab gameport 0x%x\n", +			   joystick_port[dev]); +		gameport_free_port(gameport); +		return -EBUSY;  	} -	dev++; + +	gameport->io = joystick_port[dev]; +	gameport_register_port(gameport); +	pci_set_drvdata(pci, gameport);  	return 0;  }  static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)  { -	if (riptide_gameport) { -		if (riptide_gameport_pci == pci) { -			release_region(riptide_gameport->io, 8); -			riptide_gameport_pci = NULL; -			gameport_unregister_port(riptide_gameport); -			riptide_gameport = NULL; -		} +	struct gameport *gameport = pci_get_drvdata(pci); +	if (gameport) { +		release_region(gameport->io, 8); +		gameport_unregister_port(gameport); +		pci_set_drvdata(pci, NULL);  	}  }  #endif @@ -2094,8 +2065,8 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)  	static int dev;  	struct snd_card *card;  	struct snd_riptide *chip; -	unsigned short addr; -	int err = 0; +	unsigned short val; +	int err;  	if (dev >= SNDRV_CARDS)  		return -ENODEV; @@ -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);  	if (err < 0)  		return err; -	if ((err = snd_riptide_create(card, pci, &chip)) < 0) { -		snd_card_free(card); -		return err; -	} +	err = snd_riptide_create(card, pci, &chip); +	if (err < 0) +		goto error;  	card->private_data = chip; -	if ((err = snd_riptide_pcm(chip, 0, NULL)) < 0) { -		snd_card_free(card); -		return err; -	} -	if ((err = snd_riptide_mixer(chip)) < 0) { -		snd_card_free(card); -		return err; -	} -	pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, LEGACY_ENABLE_ALL -			      | (opl3_port[dev] ? LEGACY_ENABLE_FM : 0) +	err = snd_riptide_pcm(chip, 0, NULL); +	if (err < 0) +		goto error; +	err = snd_riptide_mixer(chip); +	if (err < 0) +		goto error; + +	val = LEGACY_ENABLE_ALL; +	if (opl3_port[dev]) +		val |= LEGACY_ENABLE_FM;  #ifdef SUPPORT_JOYSTICK -			      | (joystick_port[dev] ? LEGACY_ENABLE_GAMEPORT : -				 0) +	if (joystick_port[dev]) +		val |= LEGACY_ENABLE_GAMEPORT;  #endif -			      | (mpu_port[dev] -				 ? (LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU) : -				 0) -			      | ((chip->irq << 4) & 0xF0)); -	if ((addr = mpu_port[dev]) != 0) { -		pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, addr); -		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, -					       addr, 0, chip->irq, 0, -					       &chip->rmidi)) < 0) +	if (mpu_port[dev]) +		val |= LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU; +	val |= (chip->irq << 4) & 0xf0; +	pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, val); +	if (mpu_port[dev]) { +		val = mpu_port[dev]; +		pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val); +		err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, +					  val, 0, chip->irq, 0, +					  &chip->rmidi); +		if (err < 0)  			snd_printk(KERN_WARNING  				   "Riptide: Can't Allocate MPU at 0x%x\n", -				   addr); +				   val);  		else -			chip->mpuaddr = addr; +			chip->mpuaddr = val;  	} -	if ((addr = opl3_port[dev]) != 0) { -		pci_write_config_word(chip->pci, PCI_EXT_FM_Base, addr); -		if ((err = snd_opl3_create(card, addr, addr + 2, -					   OPL3_HW_RIPTIDE, 0, -					   &chip->opl3)) < 0) +	if (opl3_port[dev]) { +		val = opl3_port[dev]; +		pci_write_config_word(chip->pci, PCI_EXT_FM_Base, val); +		err = snd_opl3_create(card, val, val + 2, +				      OPL3_HW_RIPTIDE, 0, &chip->opl3); +		if (err < 0)  			snd_printk(KERN_WARNING  				   "Riptide: Can't Allocate OPL3 at 0x%x\n", -				   addr); +				   val);  		else { -			chip->opladdr = addr; -			if ((err = -			     snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL)) < 0) +			chip->opladdr = val; +			err = snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL); +			if (err < 0)  				snd_printk(KERN_WARNING  					   "Riptide: Can't Allocate OPL3-HWDEP\n");  		}  	}  #ifdef SUPPORT_JOYSTICK -	if ((addr = joystick_port[dev]) != 0) { -		pci_write_config_word(chip->pci, PCI_EXT_Game_Base, addr); -		chip->gameaddr = addr; +	if (joystick_port[dev]) { +		val = joystick_port[dev]; +		pci_write_config_word(chip->pci, PCI_EXT_Game_Base, val); +		chip->gameaddr = val;  	}  #endif @@ -2178,13 +2152,16 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)  		 chip->opladdr);  #endif  	snd_riptide_proc_init(chip); -	if ((err = snd_card_register(card)) < 0) { -		snd_card_free(card); -		return err; -	} +	err = snd_card_register(card); +	if (err < 0) +		goto error;  	pci_set_drvdata(pci, card);  	dev++;  	return 0; + + error: +	snd_card_free(card); +	return err;  }  static void __devexit snd_card_riptide_remove(struct pci_dev *pci) @@ -2216,14 +2193,11 @@ static struct pci_driver joystick_driver = {  static int __init alsa_card_riptide_init(void)  {  	int err; -	if ((err = pci_register_driver(&driver)) < 0) +	err = pci_register_driver(&driver); +	if (err < 0)  		return err;  #if defined(SUPPORT_JOYSTICK) -	if (pci_register_driver(&joystick_driver) < 0) { -		have_joystick = 0; -		snd_printk(KERN_INFO "no joystick found\n"); -	} else -		have_joystick = 1; +	pci_register_driver(&joystick_driver);  #endif  	return 0;  } @@ -2232,8 +2206,7 @@ static void __exit alsa_card_riptide_exit(void)  {  	pci_unregister_driver(&driver);  #if defined(SUPPORT_JOYSTICK) -	if (have_joystick) -		pci_unregister_driver(&joystick_driver); +	pci_unregister_driver(&joystick_driver);  #endif  }  |