root/drivers/input/keyboard/xtkbd.c

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

DEFINITIONS

This source file includes following definitions.
  1. xtkbd_interrupt
  2. xtkbd_connect
  3. xtkbd_disconnect

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (c) 1999-2001 Vojtech Pavlik
   4  */
   5 
   6 /*
   7  * XT keyboard driver for Linux
   8  */
   9 
  10 /*
  11  */
  12 
  13 #include <linux/slab.h>
  14 #include <linux/module.h>
  15 #include <linux/input.h>
  16 #include <linux/serio.h>
  17 
  18 #define DRIVER_DESC     "XT keyboard driver"
  19 
  20 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  21 MODULE_DESCRIPTION(DRIVER_DESC);
  22 MODULE_LICENSE("GPL");
  23 
  24 #define XTKBD_EMUL0     0xe0
  25 #define XTKBD_EMUL1     0xe1
  26 #define XTKBD_KEY       0x7f
  27 #define XTKBD_RELEASE   0x80
  28 
  29 static unsigned char xtkbd_keycode[256] = {
  30           0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  31          16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32          32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  33          48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  34          64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  35          80, 81, 82, 83,  0,  0,  0, 87, 88,  0,  0,  0,  0,  0,  0,  0,
  36           0,  0,  0,  0,  0, 87, 88,  0,  0,  0,  0,110,111,103,108,105,
  37         106
  38 };
  39 
  40 struct xtkbd {
  41         unsigned char keycode[256];
  42         struct input_dev *dev;
  43         struct serio *serio;
  44         char phys[32];
  45 };
  46 
  47 static irqreturn_t xtkbd_interrupt(struct serio *serio,
  48         unsigned char data, unsigned int flags)
  49 {
  50         struct xtkbd *xtkbd = serio_get_drvdata(serio);
  51 
  52         switch (data) {
  53                 case XTKBD_EMUL0:
  54                 case XTKBD_EMUL1:
  55                         break;
  56                 default:
  57 
  58                         if (xtkbd->keycode[data & XTKBD_KEY]) {
  59                                 input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
  60                                 input_sync(xtkbd->dev);
  61                         } else {
  62                                 printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
  63                                         data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
  64                         }
  65         }
  66         return IRQ_HANDLED;
  67 }
  68 
  69 static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
  70 {
  71         struct xtkbd *xtkbd;
  72         struct input_dev *input_dev;
  73         int err = -ENOMEM;
  74         int i;
  75 
  76         xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL);
  77         input_dev = input_allocate_device();
  78         if (!xtkbd || !input_dev)
  79                 goto fail1;
  80 
  81         xtkbd->serio = serio;
  82         xtkbd->dev = input_dev;
  83         snprintf(xtkbd->phys, sizeof(xtkbd->phys), "%s/input0", serio->phys);
  84         memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
  85 
  86         input_dev->name = "XT Keyboard";
  87         input_dev->phys = xtkbd->phys;
  88         input_dev->id.bustype = BUS_XTKBD;
  89         input_dev->id.vendor  = 0x0001;
  90         input_dev->id.product = 0x0001;
  91         input_dev->id.version = 0x0100;
  92         input_dev->dev.parent = &serio->dev;
  93 
  94         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
  95         input_dev->keycode = xtkbd->keycode;
  96         input_dev->keycodesize = sizeof(unsigned char);
  97         input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
  98 
  99         for (i = 0; i < 255; i++)
 100                 set_bit(xtkbd->keycode[i], input_dev->keybit);
 101         clear_bit(0, input_dev->keybit);
 102 
 103         serio_set_drvdata(serio, xtkbd);
 104 
 105         err = serio_open(serio, drv);
 106         if (err)
 107                 goto fail2;
 108 
 109         err = input_register_device(xtkbd->dev);
 110         if (err)
 111                 goto fail3;
 112 
 113         return 0;
 114 
 115  fail3: serio_close(serio);
 116  fail2: serio_set_drvdata(serio, NULL);
 117  fail1: input_free_device(input_dev);
 118         kfree(xtkbd);
 119         return err;
 120 }
 121 
 122 static void xtkbd_disconnect(struct serio *serio)
 123 {
 124         struct xtkbd *xtkbd = serio_get_drvdata(serio);
 125 
 126         serio_close(serio);
 127         serio_set_drvdata(serio, NULL);
 128         input_unregister_device(xtkbd->dev);
 129         kfree(xtkbd);
 130 }
 131 
 132 static const struct serio_device_id xtkbd_serio_ids[] = {
 133         {
 134                 .type   = SERIO_XT,
 135                 .proto  = SERIO_ANY,
 136                 .id     = SERIO_ANY,
 137                 .extra  = SERIO_ANY,
 138         },
 139         { 0 }
 140 };
 141 
 142 MODULE_DEVICE_TABLE(serio, xtkbd_serio_ids);
 143 
 144 static struct serio_driver xtkbd_drv = {
 145         .driver         = {
 146                 .name   = "xtkbd",
 147         },
 148         .description    = DRIVER_DESC,
 149         .id_table       = xtkbd_serio_ids,
 150         .interrupt      = xtkbd_interrupt,
 151         .connect        = xtkbd_connect,
 152         .disconnect     = xtkbd_disconnect,
 153 };
 154 
 155 module_serio_driver(xtkbd_drv);

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