1 /* 2 * Sony Programmable I/O Control Device driver for VAIO 3 * 4 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net> 5 * 6 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org> 7 * 8 * Copyright (C) 2001-2002 Alc�ve <www.alcove.com> 9 * 10 * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> 11 * 12 * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> 13 * 14 * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp> 15 * 16 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> 17 * 18 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. 19 * 20 * This program is free software; you can redistribute it and/or modify 21 * it under the terms of the GNU General Public License as published by 22 * the Free Software Foundation; either version 2 of the License, or 23 * (at your option) any later version. 24 * 25 * This program is distributed in the hope that it will be useful, 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 * GNU General Public License for more details. 29 * 30 * You should have received a copy of the GNU General Public License 31 * along with this program; if not, write to the Free Software 32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 33 * 34 */ 35 36 #include <linux/config.h> 37 #include <linux/module.h> 38 #include <linux/input.h> 39 #include <linux/pci.h> 40 #include <linux/sched.h> 41 #include <linux/init.h> 42 #include <linux/interrupt.h> 43 #include <linux/miscdevice.h> 44 #include <linux/poll.h> 45 #include <linux/delay.h> 46 #include <linux/wait.h> 47 #include <linux/acpi.h> 48 #include <linux/dmi.h> 49 #include <linux/err.h> 50 #include <linux/kfifo.h> 51 52 #include <asm/uaccess.h> 53 #include <asm/io.h> 54 #include <asm/system.h> 55 56 #include <linux/sonypi.h> 57 58 #define SONYPI_DRIVER_VERSION "1.26" 59 60 MODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); 61 MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver"); 62 MODULE_LICENSE("GPL"); 63 MODULE_VERSION(SONYPI_DRIVER_VERSION); 64 65 static int minor = -1; 66 module_param(minor, int, 0); 67 MODULE_PARM_DESC(minor, 68 "minor number of the misc device, default is -1 (automatic)"); 69 70 static int verbose; /* = 0 */ 71 module_param(verbose, int, 0644); 72 MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); 73 74 static int fnkeyinit; /* = 0 */ 75 module_param(fnkeyinit, int, 0444); 76 MODULE_PARM_DESC(fnkeyinit, 77 "set this if your Fn keys do not generate any event"); 78 79 static int camera; /* = 0 */ 80 module_param(camera, int, 0444); 81 MODULE_PARM_DESC(camera, 82 "set this if you have a MotionEye camera (PictureBook series)"); 83 84 static int compat; /* = 0 */ 85 module_param(compat, int, 0444); 86 MODULE_PARM_DESC(compat, 87 "set this if you want to enable backward compatibility mode"); 88 89 static unsigned long mask = 0xffffffff; 90 module_param(mask, ulong, 0644); 91 MODULE_PARM_DESC(mask, 92 "set this to the mask of event you want to enable (see doc)"); 93 94 static int useinput = 1; 95 module_param(useinput, int, 0444); 96 MODULE_PARM_DESC(useinput, 97 "set this if you would like sonypi to feed events to the input subsystem"); 98 99 #define SONYPI_DEVICE_MODEL_TYPE1 1 100 #define SONYPI_DEVICE_MODEL_TYPE2 2 101 102 /* type1 models use those */ 103 #define SONYPI_IRQ_PORT 0x8034 104 #define SONYPI_IRQ_SHIFT 22 105 #define SONYPI_BASE 0x50 106 #define SONYPI_G10A (SONYPI_BASE+0x14) 107 #define SONYPI_TYPE1_REGION_SIZE 0x08 108 #define SONYPI_TYPE1_EVTYPE_OFFSET 0x04 109 110 /* type2 series specifics */ 111 #define SONYPI_SIRQ 0x9b 112 #define SONYPI_SLOB 0x9c 113 #define SONYPI_SHIB 0x9d 114 #define SONYPI_TYPE2_REGION_SIZE 0x20 115 #define SONYPI_TYPE2_EVTYPE_OFFSET 0x12 116 117 /* battery / brightness addresses */ 118 #define SONYPI_BAT_FLAGS 0x81 119 #define SONYPI_LCD_LIGHT 0x96 120 #define SONYPI_BAT1_PCTRM 0xa0 121 #define SONYPI_BAT1_LEFT 0xa2 122 #define SONYPI_BAT1_MAXRT 0xa4 123 #define SONYPI_BAT2_PCTRM 0xa8 124 #define SONYPI_BAT2_LEFT 0xaa 125 #define SONYPI_BAT2_MAXRT 0xac 126 #define SONYPI_BAT1_MAXTK 0xb0 127 #define SONYPI_BAT1_FULL 0xb2 128 #define SONYPI_BAT2_MAXTK 0xb8 129 #define SONYPI_BAT2_FULL 0xba 130 131 /* FAN0 information (reverse engineered from ACPI tables) */ 132 #define SONYPI_FAN0_STATUS 0x93 133 #define SONYPI_TEMP_STATUS 0xC1 134 135 /* ioports used for brightness and type2 events */ 136 #define SONYPI_DATA_IOPORT 0x62 137 #define SONYPI_CST_IOPORT 0x66 138 139 /* The set of possible ioports */ 140 struct sonypi_ioport_list { 141 u16 port1; 142 u16 port2; 143 }; 144 145 static struct sonypi_ioport_list sonypi_type1_ioport_list[] = { 146 { 0x10c0, 0x10c4 }, /* looks like the default on C1Vx */ 147 { 0x1080, 0x1084 }, 148 { 0x1090, 0x1094 }, 149 { 0x10a0, 0x10a4 }, 150 { 0x10b0, 0x10b4 }, 151 { 0x0, 0x0 } 152 }; 153 154 static struct sonypi_ioport_list sonypi_type2_ioport_list[] = { 155 { 0x1080, 0x1084 }, 156 { 0x10a0, 0x10a4 }, 157 { 0x10c0, 0x10c4 }, 158 { 0x10e0, 0x10e4 }, 159 { 0x0, 0x0 } 160 }; 161 162 /* The set of possible interrupts */ 163 struct sonypi_irq_list { 164 u16 irq; 165 u16 bits; 166 }; 167 168 static struct sonypi_irq_list sonypi_type1_irq_list[] = { 169 { 11, 0x2 }, /* IRQ 11, GO22=0,GO23=1 in AML */ 170 { 10, 0x1 }, /* IRQ 10, GO22=1,GO23=0 in AML */ 171 { 5, 0x0 }, /* IRQ 5, GO22=0,GO23=0 in AML */ 172 { 0, 0x3 } /* no IRQ, GO22=1,GO23=1 in AML */ 173 }; 174 175 static struct sonypi_irq_list sonypi_type2_irq_list[] = { 176 { 11, 0x80 }, /* IRQ 11, 0x80 in SIRQ in AML */ 177 { 10, 0x40 }, /* IRQ 10, 0x40 in SIRQ in AML */ 178 { 9, 0x20 }, /* IRQ 9, 0x20 in SIRQ in AML */ 179 { 6, 0x10 }, /* IRQ 6, 0x10 in SIRQ in AML */ 180 { 0, 0x00 } /* no IRQ, 0x00 in SIRQ in AML */ 181 }; 182 183 #define SONYPI_CAMERA_BRIGHTNESS 0 184 #define SONYPI_CAMERA_CONTRAST 1 185 #define SONYPI_CAMERA_HUE 2 186 #define SONYPI_CAMERA_COLOR 3 187 #define SONYPI_CAMERA_SHARPNESS 4 188 189 #define SONYPI_CAMERA_PICTURE 5 190 #define SONYPI_CAMERA_EXPOSURE_MASK 0xC 191 #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3 192 #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30 193 #define SONYPI_CAMERA_MUTE_MASK 0x40 194 195 /* the rest don't need a loop until not 0xff */ 196 #define SONYPI_CAMERA_AGC 6 197 #define SONYPI_CAMERA_AGC_MASK 0x30 198 #define SONYPI_CAMERA_SHUTTER_MASK 0x7 199 200 #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7 201 #define SONYPI_CAMERA_CONTROL 0x10 202 203 #define SONYPI_CAMERA_STATUS 7 204 #define SONYPI_CAMERA_STATUS_READY 0x2 205 #define SONYPI_CAMERA_STATUS_POSITION 0x4 206 207 #define SONYPI_DIRECTION_BACKWARDS 0x4 208 209 #define SONYPI_CAMERA_REVISION 8 210 #define SONYPI_CAMERA_ROMVERSION 9 211 212 /* Event masks */ 213 #define SONYPI_JOGGER_MASK 0x00000001 214 #define SONYPI_CAPTURE_MASK 0x00000002 215 #define SONYPI_FNKEY_MASK 0x00000004 216 #define SONYPI_BLUETOOTH_MASK 0x00000008 217 #define SONYPI_PKEY_MASK 0x00000010 218 #define SONYPI_BACK_MASK 0x00000020 219 #define SONYPI_HELP_MASK 0x00000040 220 #define SONYPI_LID_MASK 0x00000080 221 #define SONYPI_ZOOM_MASK 0x00000100 222 #define SONYPI_THUMBPHRASE_MASK 0x00000200 223 #define SONYPI_MEYE_MASK 0x00000400 224 #define SONYPI_MEMORYSTICK_MASK 0x00000800 225 #define SONYPI_BATTERY_MASK 0x00001000 226 227 struct sonypi_event { 228 u8 data; 229 u8 event; 230 }; 231 232 /* The set of possible button release events */ 233 static struct sonypi_event sonypi_releaseev[] = { 234 { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED }, 235 { 0, 0 } 236 }; 237 238 /* The set of possible jogger events */ 239 static struct sonypi_event sonypi_joggerev[] = { 240 { 0x1f, SONYPI_EVENT_JOGDIAL_UP }, 241 { 0x01, SONYPI_EVENT_JOGDIAL_DOWN }, 242 { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED }, 243 { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED }, 244 { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP }, 245 { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN }, 246 { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED }, 247 { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED }, 248 { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP }, 249 { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN }, 250 { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED }, 251 { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, 252 { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED }, 253 { 0, 0 } 254 }; 255 256 /* The set of possible capture button events */ 257 static struct sonypi_event sonypi_captureev[] = { 258 { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED }, 259 { 0x07, SONYPI_EVENT_CAPTURE_PRESSED }, 260 { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, 261 { 0, 0 } 262 }; 263 264 /* The set of possible fnkeys events */ 265 static struct sonypi_event sonypi_fnkeyev[] = { 266 { 0x10, SONYPI_EVENT_FNKEY_ESC }, 267 { 0x11, SONYPI_EVENT_FNKEY_F1 }, 268 { 0x12, SONYPI_EVENT_FNKEY_F2 }, 269 { 0x13, SONYPI_EVENT_FNKEY_F3 }, 270 { 0x14, SONYPI_EVENT_FNKEY_F4 }, 271 { 0x15, SONYPI_EVENT_FNKEY_F5 }, 272 { 0x16, SONYPI_EVENT_FNKEY_F6 }, 273 { 0x17, SONYPI_EVENT_FNKEY_F7 }, 274 { 0x18, SONYPI_EVENT_FNKEY_F8 }, 275 { 0x19, SONYPI_EVENT_FNKEY_F9 }, 276 { 0x1a, SONYPI_EVENT_FNKEY_F10 }, 277 { 0x1b, SONYPI_EVENT_FNKEY_F11 }, 278 { 0x1c, SONYPI_EVENT_FNKEY_F12 }, 279 { 0x1f, SONYPI_EVENT_FNKEY_RELEASED }, 280 { 0x21, SONYPI_EVENT_FNKEY_1 }, 281 { 0x22, SONYPI_EVENT_FNKEY_2 }, 282 { 0x31, SONYPI_EVENT_FNKEY_D }, 283 { 0x32, SONYPI_EVENT_FNKEY_E }, 284 { 0x33, SONYPI_EVENT_FNKEY_F }, 285 { 0x34, SONYPI_EVENT_FNKEY_S }, 286 { 0x35, SONYPI_EVENT_FNKEY_B }, 287 { 0x36, SONYPI_EVENT_FNKEY_ONLY }, 288 { 0, 0 } 289 }; 290 291 /* The set of possible program key events */ 292 static struct sonypi_event sonypi_pkeyev[] = { 293 { 0x01, SONYPI_EVENT_PKEY_P1 }, 294 { 0x02, SONYPI_EVENT_PKEY_P2 }, 295 { 0x04, SONYPI_EVENT_PKEY_P3 }, 296 { 0x5c, SONYPI_EVENT_PKEY_P1 }, 297 { 0, 0 } 298 }; 299 300 /* The set of possible bluetooth events */ 301 static struct sonypi_event sonypi_blueev[] = { 302 { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED }, 303 { 0x59, SONYPI_EVENT_BLUETOOTH_ON }, 304 { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF }, 305 { 0, 0 } 306 }; 307 308 /* The set of possible back button events */ 309 static struct sonypi_event sonypi_backev[] = { 310 { 0x20, SONYPI_EVENT_BACK_PRESSED }, 311 { 0, 0 } 312 }; 313 314 /* The set of possible help button events */ 315 static struct sonypi_event sonypi_helpev[] = { 316 { 0x3b, SONYPI_EVENT_HELP_PRESSED }, 317 { 0, 0 } 318 }; 319 320 321 /* The set of possible lid events */ 322 static struct sonypi_event sonypi_lidev[] = { 323 { 0x51, SONYPI_EVENT_LID_CLOSED }, 324 { 0x50, SONYPI_EVENT_LID_OPENED }, 325 { 0, 0 } 326 }; 327 328 /* The set of possible zoom events */ 329 static struct sonypi_event sonypi_zoomev[] = { 330 { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, 331 { 0, 0 } 332 }; 333 334 /* The set of possible thumbphrase events */ 335 static struct sonypi_event sonypi_thumbphraseev[] = { 336 { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED }, 337 { 0, 0 } 338 }; 339 340 /* The set of possible motioneye camera events */ 341 static struct sonypi_event sonypi_meyeev[] = { 342 { 0x00, SONYPI_EVENT_MEYE_FACE }, 343 { 0x01, SONYPI_EVENT_MEYE_OPPOSITE }, 344 { 0, 0 } 345 }; 346 347 /* The set of possible memorystick events */ 348 static struct sonypi_event sonypi_memorystickev[] = { 349 { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT }, 350 { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT }, 351 { 0, 0 } 352 }; 353 354 /* The set of possible battery events */ 355 static struct sonypi_event sonypi_batteryev[] = { 356 { 0x20, SONYPI_EVENT_BATTERY_INSERT }, 357 { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, 358 { 0, 0 } 359 }; 360 361 static struct sonypi_eventtypes { 362 int model; 363 u8 data; 364 unsigned long mask; 365 struct sonypi_event * events; 366 } sonypi_eventtypes[] = { 367 { SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev }, 368 { SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, 369 { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev }, 370 { SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev }, 371 { SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev }, 372 { SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 373 { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 374 { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, 375 { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 376 { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, 377 378 { SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev }, 379 { SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev }, 380 { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, 381 { SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, 382 { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 383 { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 384 { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, 385 { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev }, 386 { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev }, 387 { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev }, 388 { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, 389 { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, 390 { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 391 { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 392 { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 393 394 { 0 } 395 }; 396 397 #define SONYPI_BUF_SIZE 128 398 399 /* The name of the devices for the input device drivers */ 400 #define SONYPI_JOG_INPUTNAME "Sony Vaio Jogdial" 401 #define SONYPI_KEY_INPUTNAME "Sony Vaio Keys" 402 403 /* Correspondance table between sonypi events and input layer events */ 404 static struct { 405 int sonypiev; 406 int inputev; 407 } sonypi_inputkeys[] = { 408 { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, 409 { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, 410 { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, 411 { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, 412 { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, 413 { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, 414 { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, 415 { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, 416 { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, 417 { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, 418 { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, 419 { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, 420 { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, 421 { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, 422 { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, 423 { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, 424 { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, 425 { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, 426 { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, 427 { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, 428 { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, 429 { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, 430 { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, 431 { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, 432 { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, 433 { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, 434 { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, 435 { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, 436 { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, 437 { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, 438 { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, 439 { 0, 0 }, 440 }; 441 442 struct sonypi_keypress { 443 struct input_dev *dev; 444 int key; 445 }; 446 447 static struct sonypi_device { 448 struct pci_dev *dev; 449 struct platform_device *pdev; 450 u16 irq; 451 u16 bits; 452 u16 ioport1; 453 u16 ioport2; 454 u16 region_size; 455 u16 evtype_offset; 456 int camera_power; 457 int bluetooth_power; 458 struct semaphore lock; 459 struct kfifo *fifo; 460 spinlock_t fifo_lock; 461 wait_queue_head_t fifo_proc_list; 462 struct fasync_struct *fifo_async; 463 int open_count; 464 int model; 465 struct input_dev input_jog_dev; 466 struct input_dev input_key_dev; 467 struct work_struct input_work; 468 struct kfifo *input_fifo; 469 spinlock_t input_fifo_lock; 470 } sonypi_device; 471 472 #define ITERATIONS_LONG 10000 473 #define ITERATIONS_SHORT 10 474 475 #define wait_on_command(quiet, command, iterations) { \ 476 unsigned int n = iterations; \ 477 while (--n && (command)) \ 478 udelay(1); \ 479 if (!n && (verbose || !quiet)) \ 480 printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \ 481 } 482 483 #ifdef CONFIG_ACPI 484 #define SONYPI_ACPI_ACTIVE (!acpi_disabled) 485 #else 486 #define SONYPI_ACPI_ACTIVE 0 487 #endif /* CONFIG_ACPI */ 488 489 static int sonypi_ec_write(u8 addr, u8 value) 490 { 491 #ifdef CONFIG_ACPI_EC 492 if (SONYPI_ACPI_ACTIVE) 493 return ec_write(addr, value); 494 #endif 495 wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG); 496 outb_p(0x81, SONYPI_CST_IOPORT); 497 wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); 498 outb_p(addr, SONYPI_DATA_IOPORT); 499 wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); 500 outb_p(value, SONYPI_DATA_IOPORT); 501 wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); 502 return 0; 503 } 504 505 static int sonypi_ec_read(u8 addr, u8 *value) 506 { 507 #ifdef CONFIG_ACPI_EC 508 if (SONYPI_ACPI_ACTIVE) 509 return ec_read(addr, value); 510 #endif 511 wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG); 512 outb_p(0x80, SONYPI_CST_IOPORT); 513 wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); 514 outb_p(addr, SONYPI_DATA_IOPORT); 515 wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG); 516 *value = inb_p(SONYPI_DATA_IOPORT); 517 return 0; 518 } 519 520 static int ec_read16(u8 addr, u16 *value) 521 { 522 u8 val_lb, val_hb; 523 if (sonypi_ec_read(addr, &val_lb)) 524 return -1; 525 if (sonypi_ec_read(addr + 1, &val_hb)) 526 return -1; 527 *value = val_lb | (val_hb << 8); 528 return 0; 529 } 530 531 /* Initializes the device - this comes from the AML code in the ACPI bios */ 532 static void sonypi_type1_srs(void) 533 { 534 u32 v; 535 536 pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v); 537 v = (v & 0xFFFF0000) | ((u32) sonypi_device.ioport1); 538 pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v); 539 540 pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v); 541 v = (v & 0xFFF0FFFF) | 542 (((u32) sonypi_device.ioport1 ^ sonypi_device.ioport2) << 16); 543 pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v); 544 545 v = inl(SONYPI_IRQ_PORT); 546 v &= ~(((u32) 0x3) << SONYPI_IRQ_SHIFT); 547 v |= (((u32) sonypi_device.bits) << SONYPI_IRQ_SHIFT); 548 outl(v, SONYPI_IRQ_PORT); 549 550 pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v); 551 v = (v & 0xFF1FFFFF) | 0x00C00000; 552 pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v); 553 } 554 555 static void sonypi_type2_srs(void) 556 { 557 if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8)) 558 printk(KERN_WARNING "ec_write failed\n"); 559 if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF)) 560 printk(KERN_WARNING "ec_write failed\n"); 561 if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits)) 562 printk(KERN_WARNING "ec_write failed\n"); 563 udelay(10); 564 } 565 566 /* Disables the device - this comes from the AML code in the ACPI bios */ 567 static void sonypi_type1_dis(void) 568 { 569 u32 v; 570 571 pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v); 572 v = v & 0xFF3FFFFF; 573 pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v); 574 575 v = inl(SONYPI_IRQ_PORT); 576 v |= (0x3 << SONYPI_IRQ_SHIFT); 577 outl(v, SONYPI_IRQ_PORT); 578 } 579 580 static void sonypi_type2_dis(void) 581 { 582 if (sonypi_ec_write(SONYPI_SHIB, 0)) 583 printk(KERN_WARNING "ec_write failed\n"); 584 if (sonypi_ec_write(SONYPI_SLOB, 0)) 585 printk(KERN_WARNING "ec_write failed\n"); 586 if (sonypi_ec_write(SONYPI_SIRQ, 0)) 587 printk(KERN_WARNING "ec_write failed\n"); 588 } 589 590 static u8 sonypi_call1(u8 dev) 591 { 592 u8 v1, v2; 593 594 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 595 outb(dev, sonypi_device.ioport2); 596 v1 = inb_p(sonypi_device.ioport2); 597 v2 = inb_p(sonypi_device.ioport1); 598 return v2; 599 } 600 601 static u8 sonypi_call2(u8 dev, u8 fn) 602 { 603 u8 v1; 604 605 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 606 outb(dev, sonypi_device.ioport2); 607 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 608 outb(fn, sonypi_device.ioport1); 609 v1 = inb_p(sonypi_device.ioport1); 610 return v1; 611 } 612 613 static u8 sonypi_call3(u8 dev, u8 fn, u8 v) 614 { 615 u8 v1; 616 617 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 618 outb(dev, sonypi_device.ioport2); 619 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 620 outb(fn, sonypi_device.ioport1); 621 wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG); 622 outb(v, sonypi_device.ioport1); 623 v1 = inb_p(sonypi_device.ioport1); 624 return v1; 625 } 626 627 #if 0 628 /* Get brightness, hue etc. Unreliable... */ 629 static u8 sonypi_read(u8 fn) 630 { 631 u8 v1, v2; 632 int n = 100; 633 634 while (n--) { 635 v1 = sonypi_call2(0x8f, fn); 636 v2 = sonypi_call2(0x8f, fn); 637 if (v1 == v2 && v1 != 0xff) 638 return v1; 639 } 640 return 0xff; 641 } 642 #endif 643 644 /* Set brightness, hue etc */ 645 static void sonypi_set(u8 fn, u8 v) 646 { 647 wait_on_command(0, sonypi_call3(0x90, fn, v), ITERATIONS_SHORT); 648 } 649 650 /* Tests if the camera is ready */ 651 static int sonypi_camera_ready(void) 652 { 653 u8 v; 654 655 v = sonypi_call2(0x8f, SONYPI_CAMERA_STATUS); 656 return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY)); 657 } 658 659 /* Turns the camera off */ 660 static void sonypi_camera_off(void) 661 { 662 sonypi_set(SONYPI_CAMERA_PICTURE, SONYPI_CAMERA_MUTE_MASK); 663 664 if (!sonypi_device.camera_power) 665 return; 666 667 sonypi_call2(0x91, 0); 668 sonypi_device.camera_power = 0; 669 } 670 671 /* Turns the camera on */ 672 static void sonypi_camera_on(void) 673 { 674 int i, j; 675 676 if (sonypi_device.camera_power) 677 return; 678 679 for (j = 5; j > 0; j--) { 680 681 while (sonypi_call2(0x91, 0x1)) 682 msleep(10); 683 sonypi_call1(0x93); 684 685 for (i = 400; i > 0; i--) { 686 if (sonypi_camera_ready()) 687 break; 688 msleep(10); 689 } 690 if (i) 691 break; 692 } 693 694 if (j == 0) { 695 printk(KERN_WARNING "sonypi: failed to power on camera\n"); 696 return; 697 } 698 699 sonypi_set(0x10, 0x5a); 700 sonypi_device.camera_power = 1; 701 } 702 703 /* sets the bluetooth subsystem power state */ 704 static void sonypi_setbluetoothpower(u8 state) 705 { 706 state = !!state; 707 708 if (sonypi_device.bluetooth_power == state) 709 return; 710 711 sonypi_call2(0x96, state); 712 sonypi_call1(0x82); 713 sonypi_device.bluetooth_power = state; 714 } 715 716 static void input_keyrelease(void *data) 717 { 718 struct sonypi_keypress kp; 719 720 while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, 721 sizeof(kp)) == sizeof(kp)) { 722 msleep(10); 723 input_report_key(kp.dev, kp.key, 0); 724 input_sync(kp.dev); 725 } 726 } 727 728 static void sonypi_report_input_event(u8 event) 729 { 730 struct input_dev *jog_dev = &sonypi_device.input_jog_dev; 731 struct input_dev *key_dev = &sonypi_device.input_key_dev; 732 struct sonypi_keypress kp = { NULL }; 733 int i; 734 735 switch (event) { 736 case SONYPI_EVENT_JOGDIAL_UP: 737 case SONYPI_EVENT_JOGDIAL_UP_PRESSED: 738 input_report_rel(jog_dev, REL_WHEEL, 1); 739 input_sync(jog_dev); 740 break; 741 742 case SONYPI_EVENT_JOGDIAL_DOWN: 743 case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: 744 input_report_rel(jog_dev, REL_WHEEL, -1); 745 input_sync(jog_dev); 746 break; 747 748 case SONYPI_EVENT_JOGDIAL_PRESSED: 749 kp.key = BTN_MIDDLE; 750 kp.dev = jog_dev; 751 break; 752 753 case SONYPI_EVENT_FNKEY_RELEASED: 754 /* Nothing, not all VAIOs generate this event */ 755 break; 756 757 default: 758 for (i = 0; sonypi_inputkeys[i].sonypiev; i++) 759 if (event == sonypi_inputkeys[i].sonypiev) { 760 kp.dev = key_dev; 761 kp.key = sonypi_inputkeys[i].inputev; 762 break; 763 } 764 break; 765 } 766 767 if (kp.dev) { 768 input_report_key(kp.dev, kp.key, 1); 769 input_sync(kp.dev); 770 kfifo_put(sonypi_device.input_fifo, 771 (unsigned char *)&kp, sizeof(kp)); 772 schedule_work(&sonypi_device.input_work); 773 } 774 } 775 776 /* Interrupt handler: some event is available */ 777 static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) 778 { 779 u8 v1, v2, event = 0; 780 int i, j; 781 782 v1 = inb_p(sonypi_device.ioport1); 783 v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset); 784 785 for (i = 0; sonypi_eventtypes[i].model; i++) { 786 if (sonypi_device.model != sonypi_eventtypes[i].model) 787 continue; 788 if ((v2 & sonypi_eventtypes[i].data) != 789 sonypi_eventtypes[i].data) 790 continue; 791 if (!(mask & sonypi_eventtypes[i].mask)) 792 continue; 793 for (j = 0; sonypi_eventtypes[i].events[j].event; j++) { 794 if (v1 == sonypi_eventtypes[i].events[j].data) { 795 event = sonypi_eventtypes[i].events[j].event; 796 goto found; 797 } 798 } 799 } 800 801 if (verbose) 802 printk(KERN_WARNING 803 "sonypi: unknown event port1=0x%02x,port2=0x%02x\n", 804 v1, v2); 805 /* We need to return IRQ_HANDLED here because there *are* 806 * events belonging to the sonypi device we don't know about, 807 * but we still don't want those to pollute the logs... */ 808 return IRQ_HANDLED; 809 810 found: 811 if (verbose > 1) 812 printk(KERN_INFO 813 "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); 814 815 if (useinput) 816 sonypi_report_input_event(event); 817 818 kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); 819 kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); 820 wake_up_interruptible(&sonypi_device.fifo_proc_list); 821 822 return IRQ_HANDLED; 823 } 824 825 /* External camera command (exported to the motion eye v4l driver) */ 826 int sonypi_camera_command(int command, u8 value) 827 { 828 if (!camera) 829 return -EIO; 830 831 down(&sonypi_device.lock); 832 833 switch (command) { 834 case SONYPI_COMMAND_SETCAMERA: 835 if (value) 836 sonypi_camera_on(); 837 else 838 sonypi_camera_off(); 839 break; 840 case SONYPI_COMMAND_SETCAMERABRIGHTNESS: 841 sonypi_set(SONYPI_CAMERA_BRIGHTNESS, value); 842 break; 843 case SONYPI_COMMAND_SETCAMERACONTRAST: 844 sonypi_set(SONYPI_CAMERA_CONTRAST, value); 845 break; 846 case SONYPI_COMMAND_SETCAMERAHUE: 847 sonypi_set(SONYPI_CAMERA_HUE, value); 848 break; 849 case SONYPI_COMMAND_SETCAMERACOLOR: 850 sonypi_set(SONYPI_CAMERA_COLOR, value); 851 break; 852 case SONYPI_COMMAND_SETCAMERASHARPNESS: 853 sonypi_set(SONYPI_CAMERA_SHARPNESS, value); 854 break; 855 case SONYPI_COMMAND_SETCAMERAPICTURE: 856 sonypi_set(SONYPI_CAMERA_PICTURE, value); 857 break; 858 case SONYPI_COMMAND_SETCAMERAAGC: 859 sonypi_set(SONYPI_CAMERA_AGC, value); 860 break; 861 default: 862 printk(KERN_ERR "sonypi: sonypi_camera_command invalid: %d\n", 863 command); 864 break; 865 } 866 up(&sonypi_device.lock); 867 return 0; 868 } 869 870 EXPORT_SYMBOL(sonypi_camera_command); 871 872 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 873 { 874 int retval; 875 876 retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async); 877 if (retval < 0) 878 return retval; 879 return 0; 880 } 881 882 static int sonypi_misc_release(struct inode *inode, struct file *file) 883 { 884 sonypi_misc_fasync(-1, file, 0); 885 down(&sonypi_device.lock); 886 sonypi_device.open_count--; 887 up(&sonypi_device.lock); 888 return 0; 889 } 890 891 static int sonypi_misc_open(struct inode *inode, struct file *file) 892 { 893 down(&sonypi_device.lock); 894 /* Flush input queue on first open */ 895 if (!sonypi_device.open_count) 896 kfifo_reset(sonypi_device.fifo); 897 sonypi_device.open_count++; 898 up(&sonypi_device.lock); 899 return 0; 900 } 901 902 static ssize_t sonypi_misc_read(struct file *file, char __user *buf, 903 size_t count, loff_t *pos) 904 { 905 ssize_t ret; 906 unsigned char c; 907 908 if ((kfifo_len(sonypi_device.fifo) == 0) && 909 (file->f_flags & O_NONBLOCK)) 910 return -EAGAIN; 911 912 ret = wait_event_interruptible(sonypi_device.fifo_proc_list, 913 kfifo_len(sonypi_device.fifo) != 0); 914 if (ret) 915 return ret; 916 917 while (ret < count && 918 (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { 919 if (put_user(c, buf++)) 920 return -EFAULT; 921 ret++; 922 } 923 924 if (ret > 0) { 925 struct inode *inode = file->f_dentry->d_inode; 926 inode->i_atime = current_fs_time(inode->i_sb); 927 } 928 929 return ret; 930 } 931 932 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) 933 { 934 poll_wait(file, &sonypi_device.fifo_proc_list, wait); 935 if (kfifo_len(sonypi_device.fifo)) 936 return POLLIN | POLLRDNORM; 937 return 0; 938 } 939 940 static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, 941 unsigned int cmd, unsigned long arg) 942 { 943 int ret = 0; 944 void __user *argp = (void __user *)arg; 945 u8 val8; 946 u16 val16; 947 948 down(&sonypi_device.lock); 949 switch (cmd) { 950 case SONYPI_IOCGBRT: 951 if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) { 952 ret = -EIO; 953 break; 954 } 955 if (copy_to_user(argp, &val8, sizeof(val8))) 956 ret = -EFAULT; 957 break; 958 case SONYPI_IOCSBRT: 959 if (copy_from_user(&val8, argp, sizeof(val8))) { 960 ret = -EFAULT; 961 break; 962 } 963 if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8)) 964 ret = -EIO; 965 break; 966 case SONYPI_IOCGBAT1CAP: 967 if (ec_read16(SONYPI_BAT1_FULL, &val16)) { 968 ret = -EIO; 969 break; 970 } 971 if (copy_to_user(argp, &val16, sizeof(val16))) 972 ret = -EFAULT; 973 break; 974 case SONYPI_IOCGBAT1REM: 975 if (ec_read16(SONYPI_BAT1_LEFT, &val16)) { 976 ret = -EIO; 977 break; 978 } 979 if (copy_to_user(argp, &val16, sizeof(val16))) 980 ret = -EFAULT; 981 break; 982 case SONYPI_IOCGBAT2CAP: 983 if (ec_read16(SONYPI_BAT2_FULL, &val16)) { 984 ret = -EIO; 985 break; 986 } 987 if (copy_to_user(argp, &val16, sizeof(val16))) 988 ret = -EFAULT; 989 break; 990 case SONYPI_IOCGBAT2REM: 991 if (ec_read16(SONYPI_BAT2_LEFT, &val16)) { 992 ret = -EIO; 993 break; 994 } 995 if (copy_to_user(argp, &val16, sizeof(val16))) 996 ret = -EFAULT; 997 break; 998 case SONYPI_IOCGBATFLAGS: 999 if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) { 1000 ret = -EIO; 1001 break; 1002 } 1003 val8 &= 0x07; 1004 if (copy_to_user(argp, &val8, sizeof(val8))) 1005 ret = -EFAULT; 1006 break; 1007 case SONYPI_IOCGBLUE: 1008 val8 = sonypi_device.bluetooth_power; 1009 if (copy_to_user(argp, &val8, sizeof(val8))) 1010 ret = -EFAULT; 1011 break; 1012 case SONYPI_IOCSBLUE: 1013 if (copy_from_user(&val8, argp, sizeof(val8))) { 1014 ret = -EFAULT; 1015 break; 1016 } 1017 sonypi_setbluetoothpower(val8); 1018 break; 1019 /* FAN Controls */ 1020 case SONYPI_IOCGFAN: 1021 if (sonypi_ec_read(SONYPI_FAN0_STATUS, &val8)) { 1022 ret = -EIO; 1023 break; 1024 } 1025 if (copy_to_user(argp, &val8, sizeof(val8))) 1026 ret = -EFAULT; 1027 break; 1028 case SONYPI_IOCSFAN: 1029 if (copy_from_user(&val8, argp, sizeof(val8))) { 1030 ret = -EFAULT; 1031 break; 1032 } 1033 if (sonypi_ec_write(SONYPI_FAN0_STATUS, val8)) 1034 ret = -EIO; 1035 break; 1036 /* GET Temperature (useful under APM) */ 1037 case SONYPI_IOCGTEMP: 1038 if (sonypi_ec_read(SONYPI_TEMP_STATUS, &val8)) { 1039 ret = -EIO; 1040 break; 1041 } 1042 if (copy_to_user(argp, &val8, sizeof(val8))) 1043 ret = -EFAULT; 1044 break; 1045 default: 1046 ret = -EINVAL; 1047 } 1048 up(&sonypi_device.lock); 1049 return ret; 1050 } 1051 1052 static struct file_operations sonypi_misc_fops = { 1053 .owner = THIS_MODULE, 1054 .read = sonypi_misc_read, 1055 .poll = sonypi_misc_poll, 1056 .open = sonypi_misc_open, 1057 .release = sonypi_misc_release, 1058 .fasync = sonypi_misc_fasync, 1059 .ioctl = sonypi_misc_ioctl, 1060 }; 1061 1062 static struct miscdevice sonypi_misc_device = { 1063 .minor = MISC_DYNAMIC_MINOR, 1064 .name = "sonypi", 1065 .fops = &sonypi_misc_fops, 1066 }; 1067 1068 static void sonypi_enable(unsigned int camera_on) 1069 { 1070 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) 1071 sonypi_type2_srs(); 1072 else 1073 sonypi_type1_srs(); 1074 1075 sonypi_call1(0x82); 1076 sonypi_call2(0x81, 0xff); 1077 sonypi_call1(compat ? 0x92 : 0x82); 1078 1079 /* Enable ACPI mode to get Fn key events */ 1080 if (!SONYPI_ACPI_ACTIVE && fnkeyinit) 1081 outb(0xf0, 0xb2); 1082 1083 if (camera && camera_on) 1084 sonypi_camera_on(); 1085 } 1086 1087 static int sonypi_disable(void) 1088 { 1089 sonypi_call2(0x81, 0); /* make sure we don't get any more events */ 1090 if (camera) 1091 sonypi_camera_off(); 1092 1093 /* disable ACPI mode */ 1094 if (!SONYPI_ACPI_ACTIVE && fnkeyinit) 1095 outb(0xf1, 0xb2); 1096 1097 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) 1098 sonypi_type2_dis(); 1099 else 1100 sonypi_type1_dis(); 1101 return 0; 1102 } 1103 1104 #ifdef CONFIG_PM 1105 static int old_camera_power; 1106 1107 static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level) 1108 { 1109 if (level == SUSPEND_DISABLE) { 1110 old_camera_power = sonypi_device.camera_power; 1111 sonypi_disable(); 1112 } 1113 return 0; 1114 } 1115 1116 static int sonypi_resume(struct device *dev, u32 level) 1117 { 1118 if (level == RESUME_ENABLE) 1119 sonypi_enable(old_camera_power); 1120 return 0; 1121 } 1122 #endif 1123 1124 static void sonypi_shutdown(struct device *dev) 1125 { 1126 sonypi_disable(); 1127 } 1128 1129 static struct device_driver sonypi_driver = { 1130 .name = "sonypi", 1131 .bus = &platform_bus_type, 1132 #ifdef CONFIG_PM 1133 .suspend = sonypi_suspend, 1134 .resume = sonypi_resume, 1135 #endif 1136 .shutdown = sonypi_shutdown, 1137 }; 1138 1139 static int __devinit sonypi_probe(void) 1140 { 1141 int i, ret; 1142 struct sonypi_ioport_list *ioport_list; 1143 struct sonypi_irq_list *irq_list; 1144 struct pci_dev *pcidev; 1145 1146 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1147 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 1148 1149 sonypi_device.dev = pcidev; 1150 sonypi_device.model = pcidev ? 1151 SONYPI_DEVICE_MODEL_TYPE1 : SONYPI_DEVICE_MODEL_TYPE2; 1152 1153 spin_lock_init(&sonypi_device.fifo_lock); 1154 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, 1155 &sonypi_device.fifo_lock); 1156 if (IS_ERR(sonypi_device.fifo)) { 1157 printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); 1158 ret = PTR_ERR(sonypi_device.fifo); 1159 goto out_fifo; 1160 } 1161 1162 init_waitqueue_head(&sonypi_device.fifo_proc_list); 1163 init_MUTEX(&sonypi_device.lock); 1164 sonypi_device.bluetooth_power = -1; 1165 1166 if (pcidev && pci_enable_device(pcidev)) { 1167 printk(KERN_ERR "sonypi: pci_enable_device failed\n"); 1168 ret = -EIO; 1169 goto out_pcienable; 1170 } 1171 1172 if (minor != -1) 1173 sonypi_misc_device.minor = minor; 1174 if ((ret = misc_register(&sonypi_misc_device))) { 1175 printk(KERN_ERR "sonypi: misc_register failed\n"); 1176 goto out_miscreg; 1177 } 1178 1179 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { 1180 ioport_list = sonypi_type2_ioport_list; 1181 sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; 1182 sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; 1183 irq_list = sonypi_type2_irq_list; 1184 } else { 1185 ioport_list = sonypi_type1_ioport_list; 1186 sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; 1187 sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; 1188 irq_list = sonypi_type1_irq_list; 1189 } 1190 1191 for (i = 0; ioport_list[i].port1; i++) { 1192 if (request_region(ioport_list[i].port1, 1193 sonypi_device.region_size, 1194 "Sony Programable I/O Device")) { 1195 /* get the ioport */ 1196 sonypi_device.ioport1 = ioport_list[i].port1; 1197 sonypi_device.ioport2 = ioport_list[i].port2; 1198 break; 1199 } 1200 } 1201 if (!sonypi_device.ioport1) { 1202 printk(KERN_ERR "sonypi: request_region failed\n"); 1203 ret = -ENODEV; 1204 goto out_reqreg; 1205 } 1206 1207 for (i = 0; irq_list[i].irq; i++) { 1208 1209 sonypi_device.irq = irq_list[i].irq; 1210 sonypi_device.bits = irq_list[i].bits; 1211 1212 if (!request_irq(sonypi_device.irq, sonypi_irq, 1213 SA_SHIRQ, "sonypi", sonypi_irq)) 1214 break; 1215 } 1216 1217 if (!irq_list[i].irq) { 1218 printk(KERN_ERR "sonypi: request_irq failed\n"); 1219 ret = -ENODEV; 1220 goto out_reqirq; 1221 } 1222 1223 if (useinput) { 1224 /* Initialize the Input Drivers: jogdial */ 1225 int i; 1226 sonypi_device.input_jog_dev.evbit[0] = 1227 BIT(EV_KEY) | BIT(EV_REL); 1228 sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = 1229 BIT(BTN_MIDDLE); 1230 sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); 1231 sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; 1232 sonypi_device.input_jog_dev.id.bustype = BUS_ISA; 1233 sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; 1234 1235 input_register_device(&sonypi_device.input_jog_dev); 1236 printk(KERN_INFO "%s input method installed.\n", 1237 sonypi_device.input_jog_dev.name); 1238 1239 /* Initialize the Input Drivers: special keys */ 1240 sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY); 1241 for (i = 0; sonypi_inputkeys[i].sonypiev; i++) 1242 if (sonypi_inputkeys[i].inputev) 1243 set_bit(sonypi_inputkeys[i].inputev, 1244 sonypi_device.input_key_dev.keybit); 1245 sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; 1246 sonypi_device.input_key_dev.id.bustype = BUS_ISA; 1247 sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; 1248 1249 input_register_device(&sonypi_device.input_key_dev); 1250 printk(KERN_INFO "%s input method installed.\n", 1251 sonypi_device.input_key_dev.name); 1252 1253 spin_lock_init(&sonypi_device.input_fifo_lock); 1254 sonypi_device.input_fifo = 1255 kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, 1256 &sonypi_device.input_fifo_lock); 1257 if (IS_ERR(sonypi_device.input_fifo)) { 1258 printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); 1259 ret = PTR_ERR(sonypi_device.input_fifo); 1260 goto out_infifo; 1261 } 1262 1263 INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL); 1264 } 1265 1266 sonypi_device.pdev = platform_device_register_simple("sonypi", -1, 1267 NULL, 0); 1268 if (IS_ERR(sonypi_device.pdev)) { 1269 ret = PTR_ERR(sonypi_device.pdev); 1270 goto out_platformdev; 1271 } 1272 1273 sonypi_enable(0); 1274 1275 printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver" 1276 "v%s.\n", SONYPI_DRIVER_VERSION); 1277 printk(KERN_INFO "sonypi: detected %s model, " 1278 "verbose = %d, fnkeyinit = %s, camera = %s, " 1279 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", 1280 (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? 1281 "type1" : "type2", 1282 verbose, 1283 fnkeyinit ? "on" : "off", 1284 camera ? "on" : "off", 1285 compat ? "on" : "off", 1286 mask, 1287 useinput ? "on" : "off", 1288 SONYPI_ACPI_ACTIVE ? "on" : "off"); 1289 printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", 1290 sonypi_device.irq, 1291 sonypi_device.ioport1, sonypi_device.ioport2); 1292 1293 if (minor == -1) 1294 printk(KERN_INFO "sonypi: device allocated minor is %d\n", 1295 sonypi_misc_device.minor); 1296 1297 return 0; 1298 1299 out_platformdev: 1300 kfifo_free(sonypi_device.input_fifo); 1301 out_infifo: 1302 input_unregister_device(&sonypi_device.input_key_dev); 1303 input_unregister_device(&sonypi_device.input_jog_dev); 1304 free_irq(sonypi_device.irq, sonypi_irq); 1305 out_reqirq: 1306 release_region(sonypi_device.ioport1, sonypi_device.region_size); 1307 out_reqreg: 1308 misc_deregister(&sonypi_misc_device); 1309 out_miscreg: 1310 if (pcidev) 1311 pci_disable_device(pcidev); 1312 out_pcienable: 1313 kfifo_free(sonypi_device.fifo); 1314 out_fifo: 1315 pci_dev_put(sonypi_device.dev); 1316 return ret; 1317 } 1318 1319 static void __devexit sonypi_remove(void) 1320 { 1321 sonypi_disable(); 1322 1323 synchronize_sched(); /* Allow sonypi interrupt to complete. */ 1324 flush_scheduled_work(); 1325 1326 platform_device_unregister(sonypi_device.pdev); 1327 1328 if (useinput) { 1329 input_unregister_device(&sonypi_device.input_key_dev); 1330 input_unregister_device(&sonypi_device.input_jog_dev); 1331 kfifo_free(sonypi_device.input_fifo); 1332 } 1333 1334 free_irq(sonypi_device.irq, sonypi_irq); 1335 release_region(sonypi_device.ioport1, sonypi_device.region_size); 1336 misc_deregister(&sonypi_misc_device); 1337 if (sonypi_device.dev) 1338 pci_disable_device(sonypi_device.dev); 1339 kfifo_free(sonypi_device.fifo); 1340 pci_dev_put(sonypi_device.dev); 1341 printk(KERN_INFO "sonypi: removed.\n"); 1342 } 1343 1344 static struct dmi_system_id __initdata sonypi_dmi_table[] = { 1345 { 1346 .ident = "Sony Vaio", 1347 .matches = { 1348 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 1349 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"), 1350 }, 1351 }, 1352 { 1353 .ident = "Sony Vaio", 1354 .matches = { 1355 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 1356 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"), 1357 }, 1358 }, 1359 { } 1360 }; 1361 1362 static int __init sonypi_init(void) 1363 { 1364 int ret; 1365 1366 if (!dmi_check_system(sonypi_dmi_table)) 1367 return -ENODEV; 1368 1369 ret = driver_register(&sonypi_driver); 1370 if (ret) 1371 return ret; 1372 1373 ret = sonypi_probe(); 1374 if (ret) 1375 driver_unregister(&sonypi_driver); 1376 1377 return ret; 1378 } 1379 1380 static void __exit sonypi_exit(void) 1381 { 1382 driver_unregister(&sonypi_driver); 1383 sonypi_remove(); 1384 } 1385 1386 module_init(sonypi_init); 1387 module_exit(sonypi_exit); 1388