cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fm801-gp.c (3273B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  FM801 gameport driver for Linux
      4 *
      5 *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
      6 */
      7
      8#include <asm/io.h>
      9#include <linux/delay.h>
     10#include <linux/errno.h>
     11#include <linux/ioport.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/pci.h>
     15#include <linux/slab.h>
     16#include <linux/gameport.h>
     17
     18#define PCI_VENDOR_ID_FORTEMEDIA	0x1319
     19#define PCI_DEVICE_ID_FM801_GP	0x0802
     20
     21#define HAVE_COOKED
     22
     23struct fm801_gp {
     24	struct gameport *gameport;
     25	struct resource *res_port;
     26};
     27
     28#ifdef HAVE_COOKED
     29static int fm801_gp_cooked_read(struct gameport *gameport, int *axes, int *buttons)
     30{
     31	unsigned short w;
     32
     33	w = inw(gameport->io + 2);
     34	*buttons = (~w >> 14) & 0x03;
     35	axes[0] = (w == 0xffff) ? -1 : ((w & 0x1fff) << 5);
     36	w = inw(gameport->io + 4);
     37	axes[1] = (w == 0xffff) ? -1 : ((w & 0x1fff) << 5);
     38	w = inw(gameport->io + 6);
     39	*buttons |= ((~w >> 14) & 0x03) << 2;
     40	axes[2] = (w == 0xffff) ? -1 : ((w & 0x1fff) << 5);
     41	w = inw(gameport->io + 8);
     42	axes[3] = (w == 0xffff) ? -1 : ((w & 0x1fff) << 5);
     43	outw(0xff, gameport->io); /* reset */
     44
     45        return 0;
     46}
     47#endif
     48
     49static int fm801_gp_open(struct gameport *gameport, int mode)
     50{
     51	switch (mode) {
     52#ifdef HAVE_COOKED
     53	case GAMEPORT_MODE_COOKED:
     54		return 0;
     55#endif
     56	case GAMEPORT_MODE_RAW:
     57		return 0;
     58	default:
     59		return -1;
     60	}
     61
     62	return 0;
     63}
     64
     65static int fm801_gp_probe(struct pci_dev *pci, const struct pci_device_id *id)
     66{
     67	struct fm801_gp *gp;
     68	struct gameport *port;
     69	int error;
     70
     71	gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL);
     72	port = gameport_allocate_port();
     73	if (!gp || !port) {
     74		printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
     75		error = -ENOMEM;
     76		goto err_out_free;
     77	}
     78
     79	error = pci_enable_device(pci);
     80	if (error)
     81		goto err_out_free;
     82
     83	port->open = fm801_gp_open;
     84#ifdef HAVE_COOKED
     85	port->cooked_read = fm801_gp_cooked_read;
     86#endif
     87	gameport_set_name(port, "FM801");
     88	gameport_set_phys(port, "pci%s/gameport0", pci_name(pci));
     89	port->dev.parent = &pci->dev;
     90	port->io = pci_resource_start(pci, 0);
     91
     92	gp->gameport = port;
     93	gp->res_port = request_region(port->io, 0x10, "FM801 GP");
     94	if (!gp->res_port) {
     95		printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n",
     96			port->io, port->io + 0x0f);
     97		error = -EBUSY;
     98		goto err_out_disable_dev;
     99	}
    100
    101	pci_set_drvdata(pci, gp);
    102
    103	outb(0x60, port->io + 0x0d); /* enable joystick 1 and 2 */
    104	gameport_register_port(port);
    105
    106	return 0;
    107
    108 err_out_disable_dev:
    109	pci_disable_device(pci);
    110 err_out_free:
    111	gameport_free_port(port);
    112	kfree(gp);
    113	return error;
    114}
    115
    116static void fm801_gp_remove(struct pci_dev *pci)
    117{
    118	struct fm801_gp *gp = pci_get_drvdata(pci);
    119
    120	gameport_unregister_port(gp->gameport);
    121	release_resource(gp->res_port);
    122	kfree(gp);
    123
    124	pci_disable_device(pci);
    125}
    126
    127static const struct pci_device_id fm801_gp_id_table[] = {
    128	{ PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0  },
    129	{ 0 }
    130};
    131MODULE_DEVICE_TABLE(pci, fm801_gp_id_table);
    132
    133static struct pci_driver fm801_gp_driver = {
    134	.name =		"FM801_gameport",
    135	.id_table =	fm801_gp_id_table,
    136	.probe =	fm801_gp_probe,
    137	.remove =	fm801_gp_remove,
    138};
    139
    140module_pci_driver(fm801_gp_driver);
    141
    142MODULE_DESCRIPTION("FM801 gameport driver");
    143MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
    144MODULE_LICENSE("GPL");