Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/au88x0/au88x0_game.c
26451 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Manuel Jander.
4
*
5
* Based on the work of:
6
* Vojtech Pavlik
7
* Raymond Ingles
8
*
9
* Should you need to contact me, the author, you can do so either by
10
* e-mail - mail your message to <[email protected]>, or by paper mail:
11
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
12
*
13
* Based 90% on Vojtech Pavlik pcigame driver.
14
* Merged and modified by Manuel Jander, for the OpenVortex
15
* driver. (email: [email protected]).
16
*/
17
18
#include <linux/time.h>
19
#include <linux/delay.h>
20
#include <linux/init.h>
21
#include <sound/core.h>
22
#include "au88x0.h"
23
#include <linux/gameport.h>
24
#include <linux/export.h>
25
26
#if IS_REACHABLE(CONFIG_GAMEPORT)
27
28
#define VORTEX_GAME_DWAIT 20 /* 20 ms */
29
30
static unsigned char vortex_game_read(struct gameport *gameport)
31
{
32
vortex_t *vortex = gameport_get_port_data(gameport);
33
return hwread(vortex->mmio, VORTEX_GAME_LEGACY);
34
}
35
36
static void vortex_game_trigger(struct gameport *gameport)
37
{
38
vortex_t *vortex = gameport_get_port_data(gameport);
39
hwwrite(vortex->mmio, VORTEX_GAME_LEGACY, 0xff);
40
}
41
42
static int
43
vortex_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
44
{
45
vortex_t *vortex = gameport_get_port_data(gameport);
46
int i;
47
48
*buttons = (~hwread(vortex->mmio, VORTEX_GAME_LEGACY) >> 4) & 0xf;
49
50
for (i = 0; i < 4; i++) {
51
axes[i] =
52
hwread(vortex->mmio, VORTEX_GAME_AXIS + (i * AXIS_SIZE));
53
if (axes[i] == AXIS_RANGE)
54
axes[i] = -1;
55
}
56
return 0;
57
}
58
59
static int vortex_game_open(struct gameport *gameport, int mode)
60
{
61
vortex_t *vortex = gameport_get_port_data(gameport);
62
63
switch (mode) {
64
case GAMEPORT_MODE_COOKED:
65
hwwrite(vortex->mmio, VORTEX_CTRL2,
66
hwread(vortex->mmio,
67
VORTEX_CTRL2) | CTRL2_GAME_ADCMODE);
68
msleep(VORTEX_GAME_DWAIT);
69
return 0;
70
case GAMEPORT_MODE_RAW:
71
hwwrite(vortex->mmio, VORTEX_CTRL2,
72
hwread(vortex->mmio,
73
VORTEX_CTRL2) & ~CTRL2_GAME_ADCMODE);
74
return 0;
75
default:
76
return -1;
77
}
78
79
return 0;
80
}
81
82
static int vortex_gameport_register(vortex_t *vortex)
83
{
84
struct gameport *gp;
85
86
vortex->gameport = gp = gameport_allocate_port();
87
if (!gp) {
88
dev_err(vortex->card->dev,
89
"cannot allocate memory for gameport\n");
90
return -ENOMEM;
91
}
92
93
gameport_set_name(gp, "AU88x0 Gameport");
94
gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
95
gameport_set_dev_parent(gp, &vortex->pci_dev->dev);
96
97
gp->read = vortex_game_read;
98
gp->trigger = vortex_game_trigger;
99
gp->cooked_read = vortex_game_cooked_read;
100
gp->open = vortex_game_open;
101
102
gameport_set_port_data(gp, vortex);
103
gp->fuzz = 64;
104
105
gameport_register_port(gp);
106
107
return 0;
108
}
109
110
static void vortex_gameport_unregister(vortex_t * vortex)
111
{
112
if (vortex->gameport) {
113
gameport_unregister_port(vortex->gameport);
114
vortex->gameport = NULL;
115
}
116
}
117
118
#else
119
static inline int vortex_gameport_register(vortex_t * vortex) { return -ENOSYS; }
120
static inline void vortex_gameport_unregister(vortex_t * vortex) { }
121
#endif
122
123