OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [joystick/] [cs461x.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
        The all defines and part of code (such as cs461x_*) are
3
        contributed from ALSA 0.5.8 sources.
4
        See http://www.alsa-project.org/ for sources
5
 
6
        Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
7
*/
8
 
9
#include <asm/io.h>
10
 
11
#include <linux/module.h>
12
#include <linux/ioport.h>
13
#include <linux/config.h>
14
#include <linux/init.h>
15
#include <linux/gameport.h>
16
#include <linux/slab.h>
17
#include <linux/pci.h>
18
 
19
MODULE_AUTHOR("Victor Krapivin <vik@belcaf.minsk.by>");
20
MODULE_LICENSE("GPL");
21
 
22
/*
23
        These options are experimental
24
 
25
#define CS461X_FULL_MAP
26
*/
27
 
28
#define COOKED_MODE
29
 
30
 
31
#ifndef PCI_VENDOR_ID_CIRRUS
32
#define PCI_VENDOR_ID_CIRRUS            0x1013
33
#endif
34
#ifndef PCI_DEVICE_ID_CIRRUS_4610
35
#define PCI_DEVICE_ID_CIRRUS_4610       0x6001
36
#endif
37
#ifndef PCI_DEVICE_ID_CIRRUS_4612
38
#define PCI_DEVICE_ID_CIRRUS_4612       0x6003
39
#endif
40
#ifndef PCI_DEVICE_ID_CIRRUS_4615
41
#define PCI_DEVICE_ID_CIRRUS_4615       0x6004
42
#endif
43
 
44
/* Registers */
45
 
46
#define BA0_JSPT                                0x00000480
47
#define BA0_JSCTL                               0x00000484
48
#define BA0_JSC1                                0x00000488
49
#define BA0_JSC2                                0x0000048C
50
#define BA0_JSIO                                0x000004A0
51
 
52
/* Bits for JSPT */
53
 
54
#define JSPT_CAX                                0x00000001
55
#define JSPT_CAY                                0x00000002
56
#define JSPT_CBX                                0x00000004
57
#define JSPT_CBY                                0x00000008
58
#define JSPT_BA1                                0x00000010
59
#define JSPT_BA2                                0x00000020
60
#define JSPT_BB1                                0x00000040
61
#define JSPT_BB2                                0x00000080
62
 
63
/* Bits for JSCTL */
64
 
65
#define JSCTL_SP_MASK                           0x00000003
66
#define JSCTL_SP_SLOW                           0x00000000
67
#define JSCTL_SP_MEDIUM_SLOW                    0x00000001
68
#define JSCTL_SP_MEDIUM_FAST                    0x00000002
69
#define JSCTL_SP_FAST                           0x00000003
70
#define JSCTL_ARE                               0x00000004
71
 
72
/* Data register pairs masks */
73
 
74
#define JSC1_Y1V_MASK                           0x0000FFFF
75
#define JSC1_X1V_MASK                           0xFFFF0000
76
#define JSC1_Y1V_SHIFT                          0
77
#define JSC1_X1V_SHIFT                          16
78
#define JSC2_Y2V_MASK                           0x0000FFFF
79
#define JSC2_X2V_MASK                           0xFFFF0000
80
#define JSC2_Y2V_SHIFT                          0
81
#define JSC2_X2V_SHIFT                          16
82
 
83
/* JS GPIO */
84
 
85
#define JSIO_DAX                                0x00000001
86
#define JSIO_DAY                                0x00000002
87
#define JSIO_DBX                                0x00000004
88
#define JSIO_DBY                                0x00000008
89
#define JSIO_AXOE                               0x00000010
90
#define JSIO_AYOE                               0x00000020
91
#define JSIO_BXOE                               0x00000040
92
#define JSIO_BYOE                               0x00000080
93
 
94
/*
95
   The card initialization code is obfuscated; the module cs461x
96
   need to be loaded after ALSA modules initialized and something
97
   played on the CS 4610 chip (see sources for details of CS4610
98
   initialization code from ALSA)
99
*/
100
 
101
/* Card specific definitions */
102
 
103
#define CS461X_BA0_SIZE         0x2000
104
#define CS461X_BA1_DATA0_SIZE   0x3000
105
#define CS461X_BA1_DATA1_SIZE   0x3800
106
#define CS461X_BA1_PRG_SIZE     0x7000
107
#define CS461X_BA1_REG_SIZE     0x0100
108
 
109
#define BA1_SP_DMEM0                            0x00000000
110
#define BA1_SP_DMEM1                            0x00010000
111
#define BA1_SP_PMEM                             0x00020000
112
#define BA1_SP_REG                              0x00030000
113
 
114
#define BA1_DWORD_SIZE          (13 * 1024 + 512)
115
#define BA1_MEMORY_COUNT        3
116
 
117
/*
118
   Only one CS461x card is still suppoted; the code requires
119
   redesign to avoid this limitatuion.
120
*/
121
 
122
static unsigned long ba0_addr;
123
static unsigned int *ba0;
124
 
125
#ifdef CS461X_FULL_MAP
126
static unsigned long ba1_addr;
127
static union ba1_t {
128
        struct {
129
                unsigned int *data0;
130
                unsigned int *data1;
131
                unsigned int *pmem;
132
                unsigned int *reg;
133
        } name;
134
        unsigned int *idx[4];
135
} ba1;
136
 
137
static void cs461x_poke(unsigned long reg, unsigned int val)
138
{
139
        ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff] = val;
140
}
141
 
142
static unsigned int cs461x_peek(unsigned long reg)
143
{
144
        return ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff];
145
}
146
 
147
#endif
148
 
149
static void cs461x_pokeBA0(unsigned long reg, unsigned int val)
150
{
151
        ba0[reg >> 2] = val;
152
}
153
 
154
static unsigned int cs461x_peekBA0(unsigned long reg)
155
{
156
        return ba0[reg >> 2];
157
}
158
 
159
static int cs461x_free(struct pci_dev *pdev)
160
{
161
        struct gameport *port = pci_get_drvdata(pdev);
162
        if(port){
163
            gameport_unregister_port(port);
164
            kfree(port);
165
        }
166
        if (ba0) iounmap(ba0);
167
#ifdef CS461X_FULL_MAP
168
        if (ba1.name.data0) iounmap(ba1.name.data0);
169
        if (ba1.name.data1) iounmap(ba1.name.data1);
170
        if (ba1.name.pmem)  iounmap(ba1.name.pmem);
171
        if (ba1.name.reg)   iounmap(ba1.name.reg);
172
#endif
173
        return 0;
174
}
175
 
176
static void cs461x_gameport_trigger(struct gameport *gameport)
177
{
178
        cs461x_pokeBA0(BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
179
}
180
 
181
static unsigned char cs461x_gameport_read(struct gameport *gameport)
182
{
183
        return cs461x_peekBA0(BA0_JSPT); //inb(gameport->io);
184
}
185
 
186
static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
187
{
188
        unsigned js1, js2, jst;
189
 
190
        js1 = cs461x_peekBA0(BA0_JSC1);
191
        js2 = cs461x_peekBA0(BA0_JSC2);
192
        jst = cs461x_peekBA0(BA0_JSPT);
193
 
194
        *buttons = (~jst >> 4) & 0x0F;
195
 
196
        axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
197
        axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
198
        axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
199
        axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
200
 
201
        for(jst=0;jst<4;++jst)
202
                if(axes[jst]==0xFFFF) axes[jst] = -1;
203
        return 0;
204
}
205
 
206
static int cs461x_gameport_open(struct gameport *gameport, int mode)
207
{
208
        switch (mode) {
209
#ifdef COOKED_MODE
210
        case GAMEPORT_MODE_COOKED:
211
                return 0;
212
#endif
213
        case GAMEPORT_MODE_RAW:
214
                return 0;
215
        default:
216
                return -1;
217
        }
218
        return 0;
219
}
220
 
221
static struct pci_device_id cs461x_pci_tbl[] __devinitdata = {
222
        { PCI_VENDOR_ID_CIRRUS, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4610 */
223
        { PCI_VENDOR_ID_CIRRUS, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4612 */
224
        { PCI_VENDOR_ID_CIRRUS, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4615 */
225
        { 0, }
226
};
227
MODULE_DEVICE_TABLE(pci, cs461x_pci_tbl);
228
 
229
static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
230
{
231
        int rc;
232
        struct gameport* port;
233
 
234
        rc = pci_enable_device(pdev);
235
        if (rc) {
236
                printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
237
                        pdev->bus->number, pdev->devfn, rc);
238
                return rc;
239
        }
240
 
241
        ba0_addr = pci_resource_start(pdev, 0);
242
#ifdef CS461X_FULL_MAP
243
        ba1_addr = pci_resource_start(pdev, 1);
244
#endif
245
        if (ba0_addr == 0 || ba0_addr == ~0
246
#ifdef CS461X_FULL_MAP
247
            || ba1_addr == 0 || ba1_addr == ~0
248
#endif
249
            ) {
250
                printk(KERN_ERR "cs461x: wrong address - ba0 = 0x%lx\n", ba0_addr);
251
#ifdef CS461X_FULL_MAP
252
                printk(KERN_ERR "cs461x: wrong address - ba1 = 0x%lx\n", ba1_addr);
253
#endif
254
                cs461x_free(pdev);
255
                return -ENOMEM;
256
        }
257
 
258
        ba0 = ioremap(ba0_addr, CS461X_BA0_SIZE);
259
#ifdef CS461X_FULL_MAP
260
        ba1.name.data0 = ioremap(ba1_addr + BA1_SP_DMEM0, CS461X_BA1_DATA0_SIZE);
261
        ba1.name.data1 = ioremap(ba1_addr + BA1_SP_DMEM1, CS461X_BA1_DATA1_SIZE);
262
        ba1.name.pmem  = ioremap(ba1_addr + BA1_SP_PMEM, CS461X_BA1_PRG_SIZE);
263
        ba1.name.reg   = ioremap(ba1_addr + BA1_SP_REG, CS461X_BA1_REG_SIZE);
264
 
265
        if (ba0 == NULL || ba1.name.data0 == NULL ||
266
            ba1.name.data1 == NULL || ba1.name.pmem == NULL ||
267
            ba1.name.reg == NULL) {
268
                cs461x_free(pdev);
269
                return -ENOMEM;
270
        }
271
#else
272
        if (ba0 == NULL){
273
                cs461x_free(pdev);
274
                return -ENOMEM;
275
        }
276
#endif
277
        printk(KERN_INFO "CS461x PCI: %lx[%d]\n",
278
            ba0_addr, CS461X_BA0_SIZE);
279
 
280
        if (!(port = kmalloc(sizeof(struct gameport), GFP_KERNEL))) {
281
                printk(KERN_ERR "Memory allocation failed.\n");
282
                cs461x_free(pdev);
283
                return -ENOMEM;
284
        }
285
        memset(port, 0, sizeof(struct gameport));
286
 
287
        pci_set_drvdata(pdev, port);
288
 
289
        port->open = cs461x_gameport_open;
290
        port->read = cs461x_gameport_read;
291
        port->trigger = cs461x_gameport_trigger;
292
#ifdef COOKED_MODE
293
        port->cooked_read = cs461x_gameport_cooked_read;
294
#endif
295
 
296
        cs461x_pokeBA0(BA0_JSIO, 0xFF); // ?
297
        cs461x_pokeBA0(BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
298
 
299
        gameport_register_port(port);
300
 
301
        printk(KERN_INFO "gameport%d: CS461x Gameport speed %d kHz\n",
302
                port->number, port->speed);
303
 
304
        return 0;
305
}
306
 
307
static void __devexit cs461x_pci_remove(struct pci_dev *pdev)
308
{
309
        cs461x_free(pdev);
310
}
311
 
312
static struct pci_driver cs461x_pci_driver = {
313
        name:           "PCI Gameport",
314
        id_table:       cs461x_pci_tbl,
315
        probe:          cs461x_pci_probe,
316
        remove:         __devexit_p(cs461x_pci_remove),
317
};
318
 
319
int __init js_cs461x_init(void)
320
{
321
        return pci_module_init(&cs461x_pci_driver);
322
}
323
 
324
void __exit js_cs461x_exit(void)
325
{
326
        pci_unregister_driver(&cs461x_pci_driver);
327
}
328
 
329
module_init(js_cs461x_init);
330
module_exit(js_cs461x_exit);
331
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.