Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
newtonkbd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000 Justin Cormack
3  */
4 
5 /*
6  * Newton keyboard driver for Linux
7  */
8 
9 /*
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * Should you need to contact me, the author, you can do so either by
25  * e-mail - mail your message to <[email protected]>, or by paper mail:
26  * Justin Cormack, 68 Dartmouth Park Road, London NW5 1SN, UK.
27  */
28 
29 #include <linux/slab.h>
30 #include <linux/module.h>
31 #include <linux/input.h>
32 #include <linux/init.h>
33 #include <linux/serio.h>
34 
35 #define DRIVER_DESC "Newton keyboard driver"
36 
37 MODULE_AUTHOR("Justin Cormack <[email protected]>");
39 MODULE_LICENSE("GPL");
40 
41 #define NKBD_KEY 0x7f
42 #define NKBD_PRESS 0x80
43 
44 static unsigned char nkbd_keycode[128] = {
53  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 };
59 
60 struct nkbd {
61  unsigned char keycode[128];
62  struct input_dev *dev;
63  struct serio *serio;
64  char phys[32];
65 };
66 
67 static irqreturn_t nkbd_interrupt(struct serio *serio,
68  unsigned char data, unsigned int flags)
69 {
70  struct nkbd *nkbd = serio_get_drvdata(serio);
71 
72  /* invalid scan codes are probably the init sequence, so we ignore them */
73  if (nkbd->keycode[data & NKBD_KEY]) {
74  input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
75  input_sync(nkbd->dev);
76  }
77 
78  else if (data == 0xe7) /* end of init sequence */
79  printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
80  return IRQ_HANDLED;
81 
82 }
83 
84 static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
85 {
86  struct nkbd *nkbd;
87  struct input_dev *input_dev;
88  int err = -ENOMEM;
89  int i;
90 
91  nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
92  input_dev = input_allocate_device();
93  if (!nkbd || !input_dev)
94  goto fail1;
95 
96  nkbd->serio = serio;
97  nkbd->dev = input_dev;
98  snprintf(nkbd->phys, sizeof(nkbd->phys), "%s/input0", serio->phys);
99  memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
100 
101  input_dev->name = "Newton Keyboard";
102  input_dev->phys = nkbd->phys;
103  input_dev->id.bustype = BUS_RS232;
104  input_dev->id.vendor = SERIO_NEWTON;
105  input_dev->id.product = 0x0001;
106  input_dev->id.version = 0x0100;
107  input_dev->dev.parent = &serio->dev;
108 
109  input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
110  input_dev->keycode = nkbd->keycode;
111  input_dev->keycodesize = sizeof(unsigned char);
112  input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
113  for (i = 0; i < 128; i++)
114  set_bit(nkbd->keycode[i], input_dev->keybit);
115  clear_bit(0, input_dev->keybit);
116 
117  serio_set_drvdata(serio, nkbd);
118 
119  err = serio_open(serio, drv);
120  if (err)
121  goto fail2;
122 
123  err = input_register_device(nkbd->dev);
124  if (err)
125  goto fail3;
126 
127  return 0;
128 
129  fail3: serio_close(serio);
130  fail2: serio_set_drvdata(serio, NULL);
131  fail1: input_free_device(input_dev);
132  kfree(nkbd);
133  return err;
134 }
135 
136 static void nkbd_disconnect(struct serio *serio)
137 {
138  struct nkbd *nkbd = serio_get_drvdata(serio);
139 
140  serio_close(serio);
141  serio_set_drvdata(serio, NULL);
142  input_unregister_device(nkbd->dev);
143  kfree(nkbd);
144 }
145 
146 static struct serio_device_id nkbd_serio_ids[] = {
147  {
148  .type = SERIO_RS232,
149  .proto = SERIO_NEWTON,
150  .id = SERIO_ANY,
151  .extra = SERIO_ANY,
152  },
153  { 0 }
154 };
155 
156 MODULE_DEVICE_TABLE(serio, nkbd_serio_ids);
157 
158 static struct serio_driver nkbd_drv = {
159  .driver = {
160  .name = "newtonkbd",
161  },
162  .description = DRIVER_DESC,
163  .id_table = nkbd_serio_ids,
164  .interrupt = nkbd_interrupt,
165  .connect = nkbd_connect,
166  .disconnect = nkbd_disconnect,
167 };
168 
169 module_serio_driver(nkbd_drv);