aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/toshiba_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r--drivers/platform/x86/toshiba_acpi.c635
1 files changed, 578 insertions, 57 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 90dd7645a9e5..46473ca7566b 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -5,6 +5,7 @@
5 * Copyright (C) 2002-2004 John Belmonte 5 * Copyright (C) 2002-2004 John Belmonte
6 * Copyright (C) 2008 Philip Langdale 6 * Copyright (C) 2008 Philip Langdale
7 * Copyright (C) 2010 Pierre Ducroquet 7 * Copyright (C) 2010 Pierre Ducroquet
8 * Copyright (C) 2014 Azael Avalos
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * 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 * it under the terms of the GNU General Public License as published by
@@ -37,7 +38,7 @@
37 38
38#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 39#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
39 40
40#define TOSHIBA_ACPI_VERSION "0.19" 41#define TOSHIBA_ACPI_VERSION "0.20"
41#define PROC_INTERFACE_VERSION 1 42#define PROC_INTERFACE_VERSION 1
42 43
43#include <linux/kernel.h> 44#include <linux/kernel.h>
@@ -77,6 +78,9 @@ MODULE_LICENSE("GPL");
77 * However the ACPI methods seem to be incomplete in some areas (for 78 * However the ACPI methods seem to be incomplete in some areas (for
78 * example they allow setting, but not reading, the LCD brightness value), 79 * example they allow setting, but not reading, the LCD brightness value),
79 * so this is still useful. 80 * so this is still useful.
81 *
82 * SCI stands for "System Configuration Interface" which aim is to
83 * conceal differences in hardware between different models.
80 */ 84 */
81 85
82#define HCI_WORDS 6 86#define HCI_WORDS 6
@@ -84,12 +88,23 @@ MODULE_LICENSE("GPL");
84/* operations */ 88/* operations */
85#define HCI_SET 0xff00 89#define HCI_SET 0xff00
86#define HCI_GET 0xfe00 90#define HCI_GET 0xfe00
91#define SCI_OPEN 0xf100
92#define SCI_CLOSE 0xf200
93#define SCI_GET 0xf300
94#define SCI_SET 0xf400
87 95
88/* return codes */ 96/* return codes */
89#define HCI_SUCCESS 0x0000 97#define HCI_SUCCESS 0x0000
90#define HCI_FAILURE 0x1000 98#define HCI_FAILURE 0x1000
91#define HCI_NOT_SUPPORTED 0x8000 99#define HCI_NOT_SUPPORTED 0x8000
92#define HCI_EMPTY 0x8c00 100#define HCI_EMPTY 0x8c00
101#define HCI_DATA_NOT_AVAILABLE 0x8d20
102#define HCI_NOT_INITIALIZED 0x8d50
103#define SCI_OPEN_CLOSE_OK 0x0044
104#define SCI_ALREADY_OPEN 0x8100
105#define SCI_NOT_OPENED 0x8200
106#define SCI_INPUT_DATA_ERROR 0x8300
107#define SCI_NOT_PRESENT 0x8600
93 108
94/* registers */ 109/* registers */
95#define HCI_FAN 0x0004 110#define HCI_FAN 0x0004
@@ -99,13 +114,22 @@ MODULE_LICENSE("GPL");
99#define HCI_HOTKEY_EVENT 0x001e 114#define HCI_HOTKEY_EVENT 0x001e
100#define HCI_LCD_BRIGHTNESS 0x002a 115#define HCI_LCD_BRIGHTNESS 0x002a
101#define HCI_WIRELESS 0x0056 116#define HCI_WIRELESS 0x0056
117#define HCI_ACCELEROMETER 0x006d
118#define HCI_KBD_ILLUMINATION 0x0095
119#define HCI_ECO_MODE 0x0097
120#define HCI_ACCELEROMETER2 0x00a6
121#define SCI_ILLUMINATION 0x014e
122#define SCI_KBD_ILLUM_STATUS 0x015c
123#define SCI_TOUCHPAD 0x050e
102 124
103/* field definitions */ 125/* field definitions */
126#define HCI_ACCEL_MASK 0x7fff
104#define HCI_HOTKEY_DISABLE 0x0b 127#define HCI_HOTKEY_DISABLE 0x0b
105#define HCI_HOTKEY_ENABLE 0x09 128#define HCI_HOTKEY_ENABLE 0x09
106#define HCI_LCD_BRIGHTNESS_BITS 3 129#define HCI_LCD_BRIGHTNESS_BITS 3
107#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) 130#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS)
108#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) 131#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS)
132#define HCI_MISC_SHIFT 0x10
109#define HCI_VIDEO_OUT_LCD 0x1 133#define HCI_VIDEO_OUT_LCD 0x1
110#define HCI_VIDEO_OUT_CRT 0x2 134#define HCI_VIDEO_OUT_CRT 0x2
111#define HCI_VIDEO_OUT_TV 0x4 135#define HCI_VIDEO_OUT_TV 0x4
@@ -113,6 +137,8 @@ MODULE_LICENSE("GPL");
113#define HCI_WIRELESS_BT_PRESENT 0x0f 137#define HCI_WIRELESS_BT_PRESENT 0x0f
114#define HCI_WIRELESS_BT_ATTACH 0x40 138#define HCI_WIRELESS_BT_ATTACH 0x40
115#define HCI_WIRELESS_BT_POWER 0x80 139#define HCI_WIRELESS_BT_POWER 0x80
140#define SCI_KBD_MODE_FNZ 0x1
141#define SCI_KBD_MODE_AUTO 0x2
116 142
117struct toshiba_acpi_dev { 143struct toshiba_acpi_dev {
118 struct acpi_device *acpi_dev; 144 struct acpi_device *acpi_dev;
@@ -122,10 +148,14 @@ struct toshiba_acpi_dev {
122 struct work_struct hotkey_work; 148 struct work_struct hotkey_work;
123 struct backlight_device *backlight_dev; 149 struct backlight_device *backlight_dev;
124 struct led_classdev led_dev; 150 struct led_classdev led_dev;
151 struct led_classdev kbd_led;
152 struct led_classdev eco_led;
125 153
126 int force_fan; 154 int force_fan;
127 int last_key_event; 155 int last_key_event;
128 int key_event_valid; 156 int key_event_valid;
157 int kbd_mode;
158 int kbd_time;
129 159
130 unsigned int illumination_supported:1; 160 unsigned int illumination_supported:1;
131 unsigned int video_supported:1; 161 unsigned int video_supported:1;
@@ -134,6 +164,12 @@ struct toshiba_acpi_dev {
134 unsigned int ntfy_supported:1; 164 unsigned int ntfy_supported:1;
135 unsigned int info_supported:1; 165 unsigned int info_supported:1;
136 unsigned int tr_backlight_supported:1; 166 unsigned int tr_backlight_supported:1;
167 unsigned int kbd_illum_supported:1;
168 unsigned int kbd_led_registered:1;
169 unsigned int touchpad_supported:1;
170 unsigned int eco_supported:1;
171 unsigned int accelerometer_supported:1;
172 unsigned int sysfs_created:1;
137 173
138 struct mutex mutex; 174 struct mutex mutex;
139}; 175};
@@ -280,21 +316,94 @@ static acpi_status hci_read2(struct toshiba_acpi_dev *dev, u32 reg,
280 return status; 316 return status;
281} 317}
282 318
319/* common sci tasks
320 */
321
322static int sci_open(struct toshiba_acpi_dev *dev)
323{
324 u32 in[HCI_WORDS] = { SCI_OPEN, 0, 0, 0, 0, 0 };
325 u32 out[HCI_WORDS];
326 acpi_status status;
327
328 status = hci_raw(dev, in, out);
329 if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
330 pr_err("ACPI call to open SCI failed\n");
331 return 0;
332 }
333
334 if (out[0] == SCI_OPEN_CLOSE_OK) {
335 return 1;
336 } else if (out[0] == SCI_ALREADY_OPEN) {
337 pr_info("Toshiba SCI already opened\n");
338 return 1;
339 } else if (out[0] == SCI_NOT_PRESENT) {
340 pr_info("Toshiba SCI is not present\n");
341 }
342
343 return 0;
344}
345
346static void sci_close(struct toshiba_acpi_dev *dev)
347{
348 u32 in[HCI_WORDS] = { SCI_CLOSE, 0, 0, 0, 0, 0 };
349 u32 out[HCI_WORDS];
350 acpi_status status;
351
352 status = hci_raw(dev, in, out);
353 if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
354 pr_err("ACPI call to close SCI failed\n");
355 return;
356 }
357
358 if (out[0] == SCI_OPEN_CLOSE_OK)
359 return;
360 else if (out[0] == SCI_NOT_OPENED)
361 pr_info("Toshiba SCI not opened\n");
362 else if (out[0] == SCI_NOT_PRESENT)
363 pr_info("Toshiba SCI is not present\n");
364}
365
366static acpi_status sci_read(struct toshiba_acpi_dev *dev, u32 reg,
367 u32 *out1, u32 *result)
368{
369 u32 in[HCI_WORDS] = { SCI_GET, reg, 0, 0, 0, 0 };
370 u32 out[HCI_WORDS];
371 acpi_status status = hci_raw(dev, in, out);
372 *out1 = out[2];
373 *result = (ACPI_SUCCESS(status)) ? out[0] : HCI_FAILURE;
374 return status;
375}
376
377static acpi_status sci_write(struct toshiba_acpi_dev *dev, u32 reg,
378 u32 in1, u32 *result)
379{
380 u32 in[HCI_WORDS] = { SCI_SET, reg, in1, 0, 0, 0 };
381 u32 out[HCI_WORDS];
382 acpi_status status = hci_raw(dev, in, out);
383 *result = (ACPI_SUCCESS(status)) ? out[0] : HCI_FAILURE;
384 return status;
385}
386
283/* Illumination support */ 387/* Illumination support */
284static int toshiba_illumination_available(struct toshiba_acpi_dev *dev) 388static int toshiba_illumination_available(struct toshiba_acpi_dev *dev)
285{ 389{
286 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 390 u32 in[HCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 };
287 u32 out[HCI_WORDS]; 391 u32 out[HCI_WORDS];
288 acpi_status status; 392 acpi_status status;
289 393
290 in[0] = 0xf100; 394 if (!sci_open(dev))
395 return 0;
396
291 status = hci_raw(dev, in, out); 397 status = hci_raw(dev, in, out);
292 if (ACPI_FAILURE(status)) { 398 sci_close(dev);
399 if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
400 pr_err("ACPI call to query Illumination support failed\n");
401 return 0;
402 } else if (out[0] == HCI_NOT_SUPPORTED || out[1] != 1) {
293 pr_info("Illumination device not available\n"); 403 pr_info("Illumination device not available\n");
294 return 0; 404 return 0;
295 } 405 }
296 in[0] = 0xf400; 406
297 status = hci_raw(dev, in, out);
298 return 1; 407 return 1;
299} 408}
300 409
@@ -303,82 +412,270 @@ static void toshiba_illumination_set(struct led_classdev *cdev,
303{ 412{
304 struct toshiba_acpi_dev *dev = container_of(cdev, 413 struct toshiba_acpi_dev *dev = container_of(cdev,
305 struct toshiba_acpi_dev, led_dev); 414 struct toshiba_acpi_dev, led_dev);
306 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 415 u32 state, result;
307 u32 out[HCI_WORDS];
308 acpi_status status; 416 acpi_status status;
309 417
310 /* First request : initialize communication. */ 418 /* First request : initialize communication. */
311 in[0] = 0xf100; 419 if (!sci_open(dev))
312 status = hci_raw(dev, in, out); 420 return;
421
422 /* Switch the illumination on/off */
423 state = brightness ? 1 : 0;
424 status = sci_write(dev, SCI_ILLUMINATION, state, &result);
425 sci_close(dev);
313 if (ACPI_FAILURE(status)) { 426 if (ACPI_FAILURE(status)) {
314 pr_info("Illumination device not available\n"); 427 pr_err("ACPI call for illumination failed\n");
428 return;
429 } else if (result == HCI_NOT_SUPPORTED) {
430 pr_info("Illumination not supported\n");
315 return; 431 return;
316 } 432 }
433}
317 434
318 if (brightness) { 435static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
319 /* Switch the illumination on */ 436{
320 in[0] = 0xf400; 437 struct toshiba_acpi_dev *dev = container_of(cdev,
321 in[1] = 0x14e; 438 struct toshiba_acpi_dev, led_dev);
322 in[2] = 1; 439 u32 state, result;
323 status = hci_raw(dev, in, out); 440 acpi_status status;
324 if (ACPI_FAILURE(status)) { 441
325 pr_info("ACPI call for illumination failed\n"); 442 /* First request : initialize communication. */
326 return; 443 if (!sci_open(dev))
327 } 444 return LED_OFF;
328 } else { 445
329 /* Switch the illumination off */ 446 /* Check the illumination */
330 in[0] = 0xf400; 447 status = sci_read(dev, SCI_ILLUMINATION, &state, &result);
331 in[1] = 0x14e; 448 sci_close(dev);
332 in[2] = 0; 449 if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
333 status = hci_raw(dev, in, out); 450 pr_err("ACPI call for illumination failed\n");
334 if (ACPI_FAILURE(status)) { 451 return LED_OFF;
335 pr_info("ACPI call for illumination failed.\n"); 452 } else if (result == HCI_NOT_SUPPORTED) {
336 return; 453 pr_info("Illumination not supported\n");
337 } 454 return LED_OFF;
338 } 455 }
339 456
340 /* Last request : close communication. */ 457 return state ? LED_FULL : LED_OFF;
341 in[0] = 0xf200;
342 in[1] = 0;
343 in[2] = 0;
344 hci_raw(dev, in, out);
345} 458}
346 459
347static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) 460/* KBD Illumination */
461static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time)
462{
463 u32 result;
464 acpi_status status;
465
466 if (!sci_open(dev))
467 return -EIO;
468
469 status = sci_write(dev, SCI_KBD_ILLUM_STATUS, time, &result);
470 sci_close(dev);
471 if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
472 pr_err("ACPI call to set KBD backlight status failed\n");
473 return -EIO;
474 } else if (result == HCI_NOT_SUPPORTED) {
475 pr_info("Keyboard backlight status not supported\n");
476 return -ENODEV;
477 }
478
479 return 0;
480}
481
482static int toshiba_kbd_illum_status_get(struct toshiba_acpi_dev *dev, u32 *time)
483{
484 u32 result;
485 acpi_status status;
486
487 if (!sci_open(dev))
488 return -EIO;
489
490 status = sci_read(dev, SCI_KBD_ILLUM_STATUS, time, &result);
491 sci_close(dev);
492 if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
493 pr_err("ACPI call to get KBD backlight status failed\n");
494 return -EIO;
495 } else if (result == HCI_NOT_SUPPORTED) {
496 pr_info("Keyboard backlight status not supported\n");
497 return -ENODEV;
498 }
499
500 return 0;
501}
502
503static enum led_brightness toshiba_kbd_backlight_get(struct led_classdev *cdev)
348{ 504{
349 struct toshiba_acpi_dev *dev = container_of(cdev, 505 struct toshiba_acpi_dev *dev = container_of(cdev,
350 struct toshiba_acpi_dev, led_dev); 506 struct toshiba_acpi_dev, kbd_led);
351 u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; 507 u32 state, result;
508 acpi_status status;
509
510 /* Check the keyboard backlight state */
511 status = hci_read1(dev, HCI_KBD_ILLUMINATION, &state, &result);
512 if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
513 pr_err("ACPI call to get the keyboard backlight failed\n");
514 return LED_OFF;
515 } else if (result == HCI_NOT_SUPPORTED) {
516 pr_info("Keyboard backlight not supported\n");
517 return LED_OFF;
518 }
519
520 return state ? LED_FULL : LED_OFF;
521}
522
523static void toshiba_kbd_backlight_set(struct led_classdev *cdev,
524 enum led_brightness brightness)
525{
526 struct toshiba_acpi_dev *dev = container_of(cdev,
527 struct toshiba_acpi_dev, kbd_led);
528 u32 state, result;
529 acpi_status status;
530
531 /* Set the keyboard backlight state */
532 state = brightness ? 1 : 0;
533 status = hci_write1(dev, HCI_KBD_ILLUMINATION, state, &result);
534 if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
535 pr_err("ACPI call to set KBD Illumination mode failed\n");
536 return;
537 } else if (result == HCI_NOT_SUPPORTED) {
538 pr_info("Keyboard backlight not supported\n");
539 return;
540 }
541}
542
543/* TouchPad support */
544static int toshiba_touchpad_set(struct toshiba_acpi_dev *dev, u32 state)
545{
546 u32 result;
547 acpi_status status;
548
549 if (!sci_open(dev))
550 return -EIO;
551
552 status = sci_write(dev, SCI_TOUCHPAD, state, &result);
553 sci_close(dev);
554 if (ACPI_FAILURE(status)) {
555 pr_err("ACPI call to set the touchpad failed\n");
556 return -EIO;
557 } else if (result == HCI_NOT_SUPPORTED) {
558 return -ENODEV;
559 }
560
561 return 0;
562}
563
564static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state)
565{
566 u32 result;
567 acpi_status status;
568
569 if (!sci_open(dev))
570 return -EIO;
571
572 status = sci_read(dev, SCI_TOUCHPAD, state, &result);
573 sci_close(dev);
574 if (ACPI_FAILURE(status)) {
575 pr_err("ACPI call to query the touchpad failed\n");
576 return -EIO;
577 } else if (result == HCI_NOT_SUPPORTED) {
578 return -ENODEV;
579 }
580
581 return 0;
582}
583
584/* Eco Mode support */
585static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev)
586{
587 acpi_status status;
588 u32 in[HCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 };
589 u32 out[HCI_WORDS];
590
591 status = hci_raw(dev, in, out);
592 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
593 pr_info("ACPI call to get ECO led failed\n");
594 return 0;
595 }
596
597 return 1;
598}
599
600static enum led_brightness toshiba_eco_mode_get_status(struct led_classdev *cdev)
601{
602 struct toshiba_acpi_dev *dev = container_of(cdev,
603 struct toshiba_acpi_dev, eco_led);
604 u32 in[HCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 };
352 u32 out[HCI_WORDS]; 605 u32 out[HCI_WORDS];
353 acpi_status status; 606 acpi_status status;
354 enum led_brightness result;
355 607
356 /* First request : initialize communication. */
357 in[0] = 0xf100;
358 status = hci_raw(dev, in, out); 608 status = hci_raw(dev, in, out);
359 if (ACPI_FAILURE(status)) { 609 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
360 pr_info("Illumination device not available\n"); 610 pr_err("ACPI call to get ECO led failed\n");
361 return LED_OFF; 611 return LED_OFF;
362 } 612 }
363 613
364 /* Check the illumination */ 614 return out[2] ? LED_FULL : LED_OFF;
365 in[0] = 0xf300; 615}
366 in[1] = 0x14e; 616
617static void toshiba_eco_mode_set_status(struct led_classdev *cdev,
618 enum led_brightness brightness)
619{
620 struct toshiba_acpi_dev *dev = container_of(cdev,
621 struct toshiba_acpi_dev, eco_led);
622 u32 in[HCI_WORDS] = { HCI_SET, HCI_ECO_MODE, 0, 1, 0, 0 };
623 u32 out[HCI_WORDS];
624 acpi_status status;
625
626 /* Switch the Eco Mode led on/off */
627 in[2] = (brightness) ? 1 : 0;
367 status = hci_raw(dev, in, out); 628 status = hci_raw(dev, in, out);
368 if (ACPI_FAILURE(status)) { 629 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
369 pr_info("ACPI call for illumination failed.\n"); 630 pr_err("ACPI call to set ECO led failed\n");
370 return LED_OFF; 631 return;
371 } 632 }
633}
372 634
373 result = out[2] ? LED_FULL : LED_OFF; 635/* Accelerometer support */
636static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev)
637{
638 u32 in[HCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 };
639 u32 out[HCI_WORDS];
640 acpi_status status;
641
642 /* Check if the accelerometer call exists,
643 * this call also serves as initialization
644 */
645 status = hci_raw(dev, in, out);
646 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
647 pr_err("ACPI call to query the accelerometer failed\n");
648 return -EIO;
649 } else if (out[0] == HCI_DATA_NOT_AVAILABLE ||
650 out[0] == HCI_NOT_INITIALIZED) {
651 pr_err("Accelerometer not initialized\n");
652 return -EIO;
653 } else if (out[0] == HCI_NOT_SUPPORTED) {
654 pr_info("Accelerometer not supported\n");
655 return -ENODEV;
656 }
657
658 return 0;
659}
660
661static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev,
662 u32 *xy, u32 *z)
663{
664 u32 in[HCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER, 0, 1, 0, 0 };
665 u32 out[HCI_WORDS];
666 acpi_status status;
667
668 /* Check the Accelerometer status */
669 status = hci_raw(dev, in, out);
670 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
671 pr_err("ACPI call to query the accelerometer failed\n");
672 return -EIO;
673 }
374 674
375 /* Last request : close communication. */ 675 *xy = out[2];
376 in[0] = 0xf200; 676 *z = out[4];
377 in[1] = 0;
378 in[2] = 0;
379 hci_raw(dev, in, out);
380 677
381 return result; 678 return 0;
382} 679}
383 680
384/* Bluetooth rfkill handlers */ 681/* Bluetooth rfkill handlers */
@@ -904,6 +1201,177 @@ static const struct backlight_ops toshiba_backlight_data = {
904 .update_status = set_lcd_status, 1201 .update_status = set_lcd_status,
905}; 1202};
906 1203
1204/*
1205 * Sysfs files
1206 */
1207
1208static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
1209 struct device_attribute *attr,
1210 const char *buf, size_t count)
1211{
1212 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1213 int mode = -1;
1214 int time = -1;
1215
1216 if (sscanf(buf, "%i", &mode) != 1 && (mode != 2 || mode != 1))
1217 return -EINVAL;
1218
1219 /* Set the Keyboard Backlight Mode where:
1220 * Mode - Auto (2) | FN-Z (1)
1221 * Auto - KBD backlight turns off automatically in given time
1222 * FN-Z - KBD backlight "toggles" when hotkey pressed
1223 */
1224 if (mode != -1 && toshiba->kbd_mode != mode) {
1225 time = toshiba->kbd_time << HCI_MISC_SHIFT;
1226 time = time + toshiba->kbd_mode;
1227 if (toshiba_kbd_illum_status_set(toshiba, time) < 0)
1228 return -EIO;
1229 toshiba->kbd_mode = mode;
1230 }
1231
1232 return count;
1233}
1234
1235static ssize_t toshiba_kbd_bl_mode_show(struct device *dev,
1236 struct device_attribute *attr,
1237 char *buf)
1238{
1239 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1240 u32 time;
1241
1242 if (toshiba_kbd_illum_status_get(toshiba, &time) < 0)
1243 return -EIO;
1244
1245 return sprintf(buf, "%i\n", time & 0x07);
1246}
1247
1248static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev,
1249 struct device_attribute *attr,
1250 const char *buf, size_t count)
1251{
1252 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1253 int time = -1;
1254
1255 if (sscanf(buf, "%i", &time) != 1 && (time < 0 || time > 60))
1256 return -EINVAL;
1257
1258 /* Set the Keyboard Backlight Timeout: 0-60 seconds */
1259 if (time != -1 && toshiba->kbd_time != time) {
1260 time = time << HCI_MISC_SHIFT;
1261 time = (toshiba->kbd_mode == SCI_KBD_MODE_AUTO) ?
1262 time + 1 : time + 2;
1263 if (toshiba_kbd_illum_status_set(toshiba, time) < 0)
1264 return -EIO;
1265 toshiba->kbd_time = time >> HCI_MISC_SHIFT;
1266 }
1267
1268 return count;
1269}
1270
1271static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev,
1272 struct device_attribute *attr,
1273 char *buf)
1274{
1275 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1276 u32 time;
1277
1278 if (toshiba_kbd_illum_status_get(toshiba, &time) < 0)
1279 return -EIO;
1280
1281 return sprintf(buf, "%i\n", time >> HCI_MISC_SHIFT);
1282}
1283
1284static ssize_t toshiba_touchpad_store(struct device *dev,
1285 struct device_attribute *attr,
1286 const char *buf, size_t count)
1287{
1288 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1289 int state;
1290
1291 /* Set the TouchPad on/off, 0 - Disable | 1 - Enable */
1292 if (sscanf(buf, "%i", &state) == 1 && (state == 0 || state == 1)) {
1293 if (toshiba_touchpad_set(toshiba, state) < 0)
1294 return -EIO;
1295 }
1296
1297 return count;
1298}
1299
1300static ssize_t toshiba_touchpad_show(struct device *dev,
1301 struct device_attribute *attr, char *buf)
1302{
1303 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1304 u32 state;
1305 int ret;
1306
1307 ret = toshiba_touchpad_get(toshiba, &state);
1308 if (ret < 0)
1309 return ret;
1310
1311 return sprintf(buf, "%i\n", state);
1312}
1313
1314static ssize_t toshiba_position_show(struct device *dev,
1315 struct device_attribute *attr, char *buf)
1316{
1317 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1318 u32 xyval, zval, tmp;
1319 u16 x, y, z;
1320 int ret;
1321
1322 xyval = zval = 0;
1323 ret = toshiba_accelerometer_get(toshiba, &xyval, &zval);
1324 if (ret < 0)
1325 return ret;
1326
1327 x = xyval & HCI_ACCEL_MASK;
1328 tmp = xyval >> HCI_MISC_SHIFT;
1329 y = tmp & HCI_ACCEL_MASK;
1330 z = zval & HCI_ACCEL_MASK;
1331
1332 return sprintf(buf, "%d %d %d\n", x, y, z);
1333}
1334
1335static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR,
1336 toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store);
1337static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR,
1338 toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store);
1339static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR,
1340 toshiba_touchpad_show, toshiba_touchpad_store);
1341static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL);
1342
1343static struct attribute *toshiba_attributes[] = {
1344 &dev_attr_kbd_backlight_mode.attr,
1345 &dev_attr_kbd_backlight_timeout.attr,
1346 &dev_attr_touchpad.attr,
1347 &dev_attr_position.attr,
1348 NULL,
1349};
1350
1351static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
1352 struct attribute *attr, int idx)
1353{
1354 struct device *dev = container_of(kobj, struct device, kobj);
1355 struct toshiba_acpi_dev *drv = dev_get_drvdata(dev);
1356 bool exists = true;
1357
1358 if (attr == &dev_attr_kbd_backlight_mode.attr)
1359 exists = (drv->kbd_illum_supported) ? true : false;
1360 else if (attr == &dev_attr_kbd_backlight_timeout.attr)
1361 exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false;
1362 else if (attr == &dev_attr_touchpad.attr)
1363 exists = (drv->touchpad_supported) ? true : false;
1364 else if (attr == &dev_attr_position.attr)
1365 exists = (drv->accelerometer_supported) ? true : false;
1366
1367 return exists ? attr->mode : 0;
1368}
1369
1370static struct attribute_group toshiba_attr_group = {
1371 .is_visible = toshiba_sysfs_is_visible,
1372 .attrs = toshiba_attributes,
1373};
1374
907static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, 1375static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
908 struct serio *port) 1376 struct serio *port)
909{ 1377{
@@ -1106,6 +1574,10 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
1106 1574
1107 remove_toshiba_proc_entries(dev); 1575 remove_toshiba_proc_entries(dev);
1108 1576
1577 if (dev->sysfs_created)
1578 sysfs_remove_group(&dev->acpi_dev->dev.kobj,
1579 &toshiba_attr_group);
1580
1109 if (dev->ntfy_supported) { 1581 if (dev->ntfy_supported) {
1110 i8042_remove_filter(toshiba_acpi_i8042_filter); 1582 i8042_remove_filter(toshiba_acpi_i8042_filter);
1111 cancel_work_sync(&dev->hotkey_work); 1583 cancel_work_sync(&dev->hotkey_work);
@@ -1127,6 +1599,12 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
1127 if (dev->illumination_supported) 1599 if (dev->illumination_supported)
1128 led_classdev_unregister(&dev->led_dev); 1600 led_classdev_unregister(&dev->led_dev);
1129 1601
1602 if (dev->kbd_led_registered)
1603 led_classdev_unregister(&dev->kbd_led);
1604
1605 if (dev->eco_supported)
1606 led_classdev_unregister(&dev->eco_led);
1607
1130 if (toshiba_acpi) 1608 if (toshiba_acpi)
1131 toshiba_acpi = NULL; 1609 toshiba_acpi = NULL;
1132 1610
@@ -1172,6 +1650,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
1172 dev->acpi_dev = acpi_dev; 1650 dev->acpi_dev = acpi_dev;
1173 dev->method_hci = hci_method; 1651 dev->method_hci = hci_method;
1174 acpi_dev->driver_data = dev; 1652 acpi_dev->driver_data = dev;
1653 dev_set_drvdata(&acpi_dev->dev, dev);
1175 1654
1176 if (toshiba_acpi_setup_keyboard(dev)) 1655 if (toshiba_acpi_setup_keyboard(dev))
1177 pr_info("Unable to activate hotkeys\n"); 1656 pr_info("Unable to activate hotkeys\n");
@@ -1212,6 +1691,40 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
1212 dev->illumination_supported = 1; 1691 dev->illumination_supported = 1;
1213 } 1692 }
1214 1693
1694 if (toshiba_eco_mode_available(dev)) {
1695 dev->eco_led.name = "toshiba::eco_mode";
1696 dev->eco_led.max_brightness = 1;
1697 dev->eco_led.brightness_set = toshiba_eco_mode_set_status;
1698 dev->eco_led.brightness_get = toshiba_eco_mode_get_status;
1699 if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led))
1700 dev->eco_supported = 1;
1701 }
1702
1703 ret = toshiba_kbd_illum_status_get(dev, &dummy);
1704 if (!ret) {
1705 dev->kbd_time = dummy >> HCI_MISC_SHIFT;
1706 dev->kbd_mode = dummy & 0x07;
1707 }
1708 dev->kbd_illum_supported = !ret;
1709 /*
1710 * Only register the LED if KBD illumination is supported
1711 * and the keyboard backlight operation mode is set to FN-Z
1712 */
1713 if (dev->kbd_illum_supported && dev->kbd_mode == SCI_KBD_MODE_FNZ) {
1714 dev->kbd_led.name = "toshiba::kbd_backlight";
1715 dev->kbd_led.max_brightness = 1;
1716 dev->kbd_led.brightness_set = toshiba_kbd_backlight_set;
1717 dev->kbd_led.brightness_get = toshiba_kbd_backlight_get;
1718 if (!led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led))
1719 dev->kbd_led_registered = 1;
1720 }
1721
1722 ret = toshiba_touchpad_get(dev, &dummy);
1723 dev->touchpad_supported = !ret;
1724
1725 ret = toshiba_accelerometer_supported(dev);
1726 dev->accelerometer_supported = !ret;
1727
1215 /* Determine whether or not BIOS supports fan and video interfaces */ 1728 /* Determine whether or not BIOS supports fan and video interfaces */
1216 1729
1217 ret = get_video_status(dev, &dummy); 1730 ret = get_video_status(dev, &dummy);
@@ -1220,6 +1733,14 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
1220 ret = get_fan_status(dev, &dummy); 1733 ret = get_fan_status(dev, &dummy);
1221 dev->fan_supported = !ret; 1734 dev->fan_supported = !ret;
1222 1735
1736 ret = sysfs_create_group(&dev->acpi_dev->dev.kobj,
1737 &toshiba_attr_group);
1738 if (ret) {
1739 dev->sysfs_created = 0;
1740 goto error;
1741 }
1742 dev->sysfs_created = !ret;
1743
1223 create_toshiba_proc_entries(dev); 1744 create_toshiba_proc_entries(dev);
1224 1745
1225 toshiba_acpi = dev; 1746 toshiba_acpi = dev;