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