root/sound/pci/au88x0/au88x0_game.c

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

DEFINITIONS

This source file includes following definitions.
  1. vortex_game_read
  2. vortex_game_trigger
  3. vortex_game_cooked_read
  4. vortex_game_open
  5. vortex_gameport_register
  6. vortex_gameport_unregister
  7. vortex_gameport_register
  8. vortex_gameport_unregister

   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 
  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

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