File Index
Files and directories
Sign in
FILE

au88x0_game.c

File preview with syntax highlighting.

linux-6.19.14/sound/pci/au88x0/au88x0_game.c C
  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 <vojtech@suse.cz>, 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: mjander@embedded.cl).
 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
 30static 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
 36static 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
 42static int
 43vortex_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
 59static 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
 82static 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
110static 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
119static inline int vortex_gameport_register(vortex_t * vortex) { return -ENOSYS; }
120static inline void vortex_gameport_unregister(vortex_t * vortex) { }
121#endif
~/ Read-only file preview.