Changes in 4.9.144 Kbuild: suppress packed-not-aligned warning for default setting only disable stringop truncation warnings for now test_hexdump: use memcpy instead of strncpy kobject: Replace strncpy with memcpy unifdef: use memcpy instead of strncpy kernfs: Replace strncpy with memcpy ip_tunnel: Fix name string concatenate in __ip_tunnel_create() drm: gma500: fix logic error scsi: bfa: convert to strlcpy/strlcat staging: rts5208: fix gcc-8 logic error warning kdb: use memmove instead of overlapping memcpy x86/power/64: Use char arrays for asm function names iser: set sector for ambiguous mr status errors uprobes: Fix handle_swbp() vs. unregister() + register() race once more MIPS: ralink: Fix mt7620 nd_sd pinmux mips: fix mips_get_syscall_arg o32 check IB/mlx5: Avoid load failure due to unknown link width drm/ast: Fix incorrect free on ioregs drm: set is_master to 0 upon drm_new_set_master() failure scsi: scsi_devinfo: cleanly zero-pad devinfo strings ALSA: trident: Suppress gcc string warning scsi: csiostor: Avoid content leaks and casts kgdboc: Fix restrict error kgdboc: Fix warning with module build binder: fix proc->files use-after-free svm: Add mutex_lock to protect apic_access_page_done on AMD systems drm/mediatek: fix OF sibling-node lookup Input: xpad - quirk all PDP Xbox One gamepads Input: matrix_keypad - check for errors from of_get_named_gpio() Input: elan_i2c - add ELAN0620 to the ACPI table Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15ARR Input: elan_i2c - add support for ELAN0621 touchpad btrfs: Always try all copies when reading extent buffers Btrfs: fix use-after-free when dumping free space ARC: change defconfig defaults to ARCv2 arc: [devboards] Add support of NFSv3 ACL udf: Allow mounting volumes with incorrect identification strings reset: make optional functions really optional reset: core: fix reset_control_put reset: fix optional reset_control_get stubs to return NULL reset: add exported __reset_control_get, return NULL if optional reset: make device_reset_optional() really optional reset: remove remaining WARN_ON() in <linux/reset.h> mm: cleancache: fix corruption on missed inode invalidation usb: gadget: dummy: fix nonsensical comparisons net: qed: use correct strncpy() size tipc: use destination length for copy string libceph: drop len argument of *verify_authorizer_reply() libceph: no need to drop con->mutex for ->get_authorizer() libceph: store ceph_auth_handshake pointer in ceph_connection libceph: factor out __prepare_write_connect() libceph: factor out __ceph_x_decrypt() libceph: factor out encrypt_authorizer() libceph: add authorizer challenge libceph: implement CEPHX_V2 calculation mode libceph: weaken sizeof check in ceph_x_verify_authorizer_reply() libceph: check authorizer reply/challenge length before reading bpf/verifier: Add spi variable to check_stack_write() bpf/verifier: Pass instruction index to check_mem_access() and check_xadd() bpf: Prevent memory disambiguation attack wil6210: missing length check in wmi_set_ie mm/hugetlb.c: don't call region_abort if region_chg fails hugetlbfs: fix offset overflow in hugetlbfs mmap hugetlbfs: check for pgoff value overflow btrfs: validate type when reading a chunk btrfs: Verify that every chunk has corresponding block group at mount time btrfs: Refactor check_leaf function for later expansion btrfs: Check if item pointer overlaps with the item itself btrfs: Add sanity check for EXTENT_DATA when reading out leaf btrfs: Add checker for EXTENT_CSUM btrfs: Move leaf and node validation checker to tree-checker.c btrfs: struct-funcs, constify readers btrfs: tree-checker: Enhance btrfs_check_node output btrfs: tree-checker: Fix false panic for sanity test btrfs: tree-checker: Add checker for dir item btrfs: tree-checker: use %zu format string for size_t btrfs: tree-check: reduce stack consumption in check_dir_item btrfs: tree-checker: Verify block_group_item btrfs: tree-checker: Detect invalid and empty essential trees btrfs: Check that each block group has corresponding chunk at mount time btrfs: tree-checker: Check level for leaves and nodes btrfs: tree-checker: Fix misleading group system information f2fs: fix a panic caused by NULL flush_cmd_control f2fs: fix race condition in between free nid allocator/initializer f2fs: detect wrong layout f2fs: return error during fill_super f2fs: check blkaddr more accuratly before issue a bio f2fs: sanity check on sit entry f2fs: enhance sanity_check_raw_super() to avoid potential overflow f2fs: clean up with is_valid_blkaddr() f2fs: introduce and spread verify_blkaddr f2fs: fix to do sanity check with secs_per_zone f2fs: fix to do sanity check with user_block_count f2fs: Add sanity_check_inode() function f2fs: fix to do sanity check with node footer and iblocks f2fs: fix to do sanity check with block address in main area f2fs: fix missing up_read f2fs: fix to do sanity check with block address in main area v2 f2fs: free meta pages if sanity check for ckpt is failed f2fs: fix to do sanity check with cp_pack_start_sum xfs: don't fail when converting shortform attr to long form during ATTR_REPLACE hugetlbfs: fix bug in pgoff overflow checking Linux 4.9.144 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
188 lines
5.5 KiB
C
188 lines
5.5 KiB
C
/*
|
|
* Driver for Trident 4DWave DX/NX & SiS SI7018 Audio PCI soundcard
|
|
*
|
|
* Driver was originated by Trident <audio@tridentmicro.com>
|
|
* Fri Feb 19 15:55:28 MST 1999
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/time.h>
|
|
#include <linux/module.h>
|
|
#include <sound/core.h>
|
|
#include "trident.h"
|
|
#include <sound/initval.h>
|
|
|
|
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
|
|
MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
|
|
"{Trident,4DWave NX},"
|
|
"{SiS,SI7018 PCI Audio},"
|
|
"{Best Union,Miss Melody 4DWave PCI},"
|
|
"{HIS,4DWave PCI},"
|
|
"{Warpspeed,ONSpeed 4DWave PCI},"
|
|
"{Aztech Systems,PCI 64-Q3D},"
|
|
"{Addonics,SV 750},"
|
|
"{CHIC,True Sound 4Dwave},"
|
|
"{Shark,Predator4D-PCI},"
|
|
"{Jaton,SonicWave 4D},"
|
|
"{Hoontech,SoundTrack Digital 4DWave NX}}");
|
|
|
|
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
|
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
|
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
|
|
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
|
|
static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
|
|
|
|
module_param_array(index, int, NULL, 0444);
|
|
MODULE_PARM_DESC(index, "Index value for Trident 4DWave PCI soundcard.");
|
|
module_param_array(id, charp, NULL, 0444);
|
|
MODULE_PARM_DESC(id, "ID string for Trident 4DWave PCI soundcard.");
|
|
module_param_array(enable, bool, NULL, 0444);
|
|
MODULE_PARM_DESC(enable, "Enable Trident 4DWave PCI soundcard.");
|
|
module_param_array(pcm_channels, int, NULL, 0444);
|
|
MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
|
|
module_param_array(wavetable_size, int, NULL, 0444);
|
|
MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
|
|
|
|
static const struct pci_device_id snd_trident_ids[] = {
|
|
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
|
|
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
|
|
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
|
|
0, 0, 0},
|
|
{PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0},
|
|
{ 0, }
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(pci, snd_trident_ids);
|
|
|
|
static int snd_trident_probe(struct pci_dev *pci,
|
|
const struct pci_device_id *pci_id)
|
|
{
|
|
static int dev;
|
|
struct snd_card *card;
|
|
struct snd_trident *trident;
|
|
const char *str;
|
|
int err, pcm_dev = 0;
|
|
|
|
if (dev >= SNDRV_CARDS)
|
|
return -ENODEV;
|
|
if (!enable[dev]) {
|
|
dev++;
|
|
return -ENOENT;
|
|
}
|
|
|
|
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
|
|
0, &card);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
if ((err = snd_trident_create(card, pci,
|
|
pcm_channels[dev],
|
|
((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
|
|
wavetable_size[dev],
|
|
&trident)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
card->private_data = trident;
|
|
|
|
switch (trident->device) {
|
|
case TRIDENT_DEVICE_ID_DX:
|
|
str = "TRID4DWAVEDX";
|
|
break;
|
|
case TRIDENT_DEVICE_ID_NX:
|
|
str = "TRID4DWAVENX";
|
|
break;
|
|
case TRIDENT_DEVICE_ID_SI7018:
|
|
str = "SI7018";
|
|
break;
|
|
default:
|
|
str = "Unknown";
|
|
}
|
|
strcpy(card->driver, str);
|
|
if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
|
|
strcpy(card->shortname, "SiS ");
|
|
} else {
|
|
strcpy(card->shortname, "Trident ");
|
|
}
|
|
strcat(card->shortname, str);
|
|
sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
|
|
card->shortname, trident->port, trident->irq);
|
|
|
|
if ((err = snd_trident_pcm(trident, pcm_dev++)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
switch (trident->device) {
|
|
case TRIDENT_DEVICE_ID_DX:
|
|
case TRIDENT_DEVICE_ID_NX:
|
|
if ((err = snd_trident_foldback_pcm(trident, pcm_dev++)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
break;
|
|
}
|
|
if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
|
|
if ((err = snd_trident_spdif_pcm(trident, pcm_dev++)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
}
|
|
if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
|
|
(err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
|
|
trident->midi_port,
|
|
MPU401_INFO_INTEGRATED |
|
|
MPU401_INFO_IRQ_HOOK,
|
|
-1, &trident->rmidi)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
|
|
snd_trident_create_gameport(trident);
|
|
|
|
if ((err = snd_card_register(card)) < 0) {
|
|
snd_card_free(card);
|
|
return err;
|
|
}
|
|
pci_set_drvdata(pci, card);
|
|
dev++;
|
|
return 0;
|
|
}
|
|
|
|
static void snd_trident_remove(struct pci_dev *pci)
|
|
{
|
|
snd_card_free(pci_get_drvdata(pci));
|
|
}
|
|
|
|
static struct pci_driver trident_driver = {
|
|
.name = KBUILD_MODNAME,
|
|
.id_table = snd_trident_ids,
|
|
.probe = snd_trident_probe,
|
|
.remove = snd_trident_remove,
|
|
#ifdef CONFIG_PM_SLEEP
|
|
.driver = {
|
|
.pm = &snd_trident_pm,
|
|
},
|
|
#endif
|
|
};
|
|
|
|
module_pci_driver(trident_driver);
|