root/drivers/input/gameport/fm801-gp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fm801_gp_cooked_read
  2. fm801_gp_open
  3. fm801_gp_probe
  4. fm801_gp_remove

   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 
  23 struct fm801_gp {
  24         struct gameport *gameport;
  25         struct resource *res_port;
  26 };
  27 
  28 #ifdef HAVE_COOKED
  29 static 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 
  49 static 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 
  65 static 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 
 116 static 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 
 127 static 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 };
 131 MODULE_DEVICE_TABLE(pci, fm801_gp_id_table);
 132 
 133 static 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 
 140 module_pci_driver(fm801_gp_driver);
 141 
 142 MODULE_DESCRIPTION("FM801 gameport driver");
 143 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
 144 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */