xref: /openbmc/linux/sound/pci/trident/trident.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  Driver for Trident 4DWave DX/NX & SiS SI7018 Audio PCI soundcard
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *  Driver was originated by Trident <audio@tridentmicro.com>
61da177e4SLinus Torvalds  *  			     Fri Feb 19 15:55:28 MST 1999
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #include <linux/init.h>
101da177e4SLinus Torvalds #include <linux/pci.h>
111da177e4SLinus Torvalds #include <linux/time.h>
1265a77217SPaul Gortmaker #include <linux/module.h>
131da177e4SLinus Torvalds #include <sound/core.h>
1481fcb170STakashi Iwai #include "trident.h"
151da177e4SLinus Torvalds #include <sound/initval.h>
161da177e4SLinus Torvalds 
17c1017a4cSJaroslav Kysela MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
181da177e4SLinus Torvalds MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
191da177e4SLinus Torvalds MODULE_LICENSE("GPL");
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
221da177e4SLinus Torvalds static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
23a67ff6a5SRusty Russell static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
241da177e4SLinus Torvalds static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
251da177e4SLinus Torvalds static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds module_param_array(index, int, NULL, 0444);
281da177e4SLinus Torvalds MODULE_PARM_DESC(index, "Index value for Trident 4DWave PCI soundcard.");
291da177e4SLinus Torvalds module_param_array(id, charp, NULL, 0444);
301da177e4SLinus Torvalds MODULE_PARM_DESC(id, "ID string for Trident 4DWave PCI soundcard.");
311da177e4SLinus Torvalds module_param_array(enable, bool, NULL, 0444);
321da177e4SLinus Torvalds MODULE_PARM_DESC(enable, "Enable Trident 4DWave PCI soundcard.");
331da177e4SLinus Torvalds module_param_array(pcm_channels, int, NULL, 0444);
341da177e4SLinus Torvalds MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
351da177e4SLinus Torvalds module_param_array(wavetable_size, int, NULL, 0444);
361da177e4SLinus Torvalds MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
371da177e4SLinus Torvalds 
389baa3c34SBenoit Taine static const struct pci_device_id snd_trident_ids[] = {
39e3183ec9SJon Mason 	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
40e3183ec9SJon Mason 		PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
41e3183ec9SJon Mason 	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
42e3183ec9SJon Mason 		0, 0, 0},
43e3183ec9SJon Mason 	{PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0},
441da177e4SLinus Torvalds 	{ 0, }
451da177e4SLinus Torvalds };
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds MODULE_DEVICE_TABLE(pci, snd_trident_ids);
481da177e4SLinus Torvalds 
snd_trident_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)49e23e7a14SBill Pemberton static int snd_trident_probe(struct pci_dev *pci,
501da177e4SLinus Torvalds 			     const struct pci_device_id *pci_id)
511da177e4SLinus Torvalds {
521da177e4SLinus Torvalds 	static int dev;
53bee1a5beSTakashi Iwai 	struct snd_card *card;
54bee1a5beSTakashi Iwai 	struct snd_trident *trident;
551da177e4SLinus Torvalds 	const char *str;
561da177e4SLinus Torvalds 	int err, pcm_dev = 0;
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds 	if (dev >= SNDRV_CARDS)
591da177e4SLinus Torvalds 		return -ENODEV;
601da177e4SLinus Torvalds 	if (!enable[dev]) {
611da177e4SLinus Torvalds 		dev++;
621da177e4SLinus Torvalds 		return -ENOENT;
631da177e4SLinus Torvalds 	}
641da177e4SLinus Torvalds 
65*5adfd8c2STakashi Iwai 	err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
66*5adfd8c2STakashi Iwai 				sizeof(*trident), &card);
67e58de7baSTakashi Iwai 	if (err < 0)
68e58de7baSTakashi Iwai 		return err;
69*5adfd8c2STakashi Iwai 	trident = card->private_data;
701da177e4SLinus Torvalds 
7134b946eeSTakashi Iwai 	err = snd_trident_create(card, pci,
721da177e4SLinus Torvalds 				 pcm_channels[dev],
731da177e4SLinus Torvalds 				 ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
74*5adfd8c2STakashi Iwai 				 wavetable_size[dev]);
75*5adfd8c2STakashi Iwai 	if (err < 0)
761da177e4SLinus Torvalds 		return err;
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 	switch (trident->device) {
791da177e4SLinus Torvalds 	case TRIDENT_DEVICE_ID_DX:
801da177e4SLinus Torvalds 		str = "TRID4DWAVEDX";
811da177e4SLinus Torvalds 		break;
821da177e4SLinus Torvalds 	case TRIDENT_DEVICE_ID_NX:
831da177e4SLinus Torvalds 		str = "TRID4DWAVENX";
841da177e4SLinus Torvalds 		break;
851da177e4SLinus Torvalds 	case TRIDENT_DEVICE_ID_SI7018:
861da177e4SLinus Torvalds 		str = "SI7018";
871da177e4SLinus Torvalds 		break;
881da177e4SLinus Torvalds 	default:
891da177e4SLinus Torvalds 		str = "Unknown";
901da177e4SLinus Torvalds 	}
911da177e4SLinus Torvalds 	strcpy(card->driver, str);
921da177e4SLinus Torvalds 	if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
931da177e4SLinus Torvalds 		strcpy(card->shortname, "SiS ");
941da177e4SLinus Torvalds 	} else {
951da177e4SLinus Torvalds 		strcpy(card->shortname, "Trident ");
961da177e4SLinus Torvalds 	}
97d6b340d7STakashi Iwai 	strcat(card->shortname, str);
981da177e4SLinus Torvalds 	sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
991da177e4SLinus Torvalds 		card->shortname, trident->port, trident->irq);
1001da177e4SLinus Torvalds 
10134b946eeSTakashi Iwai 	err = snd_trident_pcm(trident, pcm_dev++);
102*5adfd8c2STakashi Iwai 	if (err < 0)
1031da177e4SLinus Torvalds 		return err;
1041da177e4SLinus Torvalds 	switch (trident->device) {
1051da177e4SLinus Torvalds 	case TRIDENT_DEVICE_ID_DX:
1061da177e4SLinus Torvalds 	case TRIDENT_DEVICE_ID_NX:
10734b946eeSTakashi Iwai 		err = snd_trident_foldback_pcm(trident, pcm_dev++);
108*5adfd8c2STakashi Iwai 		if (err < 0)
1091da177e4SLinus Torvalds 			return err;
1101da177e4SLinus Torvalds 		break;
1111da177e4SLinus Torvalds 	}
1121da177e4SLinus Torvalds 	if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
11334b946eeSTakashi Iwai 		err = snd_trident_spdif_pcm(trident, pcm_dev++);
114*5adfd8c2STakashi Iwai 		if (err < 0)
1151da177e4SLinus Torvalds 			return err;
1161da177e4SLinus Torvalds 	}
11734b946eeSTakashi Iwai 	if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
11834b946eeSTakashi Iwai 		err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
119302e4c2fSTakashi Iwai 					  trident->midi_port,
120dba8b469SClemens Ladisch 					  MPU401_INFO_INTEGRATED |
121dba8b469SClemens Ladisch 					  MPU401_INFO_IRQ_HOOK,
12234b946eeSTakashi Iwai 					  -1, &trident->rmidi);
123*5adfd8c2STakashi Iwai 		if (err < 0)
1241da177e4SLinus Torvalds 			return err;
1251da177e4SLinus Torvalds 	}
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	snd_trident_create_gameport(trident);
1281da177e4SLinus Torvalds 
12934b946eeSTakashi Iwai 	err = snd_card_register(card);
130*5adfd8c2STakashi Iwai 	if (err < 0)
1311da177e4SLinus Torvalds 		return err;
1321da177e4SLinus Torvalds 	pci_set_drvdata(pci, card);
1331da177e4SLinus Torvalds 	dev++;
1341da177e4SLinus Torvalds 	return 0;
1351da177e4SLinus Torvalds }
1361da177e4SLinus Torvalds 
137e9f66d9bSTakashi Iwai static struct pci_driver trident_driver = {
1383733e424STakashi Iwai 	.name = KBUILD_MODNAME,
1391da177e4SLinus Torvalds 	.id_table = snd_trident_ids,
1401da177e4SLinus Torvalds 	.probe = snd_trident_probe,
141c7561cd8STakashi Iwai #ifdef CONFIG_PM_SLEEP
14268cb2b55STakashi Iwai 	.driver = {
14368cb2b55STakashi Iwai 		.pm = &snd_trident_pm,
14468cb2b55STakashi Iwai 	},
145fb0700b4STakashi Iwai #endif
1461da177e4SLinus Torvalds };
1471da177e4SLinus Torvalds 
148e9f66d9bSTakashi Iwai module_pci_driver(trident_driver);
149