1 | /* |
2 | * Copyright (c) 2001 Vojtech Pavlik |
3 | */ |
4 | |
5 | /* |
6 | * EMU10k1 - SB Live / Audigy - gameport driver for Linux |
7 | */ |
8 | |
9 | /* |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. |
14 | * |
15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | */ |
24 | |
25 | #include <asm/io.h> |
26 | |
27 | #include <linux/module.h> |
28 | #include <linux/ioport.h> |
29 | #include <linux/gameport.h> |
30 | #include <linux/slab.h> |
31 | #include <linux/pci.h> |
32 | |
33 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>" ); |
34 | MODULE_DESCRIPTION("EMU10k1 gameport driver" ); |
35 | MODULE_LICENSE("GPL" ); |
36 | |
37 | struct emu { |
38 | struct pci_dev *dev; |
39 | struct gameport *gameport; |
40 | int io; |
41 | int size; |
42 | }; |
43 | |
44 | static const struct pci_device_id emu_tbl[] = { |
45 | |
46 | { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ |
47 | { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ |
48 | { 0x1102, 0x7004, PCI_ANY_ID, PCI_ANY_ID }, /* Dell SB Live */ |
49 | { 0x1102, 0x7005, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy LS gameport */ |
50 | { 0, } |
51 | }; |
52 | |
53 | MODULE_DEVICE_TABLE(pci, emu_tbl); |
54 | |
55 | static int emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
56 | { |
57 | struct emu *emu; |
58 | struct gameport *port; |
59 | int error; |
60 | |
61 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); |
62 | port = gameport_allocate_port(); |
63 | if (!emu || !port) { |
64 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n" ); |
65 | error = -ENOMEM; |
66 | goto err_out_free; |
67 | } |
68 | |
69 | error = pci_enable_device(pdev); |
70 | if (error) |
71 | goto err_out_free; |
72 | |
73 | emu->io = pci_resource_start(pdev, 0); |
74 | emu->size = pci_resource_len(pdev, 0); |
75 | |
76 | emu->dev = pdev; |
77 | emu->gameport = port; |
78 | |
79 | gameport_set_name(port, "EMU10K1" ); |
80 | gameport_set_phys(port, "pci%s/gameport0" , pci_name(pdev)); |
81 | port->dev.parent = &pdev->dev; |
82 | port->io = emu->io; |
83 | |
84 | if (!request_region(emu->io, emu->size, "emu10k1-gp" )) { |
85 | printk(KERN_ERR "emu10k1-gp: unable to grab region 0x%x-0x%x\n" , |
86 | emu->io, emu->io + emu->size - 1); |
87 | error = -EBUSY; |
88 | goto err_out_disable_dev; |
89 | } |
90 | |
91 | pci_set_drvdata(pdev, emu); |
92 | |
93 | gameport_register_port(port); |
94 | |
95 | return 0; |
96 | |
97 | err_out_disable_dev: |
98 | pci_disable_device(pdev); |
99 | err_out_free: |
100 | gameport_free_port(port); |
101 | kfree(emu); |
102 | return error; |
103 | } |
104 | |
105 | static void emu_remove(struct pci_dev *pdev) |
106 | { |
107 | struct emu *emu = pci_get_drvdata(pdev); |
108 | |
109 | gameport_unregister_port(emu->gameport); |
110 | release_region(emu->io, emu->size); |
111 | kfree(emu); |
112 | |
113 | pci_disable_device(pdev); |
114 | } |
115 | |
116 | static struct pci_driver emu_driver = { |
117 | .name = "Emu10k1_gameport" , |
118 | .id_table = emu_tbl, |
119 | .probe = emu_probe, |
120 | .remove = emu_remove, |
121 | }; |
122 | |
123 | module_pci_driver(emu_driver); |
124 | |