1/* 2 * toshiba_acpi.c - Toshiba Laptop ACPI Extras 3 * 4 * 5 * Copyright (C) 2002-2004 John Belmonte 6 * Copyright (C) 2008 Philip Langdale 7 * Copyright (C) 2010 Pierre Ducroquet 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 * 24 * The devolpment page for this driver is located at 25 * http://memebeam.org/toys/ToshibaAcpiDriver. 26 * 27 * Credits: 28 * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse 29 * engineering the Windows drivers 30 * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 31 * Rob Miller - TV out and hotkeys help 32 * 33 * 34 * TODO 35 * 36 */ 37 38#define TOSHIBA_ACPI_VERSION "0.19" 39#define PROC_INTERFACE_VERSION 1 40 41#include <linux/kernel.h> 42#include <linux/module.h> 43#include <linux/init.h> 44#include <linux/types.h> 45#include <linux/proc_fs.h> 46#include <linux/seq_file.h> 47#include <linux/backlight.h> 48#include <linux/platform_device.h> 49#include <linux/rfkill.h> 50#include <linux/input.h> 51#include <linux/leds.h> 52#include <linux/slab.h> 53 54#include <asm/uaccess.h> 55 56#include <acpi/acpi_drivers.h> 57 58MODULE_AUTHOR("John Belmonte"); 59MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); 60MODULE_LICENSE("GPL"); 61 62#define MY_LOGPREFIX "toshiba_acpi: " 63#define MY_ERR KERN_ERR MY_LOGPREFIX 64#define MY_NOTICE KERN_NOTICE MY_LOGPREFIX 65#define MY_INFO KERN_INFO MY_LOGPREFIX 66 67/* Toshiba ACPI method paths */ 68#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" 69#define TOSH_INTERFACE_1 "\\_SB_.VALD" 70#define TOSH_INTERFACE_2 "\\_SB_.VALZ" 71#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" 72#define GHCI_METHOD ".GHCI" 73 74/* Toshiba HCI interface definitions 75 * 76 * HCI is Toshiba's "Hardware Control Interface" which is supposed to 77 * be uniform across all their models. Ideally we would just call 78 * dedicated ACPI methods instead of using this primitive interface. 79 * However the ACPI methods seem to be incomplete in some areas (for 80 * example they allow setting, but not reading, the LCD brightness value), 81 * so this is still useful. 82 */ 83 84#define HCI_WORDS 6 85 86/* operations */ 87#define HCI_SET 0xff00 88#define HCI_GET 0xfe00 89 90/* return codes */ 91#define HCI_SUCCESS 0x0000 92#define HCI_FAILURE 0x1000 93#define HCI_NOT_SUPPORTED 0x8000 94#define HCI_EMPTY 0x8c00 95 96/* registers */ 97#define HCI_FAN 0x0004 98#define HCI_SYSTEM_EVENT 0x0016 99#define HCI_VIDEO_OUT 0x001c 100#define HCI_HOTKEY_EVENT 0x001e 101#define HCI_LCD_BRIGHTNESS 0x002a 102#define HCI_WIRELESS 0x0056 103 104/* field definitions */ 105#define HCI_LCD_BRIGHTNESS_BITS 3 106#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) 107#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) 108#define HCI_VIDEO_OUT_LCD 0x1 109#define HCI_VIDEO_OUT_CRT 0x2 110#define HCI_VIDEO_OUT_TV 0x4 111#define HCI_WIRELESS_KILL_SWITCH 0x01 112#define HCI_WIRELESS_BT_PRESENT 0x0f 113#define HCI_WIRELESS_BT_ATTACH 0x40 114#define HCI_WIRELESS_BT_POWER 0x80 115 116static const struct acpi_device_id toshiba_device_ids[] = { 117 {"TOS6200", 0}, 118 {"TOS6208", 0}, 119 {"TOS1900", 0}, 120 {"", 0}, 121}; 122MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); 123 124struct key_entry { 125 char type; 126 u16 code; 127 u16 keycode; 128}; 129 130enum {KE_KEY, KE_END}; 131 132static struct key_entry toshiba_acpi_keymap[] = { 133 {KE_KEY, 0x101, KEY_MUTE}, 134 {KE_KEY, 0x102, KEY_ZOOMOUT}, 135 {KE_KEY, 0x103, KEY_ZOOMIN}, 136 {KE_KEY, 0x13b, KEY_COFFEE}, 137 {KE_KEY, 0x13c, KEY_BATTERY}, 138 {KE_KEY, 0x13d, KEY_SLEEP}, 139 {KE_KEY, 0x13e, KEY_SUSPEND}, 140 {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE}, 141 {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN}, 142 {KE_KEY, 0x141, KEY_BRIGHTNESSUP}, 143 {KE_KEY, 0x142, KEY_WLAN}, 144 {KE_KEY, 0x143, KEY_PROG1}, 145 {KE_KEY, 0xb05, KEY_PROG2}, 146 {KE_KEY, 0xb06, KEY_WWW}, 147 {KE_KEY, 0xb07, KEY_MAIL}, 148 {KE_KEY, 0xb30, KEY_STOP}, 149 {KE_KEY, 0xb31, KEY_PREVIOUSSONG}, 150 {KE_KEY, 0xb32, KEY_NEXTSONG}, 151 {KE_KEY, 0xb33, KEY_PLAYPAUSE}, 152 {KE_KEY, 0xb5a, KEY_MEDIA}, 153 {KE_END, 0, 0}, 154}; 155 156/* utility 157 */ 158 159static __inline__ void _set_bit(u32 * word, u32 mask, int value) 160{ 161 *word = (*word & ~mask) | (mask * value); 162} 163 164/* acpi interface wrappers 165 */ 166 167static int is_valid_acpi_path(const char *methodName) 168{ 169 acpi_handle handle; 170 acpi_status status; 171 172 status = acpi_get_handle(NULL, (char *)methodName, &handle); 173 return !ACPI_FAILURE(status); 174} 175 176static int write_acpi_int(const char *methodName, int val) 177{ 178 struct acpi_object_list params; 179 union acpi_object in_objs[1]; 180 acpi_status status; 181 182 params.count = ARRAY_SIZE(in_objs); 183 params.pointer = in_objs; 184 in_objs[0].type = ACPI_TYPE_INTEGER; 185 in_objs[0].integer.value = val; 186 187 status = acpi_evaluate_object(NULL, (char *)methodName, ¶ms, NULL); 188 return (status == AE_OK); 189} 190 191 192static const char *method_hci /*= 0*/ ; 193 194/* Perform a raw HCI call. Here we don't care about input or output buffer 195 * format. 196 */ 197static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) 198{ 199 struct acpi_object_list params; 200 union acpi_object in_objs[HCI_WORDS]; 201 struct acpi_buffer results; 202 union acpi_object out_objs[HCI_WORDS + 1]; 203 acpi_status status; 204 int i; 205 206 params.count = HCI_WORDS; 207 params.pointer = in_objs; 208 for (i = 0; i < HCI_WORDS; ++i) { 209 in_objs[i].type = ACPI_TYPE_INTEGER; 210 in_objs[i].integer.value = in[i]; 211 } 212 213 results.length = sizeof(out_objs); 214 results.pointer = out_objs; 215 216 status = acpi_evaluate_object(NULL, (char *)method_hci, ¶ms, 217 &results); 218 if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { 219 for (i = 0; i < out_objs->package.count; ++i) { 220 out[i] = out_objs->package.elements[i].integer.value; 221 } 222 } 223 224 return status; 225} 226 227/* common hci tasks (get or set one or two value) 228 * 229 * In addition to the ACPI status, the HCI system returns a result which 230 * may be useful (such as "not supported"). 231 */ 232 233static acpi_status hci_write1(u32 reg, u32 in1, u32 * result) 234{ 235 u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 }; 236 u32 out[HCI_WORDS]; 237 acpi_status status = hci_raw(in, out); 238 *result = (status == AE_OK) ? out[0] : HCI_FAILURE; 239 return status; 240} 241 242static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) 243{ 244 u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; 245 u32 out[HCI_WORDS]; 246 acpi_status status = hci_raw(in, out); 247 *out1 = out[2]; 248 *result = (status == AE_OK) ? out[0] : HCI_FAILURE; 249 return status; 250} 251 252static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result) 253{ 254 u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 }; 255 u32 out[HCI_WORDS]; 256 acpi_status status = hci_raw(in, out); 257 *result = (status == AE_OK) ? out[0] : HCI_FAILURE; 258 return status; 259} 260 261static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result) 262{ 263 u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 }; 264 u32 out[HCI_WORDS]; 265 acpi_status status = hci_raw(in, out); 266 *out1 = out[2]; 267 *out2 = out[3]; 268 *result = (status == AE_OK) ? out[0] : HCI_FAILURE; 269 return status; 270} 271 272struct toshiba_acpi_dev { 273 struct platform_device *p_dev; 274 struct rfkill *bt_rfk; 275 struct input_dev *hotkey_dev; 276 int illumination_installed; 277 acpi_handle handle; 278 279 const char *bt_name; 280 281 struct mutex mutex; 282}; 283 284/* Illumination support */ 285static int toshiba_illumination_available(void) 286{ 287 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 288 u32 out[HCI_WORDS]; 289 acpi_status status; 290 291 in[0] = 0xf100; 292 status = hci_raw(in, out); 293 if (ACPI_FAILURE(status)) { 294 printk(MY_INFO "Illumination device not available\n"); 295 return 0; 296 } 297 in[0] = 0xf400; 298 status = hci_raw(in, out); 299 return 1; 300} 301 302static void toshiba_illumination_set(struct led_classdev *cdev, 303 enum led_brightness brightness) 304{ 305 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 306 u32 out[HCI_WORDS]; 307 acpi_status status; 308 309 /* First request : initialize communication. */ 310 in[0] = 0xf100; 311 status = hci_raw(in, out); 312 if (ACPI_FAILURE(status)) { 313 printk(MY_INFO "Illumination device not available\n"); 314 return; 315 } 316 317 if (brightness) { 318 /* Switch the illumination on */ 319 in[0] = 0xf400; 320 in[1] = 0x14e; 321 in[2] = 1; 322 status = hci_raw(in, out); 323 if (ACPI_FAILURE(status)) { 324 printk(MY_INFO "ACPI call for illumination failed.\n"); 325 return; 326 } 327 } else { 328 /* Switch the illumination off */ 329 in[0] = 0xf400; 330 in[1] = 0x14e; 331 in[2] = 0; 332 status = hci_raw(in, out); 333 if (ACPI_FAILURE(status)) { 334 printk(MY_INFO "ACPI call for illumination failed.\n"); 335 return; 336 } 337 } 338 339 /* Last request : close communication. */ 340 in[0] = 0xf200; 341 in[1] = 0; 342 in[2] = 0; 343 hci_raw(in, out); 344} 345 346static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) 347{ 348 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 349 u32 out[HCI_WORDS]; 350 acpi_status status; 351 enum led_brightness result; 352 353 /*��First request : initialize communication. */ 354 in[0] = 0xf100; 355 status = hci_raw(in, out); 356 if (ACPI_FAILURE(status)) { 357 printk(MY_INFO "Illumination device not available\n"); 358 return LED_OFF; 359 } 360 361 /* Check the illumination */ 362 in[0] = 0xf300; 363 in[1] = 0x14e; 364 status = hci_raw(in, out); 365 if (ACPI_FAILURE(status)) { 366 printk(MY_INFO "ACPI call for illumination failed.\n"); 367 return LED_OFF; 368 } 369 370 result = out[2] ? LED_FULL : LED_OFF; 371 372 /* Last request : close communication. */ 373 in[0] = 0xf200; 374 in[1] = 0; 375 in[2] = 0; 376 hci_raw(in, out); 377 378 return result; 379} 380 381static struct led_classdev toshiba_led = { 382 .name = "toshiba::illumination", 383 .max_brightness = 1, 384 .brightness_set = toshiba_illumination_set, 385 .brightness_get = toshiba_illumination_get, 386}; 387 388static struct toshiba_acpi_dev toshiba_acpi = { 389 .bt_name = "Toshiba Bluetooth", 390}; 391 392/* Bluetooth rfkill handlers */ 393 394static u32 hci_get_bt_present(bool *present) 395{ 396 u32 hci_result; 397 u32 value, value2; 398 399 value = 0; 400 value2 = 0; 401 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result); 402 if (hci_result == HCI_SUCCESS) 403 *present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false; 404 405 return hci_result; 406} 407 408static u32 hci_get_radio_state(bool *radio_state) 409{ 410 u32 hci_result; 411 u32 value, value2; 412 413 value = 0; 414 value2 = 0x0001; 415 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result); 416 417 *radio_state = value & HCI_WIRELESS_KILL_SWITCH; 418 return hci_result; 419} 420 421static int bt_rfkill_set_block(void *data, bool blocked) 422{ 423 struct toshiba_acpi_dev *dev = data; 424 u32 result1, result2; 425 u32 value; 426 int err; 427 bool radio_state; 428 429 value = (blocked == false); 430 431 mutex_lock(&dev->mutex); 432 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) { 433 err = -EBUSY; 434 goto out; 435 } 436 437 if (!radio_state) { 438 err = 0; 439 goto out; 440 } 441 442 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); 443 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); 444 445 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) 446 err = -EBUSY; 447 else 448 err = 0; 449 out: 450 mutex_unlock(&dev->mutex); 451 return err; 452} 453 454static void bt_rfkill_poll(struct rfkill *rfkill, void *data) 455{ 456 bool new_rfk_state; 457 bool value; 458 u32 hci_result; 459 struct toshiba_acpi_dev *dev = data; 460 461 mutex_lock(&dev->mutex); 462 463 hci_result = hci_get_radio_state(&value); 464 if (hci_result != HCI_SUCCESS) { 465 /* Can't do anything useful */ 466 mutex_unlock(&dev->mutex); 467 return; 468 } 469 470 new_rfk_state = value; 471 472 mutex_unlock(&dev->mutex); 473 474 if (rfkill_set_hw_state(rfkill, !new_rfk_state)) 475 bt_rfkill_set_block(data, true); 476} 477 478static const struct rfkill_ops toshiba_rfk_ops = { 479 .set_block = bt_rfkill_set_block, 480 .poll = bt_rfkill_poll, 481}; 482 483static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 484static struct backlight_device *toshiba_backlight_device; 485static int force_fan; 486static int last_key_event; 487static int key_event_valid; 488 489static int get_lcd(struct backlight_device *bd) 490{ 491 u32 hci_result; 492 u32 value; 493 494 hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); 495 if (hci_result == HCI_SUCCESS) { 496 return (value >> HCI_LCD_BRIGHTNESS_SHIFT); 497 } else 498 return -EFAULT; 499} 500 501static int lcd_proc_show(struct seq_file *m, void *v) 502{ 503 int value = get_lcd(NULL); 504 505 if (value >= 0) { 506 seq_printf(m, "brightness: %d\n", value); 507 seq_printf(m, "brightness_levels: %d\n", 508 HCI_LCD_BRIGHTNESS_LEVELS); 509 } else { 510 printk(MY_ERR "Error reading LCD brightness\n"); 511 } 512 513 return 0; 514} 515 516static int lcd_proc_open(struct inode *inode, struct file *file) 517{ 518 return single_open(file, lcd_proc_show, NULL); 519} 520 521static int set_lcd(int value) 522{ 523 u32 hci_result; 524 525 value = value << HCI_LCD_BRIGHTNESS_SHIFT; 526 hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); 527 if (hci_result != HCI_SUCCESS) 528 return -EFAULT; 529 530 return 0; 531} 532 533static int set_lcd_status(struct backlight_device *bd) 534{ 535 return set_lcd(bd->props.brightness); 536} 537 538static ssize_t lcd_proc_write(struct file *file, const char __user *buf, 539 size_t count, loff_t *pos) 540{ 541 char cmd[42]; 542 size_t len; 543 int value; 544 int ret; 545 546 len = min(count, sizeof(cmd) - 1); 547 if (copy_from_user(cmd, buf, len)) 548 return -EFAULT; 549 cmd[len] = '\0'; 550 551 if (sscanf(cmd, " brightness : %i", &value) == 1 && 552 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { 553 ret = set_lcd(value); 554 if (ret == 0) 555 ret = count; 556 } else { 557 ret = -EINVAL; 558 } 559 return ret; 560} 561 562static const struct file_operations lcd_proc_fops = { 563 .owner = THIS_MODULE, 564 .open = lcd_proc_open, 565 .read = seq_read, 566 .llseek = seq_lseek, 567 .release = single_release, 568 .write = lcd_proc_write, 569}; 570 571static int video_proc_show(struct seq_file *m, void *v) 572{ 573 u32 hci_result; 574 u32 value; 575 576 hci_read1(HCI_VIDEO_OUT, &value, &hci_result); 577 if (hci_result == HCI_SUCCESS) { 578 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; 579 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; 580 int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; 581 seq_printf(m, "lcd_out: %d\n", is_lcd); 582 seq_printf(m, "crt_out: %d\n", is_crt); 583 seq_printf(m, "tv_out: %d\n", is_tv); 584 } else { 585 printk(MY_ERR "Error reading video out status\n"); 586 } 587 588 return 0; 589} 590 591static int video_proc_open(struct inode *inode, struct file *file) 592{ 593 return single_open(file, video_proc_show, NULL); 594} 595 596static ssize_t video_proc_write(struct file *file, const char __user *buf, 597 size_t count, loff_t *pos) 598{ 599 char *cmd, *buffer; 600 int value; 601 int remain = count; 602 int lcd_out = -1; 603 int crt_out = -1; 604 int tv_out = -1; 605 u32 hci_result; 606 u32 video_out; 607 608 cmd = kmalloc(count + 1, GFP_KERNEL); 609 if (!cmd) 610 return -ENOMEM; 611 if (copy_from_user(cmd, buf, count)) { 612 kfree(cmd); 613 return -EFAULT; 614 } 615 cmd[count] = '\0'; 616 617 buffer = cmd; 618 619 /* scan expression. Multiple expressions may be delimited with ; 620 * 621 * NOTE: to keep scanning simple, invalid fields are ignored 622 */ 623 while (remain) { 624 if (sscanf(buffer, " lcd_out : %i", &value) == 1) 625 lcd_out = value & 1; 626 else if (sscanf(buffer, " crt_out : %i", &value) == 1) 627 crt_out = value & 1; 628 else if (sscanf(buffer, " tv_out : %i", &value) == 1) 629 tv_out = value & 1; 630 /* advance to one character past the next ; */ 631 do { 632 ++buffer; 633 --remain; 634 } 635 while (remain && *(buffer - 1) != ';'); 636 } 637 638 kfree(cmd); 639 640 hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); 641 if (hci_result == HCI_SUCCESS) { 642 unsigned int new_video_out = video_out; 643 if (lcd_out != -1) 644 _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); 645 if (crt_out != -1) 646 _set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out); 647 if (tv_out != -1) 648 _set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out); 649 /* To avoid unnecessary video disruption, only write the new 650 * video setting if something changed. */ 651 if (new_video_out != video_out) 652 write_acpi_int(METHOD_VIDEO_OUT, new_video_out); 653 } else { 654 return -EFAULT; 655 } 656 657 return count; 658} 659 660static const struct file_operations video_proc_fops = { 661 .owner = THIS_MODULE, 662 .open = video_proc_open, 663 .read = seq_read, 664 .llseek = seq_lseek, 665 .release = single_release, 666 .write = video_proc_write, 667}; 668 669static int fan_proc_show(struct seq_file *m, void *v) 670{ 671 u32 hci_result; 672 u32 value; 673 674 hci_read1(HCI_FAN, &value, &hci_result); 675 if (hci_result == HCI_SUCCESS) { 676 seq_printf(m, "running: %d\n", (value > 0)); 677 seq_printf(m, "force_on: %d\n", force_fan); 678 } else { 679 printk(MY_ERR "Error reading fan status\n"); 680 } 681 682 return 0; 683} 684 685static int fan_proc_open(struct inode *inode, struct file *file) 686{ 687 return single_open(file, fan_proc_show, NULL); 688} 689 690static ssize_t fan_proc_write(struct file *file, const char __user *buf, 691 size_t count, loff_t *pos) 692{ 693 char cmd[42]; 694 size_t len; 695 int value; 696 u32 hci_result; 697 698 len = min(count, sizeof(cmd) - 1); 699 if (copy_from_user(cmd, buf, len)) 700 return -EFAULT; 701 cmd[len] = '\0'; 702 703 if (sscanf(cmd, " force_on : %i", &value) == 1 && 704 value >= 0 && value <= 1) { 705 hci_write1(HCI_FAN, value, &hci_result); 706 if (hci_result != HCI_SUCCESS) 707 return -EFAULT; 708 else 709 force_fan = value; 710 } else { 711 return -EINVAL; 712 } 713 714 return count; 715} 716 717static const struct file_operations fan_proc_fops = { 718 .owner = THIS_MODULE, 719 .open = fan_proc_open, 720 .read = seq_read, 721 .llseek = seq_lseek, 722 .release = single_release, 723 .write = fan_proc_write, 724}; 725 726static int keys_proc_show(struct seq_file *m, void *v) 727{ 728 u32 hci_result; 729 u32 value; 730 731 if (!key_event_valid) { 732 hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); 733 if (hci_result == HCI_SUCCESS) { 734 key_event_valid = 1; 735 last_key_event = value; 736 } else if (hci_result == HCI_EMPTY) { 737 /* better luck next time */ 738 } else if (hci_result == HCI_NOT_SUPPORTED) { 739 hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); 740 printk(MY_NOTICE "Re-enabled hotkeys\n"); 741 } else { 742 printk(MY_ERR "Error reading hotkey status\n"); 743 goto end; 744 } 745 } 746 747 seq_printf(m, "hotkey_ready: %d\n", key_event_valid); 748 seq_printf(m, "hotkey: 0x%04x\n", last_key_event); 749end: 750 return 0; 751} 752 753static int keys_proc_open(struct inode *inode, struct file *file) 754{ 755 return single_open(file, keys_proc_show, NULL); 756} 757 758static ssize_t keys_proc_write(struct file *file, const char __user *buf, 759 size_t count, loff_t *pos) 760{ 761 char cmd[42]; 762 size_t len; 763 int value; 764 765 len = min(count, sizeof(cmd) - 1); 766 if (copy_from_user(cmd, buf, len)) 767 return -EFAULT; 768 cmd[len] = '\0'; 769 770 if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { 771 key_event_valid = 0; 772 } else { 773 return -EINVAL; 774 } 775 776 return count; 777} 778 779static const struct file_operations keys_proc_fops = { 780 .owner = THIS_MODULE, 781 .open = keys_proc_open, 782 .read = seq_read, 783 .llseek = seq_lseek, 784 .release = single_release, 785 .write = keys_proc_write, 786}; 787 788static int version_proc_show(struct seq_file *m, void *v) 789{ 790 seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION); 791 seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION); 792 return 0; 793} 794 795static int version_proc_open(struct inode *inode, struct file *file) 796{ 797 return single_open(file, version_proc_show, PDE(inode)->data); 798} 799 800static const struct file_operations version_proc_fops = { 801 .owner = THIS_MODULE, 802 .open = version_proc_open, 803 .read = seq_read, 804 .llseek = seq_lseek, 805 .release = single_release, 806}; 807 808/* proc and module init 809 */ 810 811#define PROC_TOSHIBA "toshiba" 812 813static void __init create_toshiba_proc_entries(void) 814{ 815 proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops); 816 proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops); 817 proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops); 818 proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops); 819 proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops); 820} 821 822static void remove_toshiba_proc_entries(void) 823{ 824 remove_proc_entry("lcd", toshiba_proc_dir); 825 remove_proc_entry("video", toshiba_proc_dir); 826 remove_proc_entry("fan", toshiba_proc_dir); 827 remove_proc_entry("keys", toshiba_proc_dir); 828 remove_proc_entry("version", toshiba_proc_dir); 829} 830 831static struct backlight_ops toshiba_backlight_data = { 832 .get_brightness = get_lcd, 833 .update_status = set_lcd_status, 834}; 835 836static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code) 837{ 838 struct key_entry *key; 839 840 for (key = toshiba_acpi_keymap; key->type != KE_END; key++) 841 if (code == key->code) 842 return key; 843 844 return NULL; 845} 846 847static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code) 848{ 849 struct key_entry *key; 850 851 for (key = toshiba_acpi_keymap; key->type != KE_END; key++) 852 if (code == key->keycode && key->type == KE_KEY) 853 return key; 854 855 return NULL; 856} 857 858static int toshiba_acpi_getkeycode(struct input_dev *dev, 859 unsigned int scancode, unsigned int *keycode) 860{ 861 struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); 862 863 if (key && key->type == KE_KEY) { 864 *keycode = key->keycode; 865 return 0; 866 } 867 868 return -EINVAL; 869} 870 871static int toshiba_acpi_setkeycode(struct input_dev *dev, 872 unsigned int scancode, unsigned int keycode) 873{ 874 struct key_entry *key; 875 unsigned int old_keycode; 876 877 key = toshiba_acpi_get_entry_by_scancode(scancode); 878 if (key && key->type == KE_KEY) { 879 old_keycode = key->keycode; 880 key->keycode = keycode; 881 set_bit(keycode, dev->keybit); 882 if (!toshiba_acpi_get_entry_by_keycode(old_keycode)) 883 clear_bit(old_keycode, dev->keybit); 884 return 0; 885 } 886 887 return -EINVAL; 888} 889 890static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) 891{ 892 u32 hci_result, value; 893 struct key_entry *key; 894 895 if (event != 0x80) 896 return; 897 do { 898 hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); 899 if (hci_result == HCI_SUCCESS) { 900 if (value == 0x100) 901 continue; 902 /* act on key press; ignore key release */ 903 if (value & 0x80) 904 continue; 905 906 key = toshiba_acpi_get_entry_by_scancode 907 (value); 908 if (!key) { 909 printk(MY_INFO "Unknown key %x\n", 910 value); 911 continue; 912 } 913 input_report_key(toshiba_acpi.hotkey_dev, 914 key->keycode, 1); 915 input_sync(toshiba_acpi.hotkey_dev); 916 input_report_key(toshiba_acpi.hotkey_dev, 917 key->keycode, 0); 918 input_sync(toshiba_acpi.hotkey_dev); 919 } else if (hci_result == HCI_NOT_SUPPORTED) { 920 hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); 921 printk(MY_NOTICE "Re-enabled hotkeys\n"); 922 } 923 } while (hci_result != HCI_EMPTY); 924} 925 926static int toshiba_acpi_setup_keyboard(char *device) 927{ 928 acpi_status status; 929 acpi_handle handle; 930 int result; 931 const struct key_entry *key; 932 933 status = acpi_get_handle(NULL, device, &handle); 934 if (ACPI_FAILURE(status)) { 935 printk(MY_INFO "Unable to get notification device\n"); 936 return -ENODEV; 937 } 938 939 toshiba_acpi.handle = handle; 940 941 status = acpi_evaluate_object(handle, "ENAB", NULL, NULL); 942 if (ACPI_FAILURE(status)) { 943 printk(MY_INFO "Unable to enable hotkeys\n"); 944 return -ENODEV; 945 } 946 947 status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY, 948 toshiba_acpi_notify, NULL); 949 if (ACPI_FAILURE(status)) { 950 printk(MY_INFO "Unable to install hotkey notification\n"); 951 return -ENODEV; 952 } 953 954 toshiba_acpi.hotkey_dev = input_allocate_device(); 955 if (!toshiba_acpi.hotkey_dev) { 956 printk(MY_INFO "Unable to register input device\n"); 957 return -ENOMEM; 958 } 959 960 toshiba_acpi.hotkey_dev->name = "Toshiba input device"; 961 toshiba_acpi.hotkey_dev->phys = device; 962 toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST; 963 toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode; 964 toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode; 965 966 for (key = toshiba_acpi_keymap; key->type != KE_END; key++) { 967 set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit); 968 set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit); 969 } 970 971 result = input_register_device(toshiba_acpi.hotkey_dev); 972 if (result) { 973 printk(MY_INFO "Unable to register input device\n"); 974 return result; 975 } 976 977 return 0; 978} 979 980static void toshiba_acpi_exit(void) 981{ 982 if (toshiba_acpi.hotkey_dev) 983 input_unregister_device(toshiba_acpi.hotkey_dev); 984 985 if (toshiba_acpi.bt_rfk) { 986 rfkill_unregister(toshiba_acpi.bt_rfk); 987 rfkill_destroy(toshiba_acpi.bt_rfk); 988 } 989 990 if (toshiba_backlight_device) 991 backlight_device_unregister(toshiba_backlight_device); 992 993 remove_toshiba_proc_entries(); 994 995 if (toshiba_proc_dir) 996 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 997 998 acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY, 999 toshiba_acpi_notify); 1000 1001 if (toshiba_acpi.illumination_installed) 1002 led_classdev_unregister(&toshiba_led); 1003 1004 platform_device_unregister(toshiba_acpi.p_dev); 1005 1006 return; 1007} 1008 1009static int __init toshiba_acpi_init(void) 1010{ 1011 u32 hci_result; 1012 bool bt_present; 1013 int ret = 0; 1014 struct backlight_properties props; 1015 1016 if (acpi_disabled) 1017 return -ENODEV; 1018 1019 /* simple device detection: look for HCI method */ 1020 if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { 1021 method_hci = TOSH_INTERFACE_1 GHCI_METHOD; 1022 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) 1023 printk(MY_INFO "Unable to activate hotkeys\n"); 1024 } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { 1025 method_hci = TOSH_INTERFACE_2 GHCI_METHOD; 1026 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) 1027 printk(MY_INFO "Unable to activate hotkeys\n"); 1028 } else 1029 return -ENODEV; 1030 1031 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", 1032 TOSHIBA_ACPI_VERSION); 1033 printk(MY_INFO " HCI method: %s\n", method_hci); 1034 1035 mutex_init(&toshiba_acpi.mutex); 1036 1037 toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi", 1038 -1, NULL, 0); 1039 if (IS_ERR(toshiba_acpi.p_dev)) { 1040 ret = PTR_ERR(toshiba_acpi.p_dev); 1041 printk(MY_ERR "unable to register platform device\n"); 1042 toshiba_acpi.p_dev = NULL; 1043 toshiba_acpi_exit(); 1044 return ret; 1045 } 1046 1047 force_fan = 0; 1048 key_event_valid = 0; 1049 1050 /* enable event fifo */ 1051 hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); 1052 1053 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); 1054 if (!toshiba_proc_dir) { 1055 toshiba_acpi_exit(); 1056 return -ENODEV; 1057 } else { 1058 create_toshiba_proc_entries(); 1059 } 1060 1061 props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; 1062 toshiba_backlight_device = backlight_device_register("toshiba", 1063 &toshiba_acpi.p_dev->dev, 1064 NULL, 1065 &toshiba_backlight_data, 1066 &props); 1067 if (IS_ERR(toshiba_backlight_device)) { 1068 ret = PTR_ERR(toshiba_backlight_device); 1069 1070 printk(KERN_ERR "Could not register toshiba backlight device\n"); 1071 toshiba_backlight_device = NULL; 1072 toshiba_acpi_exit(); 1073 return ret; 1074 } 1075 1076 /* Register rfkill switch for Bluetooth */ 1077 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { 1078 toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name, 1079 &toshiba_acpi.p_dev->dev, 1080 RFKILL_TYPE_BLUETOOTH, 1081 &toshiba_rfk_ops, 1082 &toshiba_acpi); 1083 if (!toshiba_acpi.bt_rfk) { 1084 printk(MY_ERR "unable to allocate rfkill device\n"); 1085 toshiba_acpi_exit(); 1086 return -ENOMEM; 1087 } 1088 1089 ret = rfkill_register(toshiba_acpi.bt_rfk); 1090 if (ret) { 1091 printk(MY_ERR "unable to register rfkill device\n"); 1092 rfkill_destroy(toshiba_acpi.bt_rfk); 1093 toshiba_acpi_exit(); 1094 return ret; 1095 } 1096 } 1097 1098 toshiba_acpi.illumination_installed = 0; 1099 if (toshiba_illumination_available()) { 1100 if (!led_classdev_register(&(toshiba_acpi.p_dev->dev), 1101 &toshiba_led)) 1102 toshiba_acpi.illumination_installed = 1; 1103 } 1104 1105 return 0; 1106} 1107 1108module_init(toshiba_acpi_init); 1109module_exit(toshiba_acpi_exit); 1110