#include <linux/gameport.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
-#include <asm/hardirq.h>
#include <asm/io.h>
#include <asm/dma.h>
#define DRIVER_VERSION "0.14.10j-2.6"
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
+
/* magic numbers to protect our data structures */
#define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
#define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */
};
static struct pci_device_id trident_pci_tbl[] = {
- {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX},
- {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_NX},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
- {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
- {PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, CYBER5050},
+ {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
+ PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TRIDENT_4D_DX},
+ {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
+ 0, 0, TRIDENT_4D_NX},
+ {PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, SIS_7018},
+ {PCI_DEVICE(PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451), 0, 0, ALI_5451},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050),
+ 0, 0, CYBER5050},
{0,}
};
struct timer_list timer;
/* Game port support */
- struct gameport gameport;
+ struct gameport *gameport;
};
enum dmabuf_mode {
static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card);
static void ali_restore_regs(struct trident_card *card);
static void ali_save_regs(struct trident_card *card);
-static int trident_suspend(struct pci_dev *dev, u32 unused);
+static int trident_suspend(struct pci_dev *dev, pm_message_t unused);
static int trident_resume(struct pci_dev *dev);
static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel);
static int ali_setup_multi_channels(struct trident_card *card, int chan_nums);
dmabuf->buforder = order;
/* now mark the pages as reserved; otherwise */
- /* remap_page_range doesn't do what we want */
+ /* remap_pfn_range doesn't do what we want */
pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
for (page = virt_to_page(rawbuf); page <= pend; page++)
SetPageReserved(page);
if (size > (PAGE_SIZE << dmabuf->buforder))
goto out;
ret = -EAGAIN;
- if (remap_page_range(vma, vma->vm_start, virt_to_phys(dmabuf->rawbuf),
+ if (remap_pfn_range(vma, vma->vm_start,
+ virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
size, vma->vm_page_prot))
goto out;
dmabuf->mapped = 1;
}
static int
-trident_suspend(struct pci_dev *dev, u32 unused)
+trident_suspend(struct pci_dev *dev, pm_message_t unused)
{
struct trident_card *card = pci_get_drvdata(dev);
}
}
-struct proc_dir_entry *res;
+static struct proc_dir_entry *res;
+
static int
ali_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
return num_ac97 + 1;
}
+#ifdef SUPPORT_JOYSTICK
/* Gameport functions for the cards ADC gameport */
-static unsigned char
-trident_game_read(struct gameport *gameport)
+static unsigned char trident_game_read(struct gameport *gameport)
{
- struct trident_card *card = gameport->driver;
+ struct trident_card *card = gameport->port_data;
+
return inb(TRID_REG(card, T4D_GAME_LEG));
}
-static void
-trident_game_trigger(struct gameport *gameport)
+static void trident_game_trigger(struct gameport *gameport)
{
- struct trident_card *card = gameport->driver;
+ struct trident_card *card = gameport->port_data;
+
outb(0xff, TRID_REG(card, T4D_GAME_LEG));
}
-static int
-trident_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
+static int trident_game_cooked_read(struct gameport *gameport,
+ int *axes, int *buttons)
{
- struct trident_card *card = gameport->driver;
+ struct trident_card *card = gameport->port_data;
int i;
*buttons = (~inb(TRID_REG(card, T4D_GAME_LEG)) >> 4) & 0xf;
return 0;
}
-static int
-trident_game_open(struct gameport *gameport, int mode)
+static int trident_game_open(struct gameport *gameport, int mode)
{
- struct trident_card *card = gameport->driver;
+ struct trident_card *card = gameport->port_data;
switch (mode) {
case GAMEPORT_MODE_COOKED:
return 0;
}
+static int __devinit trident_register_gameport(struct trident_card *card)
+{
+ struct gameport *gp;
+
+ card->gameport = gp = gameport_allocate_port();
+ if (!gp) {
+ printk(KERN_ERR "trident: can not allocate memory for gameport\n");
+ return -ENOMEM;
+ }
+
+ gameport_set_name(gp, "Trident 4DWave");
+ gameport_set_phys(gp, "pci%s/gameport0", pci_name(card->pci_dev));
+ gp->read = trident_game_read;
+ gp->trigger = trident_game_trigger;
+ gp->cooked_read = trident_game_cooked_read;
+ gp->open = trident_game_open;
+ gp->fuzz = 64;
+ gp->port_data = card;
+
+ gameport_register_port(gp);
+
+ return 0;
+}
+
+static inline void trident_unregister_gameport(struct trident_card *card)
+{
+ if (card->gameport)
+ gameport_unregister_port(card->gameport);
+}
+
+#else
+static inline int trident_register_gameport(struct trident_card *card) { return -ENOSYS; }
+static inline void trident_unregister_gameport(struct trident_card *card) { }
+#endif /* SUPPORT_JOYSTICK */
+
/* install the driver, we do not allocate hardware channel nor DMA buffer */
/* now, they are defered until "ACCESS" time (in prog_dmabuf called by */
/* open/read/write/ioctl/mmap) */
card->banks[BANK_B].addresses = &bank_b_addrs;
card->banks[BANK_B].bitmap = 0UL;
- card->gameport.driver = card;
- card->gameport.fuzz = 64;
- card->gameport.read = trident_game_read;
- card->gameport.trigger = trident_game_trigger;
- card->gameport.cooked_read = trident_game_cooked_read;
- card->gameport.open = trident_game_open;
-
init_MUTEX(&card->open_sem);
spin_lock_init(&card->lock);
init_timer(&card->timer);
trident_enable_loop_interrupts(card);
/* Register gameport */
- gameport_register_port(&card->gameport);
+ trident_register_gameport(card);
out:
return rc;
}
/* Unregister gameport */
- gameport_unregister_port(&card->gameport);
+ trident_unregister_gameport(card);
/* Kill interrupts, and SP/DIF */
trident_disable_loop_interrupts(card);
"5050 PCI Audio, version " DRIVER_VERSION ", " __TIME__ " "
__DATE__ "\n");
- if (!pci_register_driver(&trident_pci_driver)) {
- pci_unregister_driver(&trident_pci_driver);
- return -ENODEV;
- }
- return 0;
+ return pci_register_driver(&trident_pci_driver);
}
static void __exit