root/drivers/input/mouse/inport.c

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

DEFINITIONS

This source file includes following definitions.
  1. inport_interrupt
  2. inport_open
  3. inport_close
  4. inport_init
  5. inport_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (c) 1999-2001 Vojtech Pavlik
   4  *
   5  *  Based on the work of:
   6  *      Teemu Rantanen          Derrick Cole
   7  *      Peter Cervasio          Christoph Niemann
   8  *      Philip Blundell         Russell King
   9  *      Bob Harris
  10  */
  11 
  12 /*
  13  * Inport (ATI XL and Microsoft) busmouse driver for Linux
  14  */
  15 
  16 /*
  17  */
  18 
  19 #include <linux/module.h>
  20 #include <linux/ioport.h>
  21 #include <linux/init.h>
  22 #include <linux/interrupt.h>
  23 #include <linux/input.h>
  24 
  25 #include <asm/io.h>
  26 #include <asm/irq.h>
  27 
  28 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  29 MODULE_DESCRIPTION("Inport (ATI XL and Microsoft) busmouse driver");
  30 MODULE_LICENSE("GPL");
  31 
  32 #define INPORT_BASE             0x23c
  33 #define INPORT_EXTENT           4
  34 
  35 #define INPORT_CONTROL_PORT     INPORT_BASE + 0
  36 #define INPORT_DATA_PORT        INPORT_BASE + 1
  37 #define INPORT_SIGNATURE_PORT   INPORT_BASE + 2
  38 
  39 #define INPORT_REG_BTNS 0x00
  40 #define INPORT_REG_X            0x01
  41 #define INPORT_REG_Y            0x02
  42 #define INPORT_REG_MODE         0x07
  43 #define INPORT_RESET            0x80
  44 
  45 #ifdef CONFIG_MOUSE_ATIXL
  46 #define INPORT_NAME             "ATI XL Mouse"
  47 #define INPORT_VENDOR           0x0002
  48 #define INPORT_SPEED_30HZ       0x01
  49 #define INPORT_SPEED_50HZ       0x02
  50 #define INPORT_SPEED_100HZ      0x03
  51 #define INPORT_SPEED_200HZ      0x04
  52 #define INPORT_MODE_BASE        INPORT_SPEED_100HZ
  53 #define INPORT_MODE_IRQ         0x08
  54 #else
  55 #define INPORT_NAME             "Microsoft InPort Mouse"
  56 #define INPORT_VENDOR           0x0001
  57 #define INPORT_MODE_BASE        0x10
  58 #define INPORT_MODE_IRQ         0x01
  59 #endif
  60 #define INPORT_MODE_HOLD        0x20
  61 
  62 #define INPORT_IRQ              5
  63 
  64 static int inport_irq = INPORT_IRQ;
  65 module_param_hw_named(irq, inport_irq, uint, irq, 0);
  66 MODULE_PARM_DESC(irq, "IRQ number (5=default)");
  67 
  68 static struct input_dev *inport_dev;
  69 
  70 static irqreturn_t inport_interrupt(int irq, void *dev_id)
  71 {
  72         unsigned char buttons;
  73 
  74         outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
  75         outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
  76 
  77         outb(INPORT_REG_X, INPORT_CONTROL_PORT);
  78         input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
  79 
  80         outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
  81         input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
  82 
  83         outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
  84         buttons = inb(INPORT_DATA_PORT);
  85 
  86         input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
  87         input_report_key(inport_dev, BTN_LEFT,   buttons & 2);
  88         input_report_key(inport_dev, BTN_RIGHT,  buttons & 4);
  89 
  90         outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
  91         outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
  92 
  93         input_sync(inport_dev);
  94         return IRQ_HANDLED;
  95 }
  96 
  97 static int inport_open(struct input_dev *dev)
  98 {
  99         if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
 100                 return -EBUSY;
 101         outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 102         outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
 103 
 104         return 0;
 105 }
 106 
 107 static void inport_close(struct input_dev *dev)
 108 {
 109         outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 110         outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
 111         free_irq(inport_irq, NULL);
 112 }
 113 
 114 static int __init inport_init(void)
 115 {
 116         unsigned char a, b, c;
 117         int err;
 118 
 119         if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
 120                 printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
 121                 return -EBUSY;
 122         }
 123 
 124         a = inb(INPORT_SIGNATURE_PORT);
 125         b = inb(INPORT_SIGNATURE_PORT);
 126         c = inb(INPORT_SIGNATURE_PORT);
 127         if (a == b || a != c) {
 128                 printk(KERN_INFO "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
 129                 err = -ENODEV;
 130                 goto err_release_region;
 131         }
 132 
 133         inport_dev = input_allocate_device();
 134         if (!inport_dev) {
 135                 printk(KERN_ERR "inport.c: Not enough memory for input device\n");
 136                 err = -ENOMEM;
 137                 goto err_release_region;
 138         }
 139 
 140         inport_dev->name = INPORT_NAME;
 141         inport_dev->phys = "isa023c/input0";
 142         inport_dev->id.bustype = BUS_ISA;
 143         inport_dev->id.vendor  = INPORT_VENDOR;
 144         inport_dev->id.product = 0x0001;
 145         inport_dev->id.version = 0x0100;
 146 
 147         inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 148         inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
 149                 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 150         inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 151 
 152         inport_dev->open  = inport_open;
 153         inport_dev->close = inport_close;
 154 
 155         outb(INPORT_RESET, INPORT_CONTROL_PORT);
 156         outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 157         outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
 158 
 159         err = input_register_device(inport_dev);
 160         if (err)
 161                 goto err_free_dev;
 162 
 163         return 0;
 164 
 165  err_free_dev:
 166         input_free_device(inport_dev);
 167  err_release_region:
 168         release_region(INPORT_BASE, INPORT_EXTENT);
 169 
 170         return err;
 171 }
 172 
 173 static void __exit inport_exit(void)
 174 {
 175         input_unregister_device(inport_dev);
 176         release_region(INPORT_BASE, INPORT_EXTENT);
 177 }
 178 
 179 module_init(inport_init);
 180 module_exit(inport_exit);

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