Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: locomokbd - add 'off' button support for Sharp Collie/Poodle

Enables the Sharp Zaurus Collie and Poodle devices to be turned off
by pressing the "Cancel" button for a few seconds (as designed by
Sharp).

Additional small cleanups:
- removal of unused #defines and variables
- add missing __devinit/__devexit/__devinitconst annotations
- reorganized copyright notice

Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Helge Deller and committed by
Dmitry Torokhov
e6cdd156 3797fec1

+48 -25
+48 -25
drivers/input/keyboard/locomokbd.c
··· 1 1 /* 2 - * Copyright (c) 2005 John Lenz 2 + * LoCoMo keyboard driver for Linux-based ARM PDAs: 3 + * - SHARP Zaurus Collie (SL-5500) 4 + * - SHARP Zaurus Poodle (SL-5600) 3 5 * 6 + * Copyright (c) 2005 John Lenz 4 7 * Based on from xtkbd.c 5 - */ 6 - 7 - /* 8 - * LoCoMo keyboard driver for Linux/ARM 9 - */ 10 - 11 - /* 8 + * 9 + * 12 10 * This program is free software; you can redistribute it and/or modify 13 11 * it under the terms of the GNU General Public License as published by 14 12 * the Free Software Foundation; either version 2 of the License, or ··· 45 47 #define KEY_CONTACT KEY_F18 46 48 #define KEY_CENTER KEY_F15 47 49 48 - static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { 50 + static const unsigned char 51 + locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { 49 52 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ 50 53 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ 51 54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ ··· 66 67 #define KB_COLS 8 67 68 #define KB_ROWMASK(r) (1 << (r)) 68 69 #define SCANCODE(c,r) ( ((c)<<4) + (r) + 1 ) 69 - #define NR_SCANCODES 128 70 70 71 71 #define KB_DELAY 8 72 72 #define SCAN_INTERVAL (HZ/10) 73 - #define LOCOMOKBD_PRESSED 1 74 73 75 74 struct locomokbd { 76 75 unsigned char keycode[LOCOMOKBD_NUMKEYS]; 77 76 struct input_dev *input; 78 77 char phys[32]; 79 78 80 - struct locomo_dev *ldev; 81 79 unsigned long base; 82 80 spinlock_t lock; 83 81 84 82 struct timer_list timer; 83 + unsigned long suspend_jiffies; 84 + unsigned int count_cancel; 85 85 }; 86 86 87 87 /* helper functions for reading the keyboard matrix */ ··· 126 128 /* Scan the hardware keyboard and push any changes up through the input layer */ 127 129 static void locomokbd_scankeyboard(struct locomokbd *locomokbd) 128 130 { 129 - unsigned int row, col, rowd, scancode; 131 + unsigned int row, col, rowd; 130 132 unsigned long flags; 131 133 unsigned int num_pressed; 132 134 unsigned long membase = locomokbd->base; ··· 143 145 144 146 rowd = ~locomo_readl(membase + LOCOMO_KIB); 145 147 for (row = 0; row < KB_ROWS; row++) { 148 + unsigned int scancode, pressed, key; 149 + 146 150 scancode = SCANCODE(col, row); 147 - if (rowd & KB_ROWMASK(row)) { 148 - num_pressed += 1; 149 - input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1); 150 - } else { 151 - input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0); 152 - } 151 + pressed = rowd & KB_ROWMASK(row); 152 + key = locomokbd->keycode[scancode]; 153 + 154 + input_report_key(locomokbd->input, key, pressed); 155 + if (likely(!pressed)) 156 + continue; 157 + 158 + num_pressed++; 159 + 160 + /* The "Cancel/ESC" key is labeled "On/Off" on 161 + * Collie and Poodle and should suspend the device 162 + * if it was pressed for more than a second. */ 163 + if (unlikely(key == KEY_ESC)) { 164 + if (!time_after(jiffies, 165 + locomokbd->suspend_jiffies + HZ)) 166 + continue; 167 + if (locomokbd->count_cancel++ 168 + != (HZ/SCAN_INTERVAL + 1)) 169 + continue; 170 + input_event(locomokbd->input, EV_PWR, 171 + KEY_SUSPEND, 1); 172 + locomokbd->suspend_jiffies = jiffies; 173 + } else 174 + locomokbd->count_cancel = 0; 153 175 } 154 176 locomokbd_reset_col(membase, col); 155 177 } ··· 180 162 /* if any keys are pressed, enable the timer */ 181 163 if (num_pressed) 182 164 mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL); 165 + else 166 + locomokbd->count_cancel = 0; 183 167 184 168 spin_unlock_irqrestore(&locomokbd->lock, flags); 185 169 } ··· 206 186 static void locomokbd_timer_callback(unsigned long data) 207 187 { 208 188 struct locomokbd *locomokbd = (struct locomokbd *) data; 189 + 209 190 locomokbd_scankeyboard(locomokbd); 210 191 } 211 192 212 - static int locomokbd_probe(struct locomo_dev *dev) 193 + static int __devinit locomokbd_probe(struct locomo_dev *dev) 213 194 { 214 195 struct locomokbd *locomokbd; 215 196 struct input_dev *input_dev; ··· 232 211 goto err_free_mem; 233 212 } 234 213 235 - locomokbd->ldev = dev; 236 214 locomo_set_drvdata(dev, locomokbd); 237 215 238 216 locomokbd->base = (unsigned long) dev->mapbase; ··· 241 221 init_timer(&locomokbd->timer); 242 222 locomokbd->timer.function = locomokbd_timer_callback; 243 223 locomokbd->timer.data = (unsigned long) locomokbd; 224 + 225 + locomokbd->suspend_jiffies = jiffies; 244 226 245 227 locomokbd->input = input_dev; 246 228 strcpy(locomokbd->phys, "locomokbd/input0"); ··· 255 233 input_dev->id.version = 0x0100; 256 234 input_dev->dev.parent = &dev->dev; 257 235 258 - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 236 + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | 237 + BIT_MASK(EV_PWR); 259 238 input_dev->keycode = locomokbd->keycode; 260 - input_dev->keycodesize = sizeof(unsigned char); 239 + input_dev->keycodesize = sizeof(locomokbd_keycode[0]); 261 240 input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); 262 241 263 242 memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); ··· 291 268 return err; 292 269 } 293 270 294 - static int locomokbd_remove(struct locomo_dev *dev) 271 + static int __devexit locomokbd_remove(struct locomo_dev *dev) 295 272 { 296 273 struct locomokbd *locomokbd = locomo_get_drvdata(dev); 297 274 ··· 315 292 }, 316 293 .devid = LOCOMO_DEVID_KEYBOARD, 317 294 .probe = locomokbd_probe, 318 - .remove = locomokbd_remove, 295 + .remove = __devexit_p(locomokbd_remove), 319 296 }; 320 297 321 298 static int __init locomokbd_init(void)