toshiba_acpi.c 71.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 *  toshiba_acpi.c - Toshiba Laptop ACPI Extras
 *
 *  Copyright (C) 2002-2004 John Belmonte
5
 *  Copyright (C) 2008 Philip Langdale
6
 *  Copyright (C) 2010 Pierre Ducroquet
7
 *  Copyright (C) 2014-2015 Azael Avalos
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16 17 18
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
D
Darren Hart 已提交
19 20
 *  The full GNU General Public License is included in this distribution in
 *  the file called "COPYING".
L
Linus Torvalds 已提交
21 22 23 24 25 26 27 28 29 30 31
 *
 *  The devolpment page for this driver is located at
 *  http://memebeam.org/toys/ToshibaAcpiDriver.
 *
 *  Credits:
 *	Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse
 *		engineering the Windows drivers
 *	Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
 *	Rob Miller - TV out and hotkeys help
 */

32 33
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

34
#define TOSHIBA_ACPI_VERSION	"0.23"
L
Linus Torvalds 已提交
35 36 37 38 39 40 41
#define PROC_INTERFACE_VERSION	1

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
42
#include <linux/seq_file.h>
43
#include <linux/backlight.h>
44
#include <linux/input.h>
45
#include <linux/input/sparse-keymap.h>
46
#include <linux/leds.h>
47
#include <linux/slab.h>
48 49
#include <linux/workqueue.h>
#include <linux/i8042.h>
50
#include <linux/acpi.h>
51
#include <linux/dmi.h>
52
#include <linux/uaccess.h>
53 54
#include <linux/miscdevice.h>
#include <linux/toshiba.h>
55
#include <acpi/video.h>
L
Linus Torvalds 已提交
56 57 58 59 60

MODULE_AUTHOR("John Belmonte");
MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
MODULE_LICENSE("GPL");

61 62
#define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100"

63 64 65
/* Scan code for Fn key on TOS1900 models */
#define TOS1900_FN_SCAN		0x6e

L
Linus Torvalds 已提交
66 67 68
/* Toshiba ACPI method paths */
#define METHOD_VIDEO_OUT	"\\_SB_.VALX.DSSX"

69 70
/*
 * The Toshiba configuration interface is composed of the HCI and the SCI,
71
 * which are defined as follows:
L
Linus Torvalds 已提交
72 73 74 75 76 77 78
 *
 * HCI is Toshiba's "Hardware Control Interface" which is supposed to
 * be uniform across all their models.  Ideally we would just call
 * dedicated ACPI methods instead of using this primitive interface.
 * However the ACPI methods seem to be incomplete in some areas (for
 * example they allow setting, but not reading, the LCD brightness value),
 * so this is still useful.
M
Matthew Garrett 已提交
79
 *
80 81
 * SCI stands for "System Configuration Interface" which aim is to
 * conceal differences in hardware between different models.
L
Linus Torvalds 已提交
82 83
 */

84
#define TCI_WORDS			6
L
Linus Torvalds 已提交
85

A
Azael Avalos 已提交
86
/* Operations */
L
Linus Torvalds 已提交
87 88
#define HCI_SET				0xff00
#define HCI_GET				0xfe00
89 90 91 92
#define SCI_OPEN			0xf100
#define SCI_CLOSE			0xf200
#define SCI_GET				0xf300
#define SCI_SET				0xf400
L
Linus Torvalds 已提交
93

A
Azael Avalos 已提交
94
/* Return codes */
95
#define TOS_SUCCESS			0x0000
96
#define TOS_SUCCESS2			0x0001
97 98 99 100 101 102 103 104 105 106 107
#define TOS_OPEN_CLOSE_OK		0x0044
#define TOS_FAILURE			0x1000
#define TOS_NOT_SUPPORTED		0x8000
#define TOS_ALREADY_OPEN		0x8100
#define TOS_NOT_OPENED			0x8200
#define TOS_INPUT_DATA_ERROR		0x8300
#define TOS_WRITE_PROTECTED		0x8400
#define TOS_NOT_PRESENT			0x8600
#define TOS_FIFO_EMPTY			0x8c00
#define TOS_DATA_NOT_AVAILABLE		0x8d20
#define TOS_NOT_INITIALIZED		0x8d50
108
#define TOS_NOT_INSTALLED		0x8e00
L
Linus Torvalds 已提交
109

A
Azael Avalos 已提交
110
/* Registers */
L
Linus Torvalds 已提交
111
#define HCI_FAN				0x0004
112
#define HCI_TR_BACKLIGHT		0x0005
L
Linus Torvalds 已提交
113 114 115 116
#define HCI_SYSTEM_EVENT		0x0016
#define HCI_VIDEO_OUT			0x001c
#define HCI_HOTKEY_EVENT		0x001e
#define HCI_LCD_BRIGHTNESS		0x002a
117
#define HCI_ACCELEROMETER		0x006d
118
#define HCI_KBD_ILLUMINATION		0x0095
119
#define HCI_ECO_MODE			0x0097
120
#define HCI_ACCELEROMETER2		0x00a6
121
#define HCI_SYSTEM_INFO			0xc000
122
#define SCI_PANEL_POWER_ON		0x010d
123
#define SCI_ILLUMINATION		0x014e
124
#define SCI_USB_SLEEP_CHARGE		0x0150
125
#define SCI_KBD_ILLUM_STATUS		0x015c
126
#define SCI_USB_SLEEP_MUSIC		0x015e
127
#define SCI_USB_THREE			0x0169
128
#define SCI_TOUCHPAD			0x050e
129
#define SCI_KBD_FUNCTION_KEYS		0x0522
L
Linus Torvalds 已提交
130

A
Azael Avalos 已提交
131
/* Field definitions */
132
#define HCI_ACCEL_MASK			0x7fff
133
#define HCI_HOTKEY_DISABLE		0x0b
134
#define HCI_HOTKEY_ENABLE		0x01
135
#define HCI_HOTKEY_SPECIAL_FUNCTIONS	0x10
L
Linus Torvalds 已提交
136 137 138
#define HCI_LCD_BRIGHTNESS_BITS		3
#define HCI_LCD_BRIGHTNESS_SHIFT	(16-HCI_LCD_BRIGHTNESS_BITS)
#define HCI_LCD_BRIGHTNESS_LEVELS	(1 << HCI_LCD_BRIGHTNESS_BITS)
139
#define HCI_MISC_SHIFT			0x10
140 141
#define HCI_SYSTEM_TYPE1		0x10
#define HCI_SYSTEM_TYPE2		0x11
L
Linus Torvalds 已提交
142 143 144
#define HCI_VIDEO_OUT_LCD		0x1
#define HCI_VIDEO_OUT_CRT		0x2
#define HCI_VIDEO_OUT_TV		0x4
145
#define SCI_KBD_MODE_MASK		0x1f
146 147
#define SCI_KBD_MODE_FNZ		0x1
#define SCI_KBD_MODE_AUTO		0x2
148 149 150
#define SCI_KBD_MODE_ON			0x8
#define SCI_KBD_MODE_OFF		0x10
#define SCI_KBD_TIME_MAX		0x3c001a
151
#define SCI_USB_CHARGE_MODE_MASK	0xff
152 153 154 155
#define SCI_USB_CHARGE_DISABLED		0x00
#define SCI_USB_CHARGE_ALTERNATE	0x09
#define SCI_USB_CHARGE_TYPICAL		0x11
#define SCI_USB_CHARGE_AUTO		0x21
156 157 158 159
#define SCI_USB_CHARGE_BAT_MASK		0x7
#define SCI_USB_CHARGE_BAT_LVL_OFF	0x1
#define SCI_USB_CHARGE_BAT_LVL_ON	0x4
#define SCI_USB_CHARGE_BAT_LVL		0x0200
160
#define SCI_USB_CHARGE_RAPID_DSP	0x0300
L
Linus Torvalds 已提交
161

162 163 164 165
struct toshiba_acpi_dev {
	struct acpi_device *acpi_dev;
	const char *method_hci;
	struct input_dev *hotkey_dev;
166
	struct work_struct hotkey_work;
167 168
	struct backlight_device *backlight_dev;
	struct led_classdev led_dev;
169
	struct led_classdev kbd_led;
170
	struct led_classdev eco_led;
171
	struct miscdevice miscdev;
172

173 174 175
	int force_fan;
	int last_key_event;
	int key_event_valid;
176
	int kbd_type;
177 178
	int kbd_mode;
	int kbd_time;
179
	int usbsc_bat_level;
180
	int usbsc_mode_base;
181
	int hotkey_event_type;
182

183 184 185 186
	unsigned int illumination_supported:1;
	unsigned int video_supported:1;
	unsigned int fan_supported:1;
	unsigned int system_event_supported:1;
187 188
	unsigned int ntfy_supported:1;
	unsigned int info_supported:1;
189
	unsigned int tr_backlight_supported:1;
190
	unsigned int kbd_illum_supported:1;
191
	unsigned int touchpad_supported:1;
192
	unsigned int eco_supported:1;
193
	unsigned int accelerometer_supported:1;
194
	unsigned int usb_sleep_charge_supported:1;
195
	unsigned int usb_rapid_charge_supported:1;
196
	unsigned int usb_sleep_music_supported:1;
197
	unsigned int kbd_function_keys_supported:1;
198
	unsigned int panel_power_on_supported:1;
199
	unsigned int usb_three_supported:1;
200
	unsigned int sysfs_created:1;
201
	unsigned int special_functions;
202 203 204 205

	bool kbd_led_registered;
	bool illumination_led_registered;
	bool eco_led_registered;
206 207
};

208 209
static struct toshiba_acpi_dev *toshiba_acpi;

210 211
static const struct acpi_device_id toshiba_device_ids[] = {
	{"TOS6200", 0},
212
	{"TOS6207", 0},
213
	{"TOS6208", 0},
214 215 216 217 218
	{"TOS1900", 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);

219
static const struct key_entry toshiba_acpi_keymap[] = {
220
	{ KE_KEY, 0x9e, { KEY_RFKILL } },
221 222 223
	{ KE_KEY, 0x101, { KEY_MUTE } },
	{ KE_KEY, 0x102, { KEY_ZOOMOUT } },
	{ KE_KEY, 0x103, { KEY_ZOOMIN } },
224
	{ KE_KEY, 0x10f, { KEY_TAB } },
225 226
	{ KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
	{ KE_KEY, 0x139, { KEY_ZOOMRESET } },
227 228 229 230 231 232 233 234
	{ KE_KEY, 0x13b, { KEY_COFFEE } },
	{ KE_KEY, 0x13c, { KEY_BATTERY } },
	{ KE_KEY, 0x13d, { KEY_SLEEP } },
	{ KE_KEY, 0x13e, { KEY_SUSPEND } },
	{ KE_KEY, 0x13f, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
	{ KE_KEY, 0x142, { KEY_WLAN } },
235
	{ KE_KEY, 0x143, { KEY_TOUCHPAD_TOGGLE } },
236
	{ KE_KEY, 0x17f, { KEY_FN } },
237 238 239 240 241 242 243 244
	{ KE_KEY, 0xb05, { KEY_PROG2 } },
	{ KE_KEY, 0xb06, { KEY_WWW } },
	{ KE_KEY, 0xb07, { KEY_MAIL } },
	{ KE_KEY, 0xb30, { KEY_STOP } },
	{ KE_KEY, 0xb31, { KEY_PREVIOUSSONG } },
	{ KE_KEY, 0xb32, { KEY_NEXTSONG } },
	{ KE_KEY, 0xb33, { KEY_PLAYPAUSE } },
	{ KE_KEY, 0xb5a, { KEY_MEDIA } },
245 246 247 248 249
	{ KE_IGNORE, 0x1430, { KEY_RESERVED } }, /* Wake from sleep */
	{ KE_IGNORE, 0x1501, { KEY_RESERVED } }, /* Output changed */
	{ KE_IGNORE, 0x1502, { KEY_RESERVED } }, /* HDMI plugged/unplugged */
	{ KE_IGNORE, 0x1ABE, { KEY_RESERVED } }, /* Protection level set */
	{ KE_IGNORE, 0x1ABF, { KEY_RESERVED } }, /* Protection level off */
250
	{ KE_END, 0 },
251 252
};

253 254 255
static const struct key_entry toshiba_acpi_alt_keymap[] = {
	{ KE_KEY, 0x102, { KEY_ZOOMOUT } },
	{ KE_KEY, 0x103, { KEY_ZOOMIN } },
256
	{ KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
257 258 259
	{ KE_KEY, 0x139, { KEY_ZOOMRESET } },
	{ KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, 0x13d, { KEY_BRIGHTNESSUP } },
260
	{ KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } },
261
	{ KE_KEY, 0x13f, { KEY_TOUCHPAD_TOGGLE } },
262 263
	{ KE_KEY, 0x157, { KEY_MUTE } },
	{ KE_KEY, 0x158, { KEY_WLAN } },
264 265 266
	{ KE_END, 0 },
};

267 268 269 270 271 272 273 274
/*
 * List of models which have a broken acpi-video backlight interface and thus
 * need to use the toshiba (vendor) interface instead.
 */
static const struct dmi_system_id toshiba_vendor_backlight_dmi[] = {
	{}
};

275 276
/*
 * Utility
L
Linus Torvalds 已提交
277 278
 */

279
static inline void _set_bit(u32 *word, u32 mask, int value)
L
Linus Torvalds 已提交
280 281 282 283
{
	*word = (*word & ~mask) | (mask * value);
}

284 285
/*
 * ACPI interface wrappers
L
Linus Torvalds 已提交
286 287
 */

L
Len Brown 已提交
288
static int write_acpi_int(const char *methodName, int val)
L
Linus Torvalds 已提交
289 290 291
{
	acpi_status status;

292
	status = acpi_execute_simple_method(NULL, (char *)methodName, val);
S
Seth Forshee 已提交
293
	return (status == AE_OK) ? 0 : -EIO;
L
Linus Torvalds 已提交
294 295
}

296 297
/*
 * Perform a raw configuration call.  Here we don't care about input or output
298
 * buffer format.
L
Linus Torvalds 已提交
299
 */
300 301
static acpi_status tci_raw(struct toshiba_acpi_dev *dev,
			   const u32 in[TCI_WORDS], u32 out[TCI_WORDS])
L
Linus Torvalds 已提交
302 303
{
	struct acpi_object_list params;
304
	union acpi_object in_objs[TCI_WORDS];
L
Linus Torvalds 已提交
305
	struct acpi_buffer results;
306
	union acpi_object out_objs[TCI_WORDS + 1];
L
Linus Torvalds 已提交
307 308 309
	acpi_status status;
	int i;

310
	params.count = TCI_WORDS;
L
Linus Torvalds 已提交
311
	params.pointer = in_objs;
312
	for (i = 0; i < TCI_WORDS; ++i) {
L
Linus Torvalds 已提交
313 314 315 316 317 318 319
		in_objs[i].type = ACPI_TYPE_INTEGER;
		in_objs[i].integer.value = in[i];
	}

	results.length = sizeof(out_objs);
	results.pointer = out_objs;

320 321
	status = acpi_evaluate_object(dev->acpi_dev->handle,
				      (char *)dev->method_hci, &params,
L
Len Brown 已提交
322
				      &results);
323
	if ((status == AE_OK) && (out_objs->package.count <= TCI_WORDS)) {
324
		for (i = 0; i < out_objs->package.count; ++i)
L
Linus Torvalds 已提交
325 326 327 328 329 330
			out[i] = out_objs->package.elements[i].integer.value;
	}

	return status;
}

331
/*
332
 * Common hci tasks
L
Linus Torvalds 已提交
333 334 335 336 337
 *
 * In addition to the ACPI status, the HCI system returns a result which
 * may be useful (such as "not supported").
 */

338
static u32 hci_write(struct toshiba_acpi_dev *dev, u32 reg, u32 in1)
L
Linus Torvalds 已提交
339
{
340 341 342
	u32 in[TCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);
343 344

	return ACPI_SUCCESS(status) ? out[0] : TOS_FAILURE;
L
Linus Torvalds 已提交
345 346
}

347
static u32 hci_read(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1)
L
Linus Torvalds 已提交
348
{
349 350 351
	u32 in[TCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);
352

353 354 355
	if (ACPI_FAILURE(status))
		return TOS_FAILURE;

L
Linus Torvalds 已提交
356
	*out1 = out[2];
357 358

	return out[0];
L
Linus Torvalds 已提交
359 360
}

361 362
/*
 * Common sci tasks
363 364 365 366
 */

static int sci_open(struct toshiba_acpi_dev *dev)
{
367 368
	u32 in[TCI_WORDS] = { SCI_OPEN, 0, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
369 370
	acpi_status status;

371
	status = tci_raw(dev, in, out);
372
	if  (ACPI_FAILURE(status)) {
373 374 375 376
		pr_err("ACPI call to open SCI failed\n");
		return 0;
	}

377
	if (out[0] == TOS_OPEN_CLOSE_OK) {
378
		return 1;
379
	} else if (out[0] == TOS_ALREADY_OPEN) {
380 381
		pr_info("Toshiba SCI already opened\n");
		return 1;
382
	} else if (out[0] == TOS_NOT_SUPPORTED) {
383 384
		/*
		 * Some BIOSes do not have the SCI open/close functions
385 386 387 388 389 390 391 392 393 394 395
		 * implemented and return 0x8000 (Not Supported), failing to
		 * register some supported features.
		 *
		 * Simply return 1 if we hit those affected laptops to make the
		 * supported features work.
		 *
		 * In the case that some laptops really do not support the SCI,
		 * all the SCI dependent functions check for TOS_NOT_SUPPORTED,
		 * and thus, not registering support for the queried feature.
		 */
		return 1;
396
	} else if (out[0] == TOS_NOT_PRESENT) {
397 398 399 400 401 402 403 404
		pr_info("Toshiba SCI is not present\n");
	}

	return 0;
}

static void sci_close(struct toshiba_acpi_dev *dev)
{
405 406
	u32 in[TCI_WORDS] = { SCI_CLOSE, 0, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
407 408
	acpi_status status;

409
	status = tci_raw(dev, in, out);
410
	if (ACPI_FAILURE(status)) {
411 412 413 414
		pr_err("ACPI call to close SCI failed\n");
		return;
	}

415
	if (out[0] == TOS_OPEN_CLOSE_OK)
416
		return;
417
	else if (out[0] == TOS_NOT_OPENED)
418
		pr_info("Toshiba SCI not opened\n");
419
	else if (out[0] == TOS_NOT_PRESENT)
420 421 422
		pr_info("Toshiba SCI is not present\n");
}

423
static u32 sci_read(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1)
424
{
425 426 427
	u32 in[TCI_WORDS] = { SCI_GET, reg, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);
428

429 430 431
	if (ACPI_FAILURE(status))
		return TOS_FAILURE;

432
	*out1 = out[2];
433 434

	return out[0];
435 436
}

437
static u32 sci_write(struct toshiba_acpi_dev *dev, u32 reg, u32 in1)
438
{
439 440 441
	u32 in[TCI_WORDS] = { SCI_SET, reg, in1, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);
442 443

	return ACPI_SUCCESS(status) ? out[0] : TOS_FAILURE;
444 445
}

446
/* Illumination support */
447
static void toshiba_illumination_available(struct toshiba_acpi_dev *dev)
448
{
449 450
	u32 in[TCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
451 452
	acpi_status status;

453 454 455
	dev->illumination_supported = 0;
	dev->illumination_led_registered = false;

456
	if (!sci_open(dev))
457
		return;
458

459
	status = tci_raw(dev, in, out);
460
	sci_close(dev);
461
	if (ACPI_FAILURE(status))
462
		pr_err("ACPI call to query Illumination support failed\n");
463 464
	else if (out[0] == TOS_SUCCESS)
		dev->illumination_supported = 1;
465 466 467 468 469
}

static void toshiba_illumination_set(struct led_classdev *cdev,
				     enum led_brightness brightness)
{
470 471
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, led_dev);
472 473
	u32 result;
	u32 state;
474 475

	/* First request : initialize communication. */
476
	if (!sci_open(dev))
477 478
		return;

479 480
	/* Switch the illumination on/off */
	state = brightness ? 1 : 0;
481
	result = sci_write(dev, SCI_ILLUMINATION, state);
482
	sci_close(dev);
483
	if (result == TOS_FAILURE)
484
		pr_err("ACPI call for illumination failed\n");
485 486 487 488
}

static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
{
489 490
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, led_dev);
491
	u32 state, result;
492

A
Azael Avalos 已提交
493
	/* First request : initialize communication. */
494
	if (!sci_open(dev))
495 496 497
		return LED_OFF;

	/* Check the illumination */
498
	result = sci_read(dev, SCI_ILLUMINATION, &state);
499
	sci_close(dev);
500
	if (result == TOS_FAILURE) {
501 502
		pr_err("ACPI call for illumination failed\n");
		return LED_OFF;
503
	} else if (result != TOS_SUCCESS) {
504 505 506
		return LED_OFF;
	}

507
	return state ? LED_FULL : LED_OFF;
508
}
M
Matthew Garrett 已提交
509

510
/* KBD Illumination */
511
static void toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev)
512
{
513 514
	u32 in[TCI_WORDS] = { SCI_GET, SCI_KBD_ILLUM_STATUS, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
515 516
	acpi_status status;

517 518 519
	dev->kbd_illum_supported = 0;
	dev->kbd_led_registered = false;

520
	if (!sci_open(dev))
521
		return;
522

523
	status = tci_raw(dev, in, out);
524
	sci_close(dev);
525
	if (ACPI_FAILURE(status)) {
526
		pr_err("ACPI call to query kbd illumination support failed\n");
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
	} else if (out[0] == TOS_SUCCESS) {
		/*
		 * Check for keyboard backlight timeout max value,
		 * previous kbd backlight implementation set this to
		 * 0x3c0003, and now the new implementation set this
		 * to 0x3c001a, use this to distinguish between them.
		 */
		if (out[3] == SCI_KBD_TIME_MAX)
			dev->kbd_type = 2;
		else
			dev->kbd_type = 1;
		/* Get the current keyboard backlight mode */
		dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK;
		/* Get the current time (1-60 seconds) */
		dev->kbd_time = out[2] >> HCI_MISC_SHIFT;
		/* Flag as supported */
		dev->kbd_illum_supported = 1;
544 545 546
	}
}

547 548 549 550 551 552 553
static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

554
	result = sci_write(dev, SCI_KBD_ILLUM_STATUS, time);
555
	sci_close(dev);
556
	if (result == TOS_FAILURE)
557
		pr_err("ACPI call to set KBD backlight status failed\n");
558
	else if (result == TOS_NOT_SUPPORTED)
559 560
		return -ENODEV;

561
	return result == TOS_SUCCESS ? 0 : -EIO;
562 563 564 565 566 567 568 569 570
}

static int toshiba_kbd_illum_status_get(struct toshiba_acpi_dev *dev, u32 *time)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

571
	result = sci_read(dev, SCI_KBD_ILLUM_STATUS, time);
572
	sci_close(dev);
573
	if (result == TOS_FAILURE)
574
		pr_err("ACPI call to get KBD backlight status failed\n");
575
	else if (result == TOS_NOT_SUPPORTED)
576 577
		return -ENODEV;

578
	return result == TOS_SUCCESS ? 0 : -EIO;
579 580 581 582 583 584
}

static enum led_brightness toshiba_kbd_backlight_get(struct led_classdev *cdev)
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, kbd_led);
585 586
	u32 result;
	u32 state;
587 588

	/* Check the keyboard backlight state */
589
	result = hci_read(dev, HCI_KBD_ILLUMINATION, &state);
590
	if (result == TOS_FAILURE) {
591 592
		pr_err("ACPI call to get the keyboard backlight failed\n");
		return LED_OFF;
593
	} else if (result != TOS_SUCCESS) {
594 595 596 597 598 599 600 601 602 603 604
		return LED_OFF;
	}

	return state ? LED_FULL : LED_OFF;
}

static void toshiba_kbd_backlight_set(struct led_classdev *cdev,
				     enum led_brightness brightness)
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, kbd_led);
605 606
	u32 result;
	u32 state;
607 608 609

	/* Set the keyboard backlight state */
	state = brightness ? 1 : 0;
610
	result = hci_write(dev, HCI_KBD_ILLUMINATION, state);
611
	if (result == TOS_FAILURE)
612 613
		pr_err("ACPI call to set KBD Illumination mode failed\n");
}
M
Matthew Garrett 已提交
614

615 616 617 618 619 620 621 622
/* TouchPad support */
static int toshiba_touchpad_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

623
	result = sci_write(dev, SCI_TOUCHPAD, state);
624
	sci_close(dev);
625
	if (result == TOS_FAILURE)
626
		pr_err("ACPI call to set the touchpad failed\n");
627
	else if (result == TOS_NOT_SUPPORTED)
628 629
		return -ENODEV;

630
	return result == TOS_SUCCESS ? 0 : -EIO;
631 632 633 634 635 636 637 638 639
}

static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

640
	result = sci_read(dev, SCI_TOUCHPAD, state);
641
	sci_close(dev);
642
	if (result == TOS_FAILURE)
643
		pr_err("ACPI call to query the touchpad failed\n");
644
	else if (result == TOS_NOT_SUPPORTED)
645 646
		return -ENODEV;

647
	return result == TOS_SUCCESS ? 0 : -EIO;
648
}
649

650
/* Eco Mode support */
651
static void toshiba_eco_mode_available(struct toshiba_acpi_dev *dev)
652 653
{
	acpi_status status;
654
	u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 };
655
	u32 out[TCI_WORDS];
656

657 658 659
	dev->eco_supported = 0;
	dev->eco_led_registered = false;

660
	status = tci_raw(dev, in, out);
661
	if (ACPI_FAILURE(status)) {
662 663
		pr_err("ACPI call to get ECO led failed\n");
	} else if (out[0] == TOS_INPUT_DATA_ERROR) {
664 665
		/*
		 * If we receive 0x8300 (Input Data Error), it means that the
666 667 668 669 670 671 672 673 674
		 * LED device is present, but that we just screwed the input
		 * parameters.
		 *
		 * Let's query the status of the LED to see if we really have a
		 * success response, indicating the actual presense of the LED,
		 * bail out otherwise.
		 */
		in[3] = 1;
		status = tci_raw(dev, in, out);
675
		if (ACPI_FAILURE(status))
676 677
			pr_err("ACPI call to get ECO led failed\n");
		else if (out[0] == TOS_SUCCESS)
678
			dev->eco_supported = 1;
679 680 681
	}
}

682 683
static enum led_brightness
toshiba_eco_mode_get_status(struct led_classdev *cdev)
684 685 686
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, eco_led);
687 688
	u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
689 690
	acpi_status status;

691
	status = tci_raw(dev, in, out);
692
	if (ACPI_FAILURE(status)) {
693 694
		pr_err("ACPI call to get ECO led failed\n");
		return LED_OFF;
695 696
	} else if (out[0] != TOS_SUCCESS) {
		return LED_OFF;
697 698 699 700 701 702 703 704 705 706
	}

	return out[2] ? LED_FULL : LED_OFF;
}

static void toshiba_eco_mode_set_status(struct led_classdev *cdev,
				     enum led_brightness brightness)
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, eco_led);
707 708
	u32 in[TCI_WORDS] = { HCI_SET, HCI_ECO_MODE, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
709 710 711 712
	acpi_status status;

	/* Switch the Eco Mode led on/off */
	in[2] = (brightness) ? 1 : 0;
713
	status = tci_raw(dev, in, out);
714
	if (ACPI_FAILURE(status))
715 716
		pr_err("ACPI call to set ECO led failed\n");
}
M
Matthew Garrett 已提交
717

718
/* Accelerometer support */
719
static void toshiba_accelerometer_available(struct toshiba_acpi_dev *dev)
720
{
721 722
	u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
723 724
	acpi_status status;

725 726
	dev->accelerometer_supported = 0;

727 728
	/*
	 * Check if the accelerometer call exists,
729 730
	 * this call also serves as initialization
	 */
731
	status = tci_raw(dev, in, out);
732
	if (ACPI_FAILURE(status))
733
		pr_err("ACPI call to query the accelerometer failed\n");
734 735
	else if (out[0] == TOS_SUCCESS)
		dev->accelerometer_supported = 1;
736 737 738
}

static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev,
739
				     u32 *xy, u32 *z)
740
{
741 742
	u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
743 744 745
	acpi_status status;

	/* Check the Accelerometer status */
746
	status = tci_raw(dev, in, out);
747
	if (ACPI_FAILURE(status)) {
748 749
		pr_err("ACPI call to query the accelerometer failed\n");
		return -EIO;
750 751 752 753 754 755
	} else if (out[0] == TOS_NOT_SUPPORTED) {
		return -ENODEV;
	} else if (out[0] == TOS_SUCCESS) {
		*xy = out[2];
		*z = out[4];
		return 0;
756 757
	}

758
	return -EIO;
759
}
760

761
/* Sleep (Charge and Music) utilities support */
762 763 764 765 766 767 768 769 770 771 772 773
static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev)
{
	u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	dev->usb_sleep_charge_supported = 0;

	if (!sci_open(dev))
		return;

	status = tci_raw(dev, in, out);
774
	if (ACPI_FAILURE(status)) {
775 776 777 778 779 780 781 782 783 784 785 786
		pr_err("ACPI call to get USB Sleep and Charge mode failed\n");
		sci_close(dev);
		return;
	} else if (out[0] == TOS_NOT_SUPPORTED) {
		sci_close(dev);
		return;
	} else if (out[0] == TOS_SUCCESS) {
		dev->usbsc_mode_base = out[4];
	}

	in[5] = SCI_USB_CHARGE_BAT_LVL;
	status = tci_raw(dev, in, out);
787
	sci_close(dev);
788
	if (ACPI_FAILURE(status)) {
789 790 791
		pr_err("ACPI call to get USB Sleep and Charge mode failed\n");
	} else if (out[0] == TOS_SUCCESS) {
		dev->usbsc_bat_level = out[2];
792
		/* Flag as supported */
793 794 795 796 797
		dev->usb_sleep_charge_supported = 1;
	}

}

798 799 800 801 802 803 804 805 806 807
static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev,
					u32 *mode)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_read(dev, SCI_USB_SLEEP_CHARGE, mode);
	sci_close(dev);
808
	if (result == TOS_FAILURE)
809
		pr_err("ACPI call to set USB S&C mode failed\n");
810
	else if (result == TOS_NOT_SUPPORTED)
811 812
		return -ENODEV;

813
	return result == TOS_SUCCESS ? 0 : -EIO;
814 815 816 817 818 819 820 821 822 823 824 825
}

static int toshiba_usb_sleep_charge_set(struct toshiba_acpi_dev *dev,
					u32 mode)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_write(dev, SCI_USB_SLEEP_CHARGE, mode);
	sci_close(dev);
826
	if (result == TOS_FAILURE)
827
		pr_err("ACPI call to set USB S&C mode failed\n");
828
	else if (result == TOS_NOT_SUPPORTED)
829 830
		return -ENODEV;

831
	return result == TOS_SUCCESS ? 0 : -EIO;
832 833
}

834 835 836 837 838 839 840 841 842 843 844 845 846
static int toshiba_sleep_functions_status_get(struct toshiba_acpi_dev *dev,
					      u32 *mode)
{
	u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	if (!sci_open(dev))
		return -EIO;

	in[5] = SCI_USB_CHARGE_BAT_LVL;
	status = tci_raw(dev, in, out);
	sci_close(dev);
847
	if (ACPI_FAILURE(status)) {
848 849 850
		pr_err("ACPI call to get USB S&C battery level failed\n");
	} else if (out[0] == TOS_NOT_SUPPORTED) {
		return -ENODEV;
851 852 853
	} else if (out[0] == TOS_SUCCESS) {
		*mode = out[2];
		return 0;
854 855
	}

856
	return -EIO;
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
}

static int toshiba_sleep_functions_status_set(struct toshiba_acpi_dev *dev,
					      u32 mode)
{
	u32 in[TCI_WORDS] = { SCI_SET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	if (!sci_open(dev))
		return -EIO;

	in[2] = mode;
	in[5] = SCI_USB_CHARGE_BAT_LVL;
	status = tci_raw(dev, in, out);
	sci_close(dev);
873
	if (ACPI_FAILURE(status))
874
		pr_err("ACPI call to set USB S&C battery level failed\n");
875
	else if (out[0] == TOS_NOT_SUPPORTED)
876 877
		return -ENODEV;

878
	return out[0] == TOS_SUCCESS ? 0 : -EIO;
879 880
}

881 882 883 884 885 886 887 888 889 890 891 892 893
static int toshiba_usb_rapid_charge_get(struct toshiba_acpi_dev *dev,
					u32 *state)
{
	u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	if (!sci_open(dev))
		return -EIO;

	in[5] = SCI_USB_CHARGE_RAPID_DSP;
	status = tci_raw(dev, in, out);
	sci_close(dev);
894
	if (ACPI_FAILURE(status)) {
895
		pr_err("ACPI call to get USB Rapid Charge failed\n");
896
	} else if (out[0] == TOS_NOT_SUPPORTED) {
897
		return -ENODEV;
898 899 900
	} else if (out[0] == TOS_SUCCESS || out[0] == TOS_SUCCESS2) {
		*state = out[2];
		return 0;
901 902
	}

903
	return -EIO;
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
}

static int toshiba_usb_rapid_charge_set(struct toshiba_acpi_dev *dev,
					u32 state)
{
	u32 in[TCI_WORDS] = { SCI_SET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	if (!sci_open(dev))
		return -EIO;

	in[2] = state;
	in[5] = SCI_USB_CHARGE_RAPID_DSP;
	status = tci_raw(dev, in, out);
	sci_close(dev);
920
	if (ACPI_FAILURE(status))
921
		pr_err("ACPI call to set USB Rapid Charge failed\n");
922
	else if (out[0] == TOS_NOT_SUPPORTED)
923 924
		return -ENODEV;

925
	return (out[0] == TOS_SUCCESS || out[0] == TOS_SUCCESS2) ? 0 : -EIO;
926 927
}

928 929 930 931 932 933 934 935 936
static int toshiba_usb_sleep_music_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state);
	sci_close(dev);
937
	if (result == TOS_FAILURE)
938
		pr_err("ACPI call to get Sleep and Music failed\n");
939
	else if (result == TOS_NOT_SUPPORTED)
940 941
		return -ENODEV;

942
	return result == TOS_SUCCESS ? 0 : -EIO;
943 944 945 946 947 948 949 950 951 952 953
}

static int toshiba_usb_sleep_music_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state);
	sci_close(dev);
954
	if (result == TOS_FAILURE)
955
		pr_err("ACPI call to set Sleep and Music failed\n");
956
	else if (result == TOS_NOT_SUPPORTED)
957 958
		return -ENODEV;

959
	return result == TOS_SUCCESS ? 0 : -EIO;
960 961
}

962 963 964 965 966 967 968 969 970 971
/* Keyboard function keys */
static int toshiba_function_keys_get(struct toshiba_acpi_dev *dev, u32 *mode)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_read(dev, SCI_KBD_FUNCTION_KEYS, mode);
	sci_close(dev);
972
	if (result == TOS_FAILURE)
973
		pr_err("ACPI call to get KBD function keys failed\n");
974
	else if (result == TOS_NOT_SUPPORTED)
975 976
		return -ENODEV;

977
	return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO;
978 979 980 981 982 983 984 985 986 987 988
}

static int toshiba_function_keys_set(struct toshiba_acpi_dev *dev, u32 mode)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_write(dev, SCI_KBD_FUNCTION_KEYS, mode);
	sci_close(dev);
989
	if (result == TOS_FAILURE)
990
		pr_err("ACPI call to set KBD function keys failed\n");
991
	else if (result == TOS_NOT_SUPPORTED)
992 993
		return -ENODEV;

994
	return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO;
995 996
}

997 998 999 1000 1001 1002 1003 1004 1005 1006
/* Panel Power ON */
static int toshiba_panel_power_on_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_read(dev, SCI_PANEL_POWER_ON, state);
	sci_close(dev);
1007
	if (result == TOS_FAILURE)
1008
		pr_err("ACPI call to get Panel Power ON failed\n");
1009
	else if (result == TOS_NOT_SUPPORTED)
1010 1011
		return -ENODEV;

1012
	return result == TOS_SUCCESS ? 0 : -EIO;
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
}

static int toshiba_panel_power_on_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_write(dev, SCI_PANEL_POWER_ON, state);
	sci_close(dev);
1024
	if (result == TOS_FAILURE)
1025
		pr_err("ACPI call to set Panel Power ON failed\n");
1026
	else if (result == TOS_NOT_SUPPORTED)
1027 1028
		return -ENODEV;

1029
	return result == TOS_SUCCESS ? 0 : -EIO;
1030 1031
}

1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
/* USB Three */
static int toshiba_usb_three_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_read(dev, SCI_USB_THREE, state);
	sci_close(dev);
1042
	if (result == TOS_FAILURE)
1043
		pr_err("ACPI call to get USB 3 failed\n");
1044
	else if (result == TOS_NOT_SUPPORTED)
1045 1046
		return -ENODEV;

1047
	return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO;
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
}

static int toshiba_usb_three_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result;

	if (!sci_open(dev))
		return -EIO;

	result = sci_write(dev, SCI_USB_THREE, state);
	sci_close(dev);
1059
	if (result == TOS_FAILURE)
1060
		pr_err("ACPI call to set USB 3 failed\n");
1061
	else if (result == TOS_NOT_SUPPORTED)
1062 1063
		return -ENODEV;

1064
	return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO;
1065 1066
}

1067 1068 1069 1070
/* Hotkey Event type */
static int toshiba_hotkey_event_type_get(struct toshiba_acpi_dev *dev,
					 u32 *type)
{
1071 1072 1073
	u32 in[TCI_WORDS] = { HCI_GET, HCI_SYSTEM_INFO, 0x03, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;
1074

1075 1076
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
1077
		pr_err("ACPI call to get System type failed\n");
1078
	} else if (out[0] == TOS_NOT_SUPPORTED) {
1079
		return -ENODEV;
1080 1081 1082
	} else if (out[0] == TOS_SUCCESS) {
		*type = out[3];
		return 0;
1083 1084
	}

1085
	return -EIO;
1086 1087
}

A
Azael Avalos 已提交
1088
/* Transflective Backlight */
1089
static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 *status)
1090
{
1091 1092 1093 1094 1095 1096
	u32 result = hci_read(dev, HCI_TR_BACKLIGHT, status);

	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Transflective Backlight failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;
1097

1098
	return result == TOS_SUCCESS ? 0 : -EIO;
1099 1100
}

1101
static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 status)
1102
{
1103
	u32 result = hci_write(dev, HCI_TR_BACKLIGHT, !status);
1104

1105 1106 1107 1108 1109 1110
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Transflective Backlight failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

	return result == TOS_SUCCESS ? 0 : -EIO;
1111 1112
}

A
Azael Avalos 已提交
1113
static struct proc_dir_entry *toshiba_proc_dir;
L
Linus Torvalds 已提交
1114

A
Azael Avalos 已提交
1115
/* LCD Brightness */
1116
static int __get_lcd_brightness(struct toshiba_acpi_dev *dev)
L
Linus Torvalds 已提交
1117
{
1118
	u32 result;
L
Linus Torvalds 已提交
1119
	u32 value;
1120 1121 1122
	int brightness = 0;

	if (dev->tr_backlight_supported) {
1123
		int ret = get_tr_backlight_status(dev, &value);
1124

1125 1126
		if (ret)
			return ret;
1127
		if (value)
1128 1129 1130
			return 0;
		brightness++;
	}
L
Linus Torvalds 已提交
1131

1132 1133 1134 1135 1136 1137
	result = hci_read(dev, HCI_LCD_BRIGHTNESS, &value);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get LCD Brightness failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;
	if (result == TOS_SUCCESS)
1138
		return brightness + (value >> HCI_LCD_BRIGHTNESS_SHIFT);
S
Seth Forshee 已提交
1139 1140

	return -EIO;
1141 1142
}

1143 1144 1145
static int get_lcd_brightness(struct backlight_device *bd)
{
	struct toshiba_acpi_dev *dev = bl_get_data(bd);
1146

1147 1148 1149
	return __get_lcd_brightness(dev);
}

1150
static int lcd_proc_show(struct seq_file *m, void *v)
1151
{
1152
	struct toshiba_acpi_dev *dev = m->private;
1153
	int levels;
1154
	int value;
1155 1156 1157

	if (!dev->backlight_dev)
		return -ENODEV;
1158

1159
	levels = dev->backlight_dev->props.max_brightness + 1;
1160
	value = get_lcd_brightness(dev->backlight_dev);
1161
	if (value >= 0) {
1162
		seq_printf(m, "brightness:              %d\n", value);
1163
		seq_printf(m, "brightness_levels:       %d\n", levels);
S
Seth Forshee 已提交
1164
		return 0;
L
Linus Torvalds 已提交
1165 1166
	}

S
Seth Forshee 已提交
1167
	pr_err("Error reading LCD brightness\n");
1168

S
Seth Forshee 已提交
1169
	return -EIO;
1170 1171 1172 1173
}

static int lcd_proc_open(struct inode *inode, struct file *file)
{
A
Al Viro 已提交
1174
	return single_open(file, lcd_proc_show, PDE_DATA(inode));
L
Linus Torvalds 已提交
1175 1176
}

1177
static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
1178
{
1179
	u32 result;
1180

1181
	if (dev->tr_backlight_supported) {
1182
		int ret = set_tr_backlight_status(dev, !value);
1183

1184 1185 1186 1187 1188 1189
		if (ret)
			return ret;
		if (value)
			value--;
	}

1190
	value = value << HCI_LCD_BRIGHTNESS_SHIFT;
1191 1192 1193 1194 1195 1196 1197
	result = hci_write(dev, HCI_LCD_BRIGHTNESS, value);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set LCD Brightness failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

	return result == TOS_SUCCESS ? 0 : -EIO;
1198 1199 1200 1201
}

static int set_lcd_status(struct backlight_device *bd)
{
1202
	struct toshiba_acpi_dev *dev = bl_get_data(bd);
1203

1204
	return set_lcd_brightness(dev, bd->props.brightness);
1205 1206
}

1207 1208
static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *pos)
L
Linus Torvalds 已提交
1209
{
A
Al Viro 已提交
1210
	struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
1211 1212
	char cmd[42];
	size_t len;
1213
	int levels = dev->backlight_dev->props.max_brightness + 1;
1214
	int value;
L
Linus Torvalds 已提交
1215

1216 1217 1218 1219 1220
	len = min(count, sizeof(cmd) - 1);
	if (copy_from_user(cmd, buf, len))
		return -EFAULT;
	cmd[len] = '\0';

1221 1222 1223 1224 1225 1226 1227 1228
	if (sscanf(cmd, " brightness : %i", &value) != 1 &&
	    value < 0 && value > levels)
		return -EINVAL;

	if (set_lcd_brightness(dev, value))
		return -EIO;

	return count;
L
Linus Torvalds 已提交
1229 1230
}

1231 1232 1233 1234 1235 1236 1237 1238 1239
static const struct file_operations lcd_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= lcd_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= lcd_proc_write,
};

1240
/* Video-Out */
1241 1242
static int get_video_status(struct toshiba_acpi_dev *dev, u32 *status)
{
1243
	u32 result = hci_read(dev, HCI_VIDEO_OUT, status);
1244

1245 1246 1247 1248 1249 1250
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Video-Out failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

	return result == TOS_SUCCESS ? 0 : -EIO;
1251 1252
}

1253
static int video_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
1254
{
1255
	struct toshiba_acpi_dev *dev = m->private;
L
Linus Torvalds 已提交
1256 1257
	u32 value;

1258
	if (!get_video_status(dev, &value)) {
L
Linus Torvalds 已提交
1259 1260
		int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
		int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
L
Len Brown 已提交
1261
		int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
1262

1263 1264 1265
		seq_printf(m, "lcd_out:                 %d\n", is_lcd);
		seq_printf(m, "crt_out:                 %d\n", is_crt);
		seq_printf(m, "tv_out:                  %d\n", is_tv);
1266
		return 0;
L
Linus Torvalds 已提交
1267 1268
	}

1269
	return -EIO;
L
Linus Torvalds 已提交
1270 1271
}

1272
static int video_proc_open(struct inode *inode, struct file *file)
L
Linus Torvalds 已提交
1273
{
A
Al Viro 已提交
1274
	return single_open(file, video_proc_show, PDE_DATA(inode));
1275 1276 1277 1278 1279
}

static ssize_t video_proc_write(struct file *file, const char __user *buf,
				size_t count, loff_t *pos)
{
A
Al Viro 已提交
1280
	struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
1281 1282
	char *buffer;
	char *cmd;
L
Linus Torvalds 已提交
1283 1284 1285 1286
	int remain = count;
	int lcd_out = -1;
	int crt_out = -1;
	int tv_out = -1;
1287 1288
	int value;
	int ret;
A
Al Viro 已提交
1289
	u32 video_out;
L
Linus Torvalds 已提交
1290

1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
	cmd = kmalloc(count + 1, GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;
	if (copy_from_user(cmd, buf, count)) {
		kfree(cmd);
		return -EFAULT;
	}
	cmd[count] = '\0';

	buffer = cmd;

1302 1303 1304
	/*
	 * Scan expression.  Multiple expressions may be delimited with ;
	 * NOTE: To keep scanning simple, invalid fields are ignored.
L
Linus Torvalds 已提交
1305 1306 1307 1308 1309 1310 1311 1312
	 */
	while (remain) {
		if (sscanf(buffer, " lcd_out : %i", &value) == 1)
			lcd_out = value & 1;
		else if (sscanf(buffer, " crt_out : %i", &value) == 1)
			crt_out = value & 1;
		else if (sscanf(buffer, " tv_out : %i", &value) == 1)
			tv_out = value & 1;
1313
		/* Advance to one character past the next ; */
L
Linus Torvalds 已提交
1314 1315 1316
		do {
			++buffer;
			--remain;
1317
		} while (remain && *(buffer - 1) != ';');
L
Linus Torvalds 已提交
1318 1319
	}

1320 1321
	kfree(cmd);

1322 1323
	ret = get_video_status(dev, &video_out);
	if (!ret) {
1324
		unsigned int new_video_out = video_out;
1325

L
Linus Torvalds 已提交
1326 1327 1328 1329 1330 1331
		if (lcd_out != -1)
			_set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
		if (crt_out != -1)
			_set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out);
		if (tv_out != -1)
			_set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out);
1332 1333
		/*
		 * To avoid unnecessary video disruption, only write the new
A
Azael Avalos 已提交
1334 1335
		 * video setting if something changed.
		 */
L
Linus Torvalds 已提交
1336
		if (new_video_out != video_out)
S
Seth Forshee 已提交
1337
			ret = write_acpi_int(METHOD_VIDEO_OUT, new_video_out);
L
Linus Torvalds 已提交
1338 1339
	}

1340
	return ret ? -EIO : count;
L
Linus Torvalds 已提交
1341 1342
}

1343 1344 1345 1346 1347 1348 1349 1350 1351
static const struct file_operations video_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= video_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= video_proc_write,
};

1352
/* Fan status */
1353 1354
static int get_fan_status(struct toshiba_acpi_dev *dev, u32 *status)
{
1355
	u32 result = hci_read(dev, HCI_FAN, status);
1356

1357 1358 1359 1360 1361
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Fan status failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

1362
	return result == TOS_SUCCESS ? 0 : -EIO;
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
}

static int set_fan_status(struct toshiba_acpi_dev *dev, u32 status)
{
	u32 result = hci_write(dev, HCI_FAN, status);

	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Fan status failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

1374
	return result == TOS_SUCCESS ? 0 : -EIO;
1375 1376
}

1377
static int fan_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
1378
{
1379
	struct toshiba_acpi_dev *dev = m->private;
L
Linus Torvalds 已提交
1380 1381
	u32 value;

1382 1383
	if (get_fan_status(dev, &value))
		return -EIO;
L
Linus Torvalds 已提交
1384

1385 1386 1387 1388
	seq_printf(m, "running:                 %d\n", (value > 0));
	seq_printf(m, "force_on:                %d\n", dev->force_fan);

	return 0;
1389 1390 1391 1392
}

static int fan_proc_open(struct inode *inode, struct file *file)
{
A
Al Viro 已提交
1393
	return single_open(file, fan_proc_show, PDE_DATA(inode));
L
Linus Torvalds 已提交
1394 1395
}

1396 1397
static ssize_t fan_proc_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *pos)
L
Linus Torvalds 已提交
1398
{
A
Al Viro 已提交
1399
	struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
1400 1401
	char cmd[42];
	size_t len;
L
Linus Torvalds 已提交
1402 1403
	int value;

1404 1405 1406 1407 1408
	len = min(count, sizeof(cmd) - 1);
	if (copy_from_user(cmd, buf, len))
		return -EFAULT;
	cmd[len] = '\0';

1409 1410
	if (sscanf(cmd, " force_on : %i", &value) != 1 &&
	    value != 0 && value != 1)
L
Linus Torvalds 已提交
1411
		return -EINVAL;
1412 1413 1414 1415 1416

	if (set_fan_status(dev, value))
		return -EIO;

	dev->force_fan = value;
L
Linus Torvalds 已提交
1417 1418 1419 1420

	return count;
}

1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
static const struct file_operations fan_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= fan_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= fan_proc_write,
};

static int keys_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
1431
{
1432
	struct toshiba_acpi_dev *dev = m->private;
L
Linus Torvalds 已提交
1433

1434 1435
	seq_printf(m, "hotkey_ready:            %d\n", dev->key_event_valid);
	seq_printf(m, "hotkey:                  0x%04x\n", dev->last_key_event);
1436

1437 1438
	return 0;
}
L
Linus Torvalds 已提交
1439

1440 1441
static int keys_proc_open(struct inode *inode, struct file *file)
{
A
Al Viro 已提交
1442
	return single_open(file, keys_proc_show, PDE_DATA(inode));
L
Linus Torvalds 已提交
1443 1444
}

1445 1446
static ssize_t keys_proc_write(struct file *file, const char __user *buf,
			       size_t count, loff_t *pos)
L
Linus Torvalds 已提交
1447
{
A
Al Viro 已提交
1448
	struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
1449 1450
	char cmd[42];
	size_t len;
L
Linus Torvalds 已提交
1451 1452
	int value;

1453 1454 1455 1456 1457
	len = min(count, sizeof(cmd) - 1);
	if (copy_from_user(cmd, buf, len))
		return -EFAULT;
	cmd[len] = '\0';

1458
	if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0)
1459
		dev->key_event_valid = 0;
1460
	else
L
Linus Torvalds 已提交
1461 1462 1463 1464 1465
		return -EINVAL;

	return count;
}

1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
static const struct file_operations keys_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= keys_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= keys_proc_write,
};

static int version_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
1476
{
1477 1478 1479
	seq_printf(m, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
	seq_printf(m, "proc_interface:          %d\n", PROC_INTERFACE_VERSION);
	return 0;
L
Linus Torvalds 已提交
1480 1481
}

1482 1483
static int version_proc_open(struct inode *inode, struct file *file)
{
A
Al Viro 已提交
1484
	return single_open(file, version_proc_show, PDE_DATA(inode));
1485 1486 1487 1488 1489 1490 1491 1492 1493 1494
}

static const struct file_operations version_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= version_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

1495 1496
/*
 * Proc and module init
L
Linus Torvalds 已提交
1497 1498 1499 1500
 */

#define PROC_TOSHIBA		"toshiba"

1501
static void create_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
L
Linus Torvalds 已提交
1502
{
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514
	if (dev->backlight_dev)
		proc_create_data("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &lcd_proc_fops, dev);
	if (dev->video_supported)
		proc_create_data("video", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &video_proc_fops, dev);
	if (dev->fan_supported)
		proc_create_data("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &fan_proc_fops, dev);
	if (dev->hotkey_dev)
		proc_create_data("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &keys_proc_fops, dev);
1515 1516
	proc_create_data("version", S_IRUGO, toshiba_proc_dir,
			 &version_proc_fops, dev);
L
Linus Torvalds 已提交
1517 1518
}

1519
static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
L
Linus Torvalds 已提交
1520
{
1521 1522 1523 1524 1525 1526 1527 1528
	if (dev->backlight_dev)
		remove_proc_entry("lcd", toshiba_proc_dir);
	if (dev->video_supported)
		remove_proc_entry("video", toshiba_proc_dir);
	if (dev->fan_supported)
		remove_proc_entry("fan", toshiba_proc_dir);
	if (dev->hotkey_dev)
		remove_proc_entry("keys", toshiba_proc_dir);
1529
	remove_proc_entry("version", toshiba_proc_dir);
L
Linus Torvalds 已提交
1530 1531
}

L
Lionel Debroux 已提交
1532
static const struct backlight_ops toshiba_backlight_data = {
1533
	.options = BL_CORE_SUSPENDRESUME,
1534 1535
	.get_brightness = get_lcd_brightness,
	.update_status  = set_lcd_status,
1536
};
M
Matthew Garrett 已提交
1537

1538 1539 1540
/*
 * Sysfs files
 */
1541 1542
static ssize_t version_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
1543 1544 1545
{
	return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION);
}
1546
static DEVICE_ATTR_RO(version);
1547

1548 1549 1550
static ssize_t fan_store(struct device *dev,
			 struct device_attribute *attr,
			 const char *buf, size_t count)
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;

	if (state != 0 && state != 1)
		return -EINVAL;

1563 1564 1565
	ret = set_fan_status(toshiba, state);
	if (ret)
		return ret;
1566 1567 1568 1569

	return count;
}

1570 1571
static ssize_t fan_show(struct device *dev,
			struct device_attribute *attr, char *buf)
1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 value;
	int ret;

	ret = get_fan_status(toshiba, &value);
	if (ret)
		return ret;

	return sprintf(buf, "%d\n", value);
}
1583
static DEVICE_ATTR_RW(fan);
1584

1585 1586 1587
static ssize_t kbd_backlight_mode_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
1588 1589
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1590 1591 1592
	int mode;
	int ret;

1593

1594 1595 1596
	ret = kstrtoint(buf, 0, &mode);
	if (ret)
		return ret;
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608

	/* Check for supported modes depending on keyboard backlight type */
	if (toshiba->kbd_type == 1) {
		/* Type 1 supports SCI_KBD_MODE_FNZ and SCI_KBD_MODE_AUTO */
		if (mode != SCI_KBD_MODE_FNZ && mode != SCI_KBD_MODE_AUTO)
			return -EINVAL;
	} else if (toshiba->kbd_type == 2) {
		/* Type 2 doesn't support SCI_KBD_MODE_FNZ */
		if (mode != SCI_KBD_MODE_AUTO && mode != SCI_KBD_MODE_ON &&
		    mode != SCI_KBD_MODE_OFF)
			return -EINVAL;
	}
1609

1610 1611
	/*
	 * Set the Keyboard Backlight Mode where:
1612 1613
	 *	Auto - KBD backlight turns off automatically in given time
	 *	FN-Z - KBD backlight "toggles" when hotkey pressed
1614 1615
	 *	ON   - KBD backlight is always on
	 *	OFF  - KBD backlight is always off
1616
	 */
1617 1618

	/* Only make a change if the actual mode has changed */
1619
	if (toshiba->kbd_mode != mode) {
1620
		/* Shift the time to "base time" (0x3c0000 == 60 seconds) */
1621
		int time = toshiba->kbd_time << HCI_MISC_SHIFT;
1622 1623 1624 1625 1626 1627 1628 1629 1630 1631

		/* OR the "base time" to the actual method format */
		if (toshiba->kbd_type == 1) {
			/* Type 1 requires the current mode */
			time |= toshiba->kbd_mode;
		} else if (toshiba->kbd_type == 2) {
			/* Type 2 requires the desired mode */
			time |= mode;
		}

1632 1633 1634
		ret = toshiba_kbd_illum_status_set(toshiba, time);
		if (ret)
			return ret;
1635

1636 1637 1638 1639 1640 1641
		toshiba->kbd_mode = mode;
	}

	return count;
}

1642 1643 1644
static ssize_t kbd_backlight_mode_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
1645 1646 1647 1648 1649 1650 1651
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 time;

	if (toshiba_kbd_illum_status_get(toshiba, &time) < 0)
		return -EIO;

1652 1653
	return sprintf(buf, "%i\n", time & SCI_KBD_MODE_MASK);
}
1654
static DEVICE_ATTR_RW(kbd_backlight_mode);
1655

1656 1657
static ssize_t kbd_type_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
1658 1659 1660 1661 1662
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);

	return sprintf(buf, "%d\n", toshiba->kbd_type);
}
1663
static DEVICE_ATTR_RO(kbd_type);
1664

1665 1666 1667
static ssize_t available_kbd_modes_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
1668 1669 1670 1671
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);

	if (toshiba->kbd_type == 1)
1672
		return sprintf(buf, "0x%x 0x%x\n",
1673 1674
			       SCI_KBD_MODE_FNZ, SCI_KBD_MODE_AUTO);

1675
	return sprintf(buf, "0x%x 0x%x 0x%x\n",
1676
		       SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF);
1677
}
1678
static DEVICE_ATTR_RO(available_kbd_modes);
1679

1680 1681 1682
static ssize_t kbd_backlight_timeout_store(struct device *dev,
					   struct device_attribute *attr,
					   const char *buf, size_t count)
1683 1684
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1685 1686
	int time;
	int ret;
1687

1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
	ret = kstrtoint(buf, 0, &time);
	if (ret)
		return ret;

	/* Check for supported values depending on kbd_type */
	if (toshiba->kbd_type == 1) {
		if (time < 0 || time > 60)
			return -EINVAL;
	} else if (toshiba->kbd_type == 2) {
		if (time < 1 || time > 60)
			return -EINVAL;
	}

	/* Set the Keyboard Backlight Timeout */
1702

1703 1704 1705
	/* Only make a change if the actual timeout has changed */
	if (toshiba->kbd_time != time) {
		/* Shift the time to "base time" (0x3c0000 == 60 seconds) */
1706
		time = time << HCI_MISC_SHIFT;
1707 1708 1709 1710 1711 1712 1713 1714 1715 1716
		/* OR the "base time" to the actual method format */
		if (toshiba->kbd_type == 1)
			time |= SCI_KBD_MODE_FNZ;
		else if (toshiba->kbd_type == 2)
			time |= SCI_KBD_MODE_AUTO;

		ret = toshiba_kbd_illum_status_set(toshiba, time);
		if (ret)
			return ret;

1717 1718 1719 1720 1721 1722
		toshiba->kbd_time = time >> HCI_MISC_SHIFT;
	}

	return count;
}

1723 1724 1725
static ssize_t kbd_backlight_timeout_show(struct device *dev,
					  struct device_attribute *attr,
					  char *buf)
1726 1727 1728 1729 1730 1731 1732 1733 1734
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 time;

	if (toshiba_kbd_illum_status_get(toshiba, &time) < 0)
		return -EIO;

	return sprintf(buf, "%i\n", time >> HCI_MISC_SHIFT);
}
1735
static DEVICE_ATTR_RW(kbd_backlight_timeout);
M
Matthew Garrett 已提交
1736

1737 1738 1739
static ssize_t touchpad_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buf, size_t count)
1740 1741 1742
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
1743
	int ret;
1744 1745

	/* Set the TouchPad on/off, 0 - Disable | 1 - Enable */
1746 1747 1748 1749 1750 1751 1752 1753 1754
	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	if (state != 0 && state != 1)
		return -EINVAL;

	ret = toshiba_touchpad_set(toshiba, state);
	if (ret)
		return ret;
1755 1756 1757 1758

	return count;
}

1759 1760
static ssize_t touchpad_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int ret;

	ret = toshiba_touchpad_get(toshiba, &state);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%i\n", state);
}
1772
static DEVICE_ATTR_RW(touchpad);
M
Matthew Garrett 已提交
1773

1774 1775
static ssize_t position_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 xyval, zval, tmp;
	u16 x, y, z;
	int ret;

	xyval = zval = 0;
	ret = toshiba_accelerometer_get(toshiba, &xyval, &zval);
	if (ret < 0)
		return ret;

	x = xyval & HCI_ACCEL_MASK;
	tmp = xyval >> HCI_MISC_SHIFT;
	y = tmp & HCI_ACCEL_MASK;
	z = zval & HCI_ACCEL_MASK;

	return sprintf(buf, "%d %d %d\n", x, y, z);
}
1794
static DEVICE_ATTR_RO(position);
1795

1796 1797
static ssize_t usb_sleep_charge_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 mode;
	int ret;

	ret = toshiba_usb_sleep_charge_get(toshiba, &mode);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%x\n", mode & SCI_USB_CHARGE_MODE_MASK);
}

1810 1811 1812
static ssize_t usb_sleep_charge_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
1813 1814 1815 1816 1817 1818 1819 1820 1821
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 mode;
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
1822 1823
	/*
	 * Check for supported values, where:
1824 1825 1826
	 * 0 - Disabled
	 * 1 - Alternate (Non USB conformant devices that require more power)
	 * 2 - Auto (USB conformant devices)
1827
	 * 3 - Typical
1828
	 */
1829
	if (state != 0 && state != 1 && state != 2 && state != 3)
1830 1831 1832
		return -EINVAL;

	/* Set the USB charging mode to internal value */
1833
	mode = toshiba->usbsc_mode_base;
1834
	if (state == 0)
1835
		mode |= SCI_USB_CHARGE_DISABLED;
1836
	else if (state == 1)
1837
		mode |= SCI_USB_CHARGE_ALTERNATE;
1838
	else if (state == 2)
1839 1840 1841
		mode |= SCI_USB_CHARGE_AUTO;
	else if (state == 3)
		mode |= SCI_USB_CHARGE_TYPICAL;
1842 1843 1844 1845 1846 1847 1848

	ret = toshiba_usb_sleep_charge_set(toshiba, mode);
	if (ret)
		return ret;

	return count;
}
1849
static DEVICE_ATTR_RW(usb_sleep_charge);
1850

1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888
static ssize_t sleep_functions_on_battery_show(struct device *dev,
					       struct device_attribute *attr,
					       char *buf)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int bat_lvl;
	int status;
	int ret;
	int tmp;

	ret = toshiba_sleep_functions_status_get(toshiba, &state);
	if (ret < 0)
		return ret;

	/* Determine the status: 0x4 - Enabled | 0x1 - Disabled */
	tmp = state & SCI_USB_CHARGE_BAT_MASK;
	status = (tmp == 0x4) ? 1 : 0;
	/* Determine the battery level set */
	bat_lvl = state >> HCI_MISC_SHIFT;

	return sprintf(buf, "%d %d\n", status, bat_lvl);
}

static ssize_t sleep_functions_on_battery_store(struct device *dev,
						struct device_attribute *attr,
						const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 status;
	int value;
	int ret;
	int tmp;

	ret = kstrtoint(buf, 0, &value);
	if (ret)
		return ret;

1889 1890
	/*
	 * Set the status of the function:
1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911
	 * 0 - Disabled
	 * 1-100 - Enabled
	 */
	if (value < 0 || value > 100)
		return -EINVAL;

	if (value == 0) {
		tmp = toshiba->usbsc_bat_level << HCI_MISC_SHIFT;
		status = tmp | SCI_USB_CHARGE_BAT_LVL_OFF;
	} else {
		tmp = value << HCI_MISC_SHIFT;
		status = tmp | SCI_USB_CHARGE_BAT_LVL_ON;
	}
	ret = toshiba_sleep_functions_status_set(toshiba, status);
	if (ret < 0)
		return ret;

	toshiba->usbsc_bat_level = status >> HCI_MISC_SHIFT;

	return count;
}
1912
static DEVICE_ATTR_RW(sleep_functions_on_battery);
1913

1914 1915
static ssize_t usb_rapid_charge_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int ret;

	ret = toshiba_usb_rapid_charge_get(toshiba, &state);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%d\n", state);
}

1928 1929 1930
static ssize_t usb_rapid_charge_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	if (state != 0 && state != 1)
		return -EINVAL;

	ret = toshiba_usb_rapid_charge_set(toshiba, state);
	if (ret)
		return ret;

	return count;
}
1948
static DEVICE_ATTR_RW(usb_rapid_charge);
1949

1950 1951
static ssize_t usb_sleep_music_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int ret;

	ret = toshiba_usb_sleep_music_get(toshiba, &state);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%d\n", state);
}

1964 1965 1966
static ssize_t usb_sleep_music_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	if (state != 0 && state != 1)
		return -EINVAL;

	ret = toshiba_usb_sleep_music_set(toshiba, state);
	if (ret)
		return ret;

	return count;
}
1984
static DEVICE_ATTR_RW(usb_sleep_music);
1985

1986 1987
static ssize_t kbd_function_keys_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int mode;
	int ret;

	ret = toshiba_function_keys_get(toshiba, &mode);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%d\n", mode);
}

2000 2001 2002
static ssize_t kbd_function_keys_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
2003 2004 2005 2006 2007 2008 2009 2010
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int mode;
	int ret;

	ret = kstrtoint(buf, 0, &mode);
	if (ret)
		return ret;
2011 2012
	/*
	 * Check for the function keys mode where:
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026
	 * 0 - Normal operation (F{1-12} as usual and hotkeys via FN-F{1-12})
	 * 1 - Special functions (Opposite of the above setting)
	 */
	if (mode != 0 && mode != 1)
		return -EINVAL;

	ret = toshiba_function_keys_set(toshiba, mode);
	if (ret)
		return ret;

	pr_info("Reboot for changes to KBD Function Keys to take effect");

	return count;
}
2027
static DEVICE_ATTR_RW(kbd_function_keys);
2028

2029 2030
static ssize_t panel_power_on_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int ret;

	ret = toshiba_panel_power_on_get(toshiba, &state);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%d\n", state);
}

2043 2044 2045
static ssize_t panel_power_on_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	if (state != 0 && state != 1)
		return -EINVAL;

	ret = toshiba_panel_power_on_set(toshiba, state);
	if (ret)
		return ret;

	pr_info("Reboot for changes to Panel Power ON to take effect");

	return count;
}
2065
static DEVICE_ATTR_RW(panel_power_on);
2066

2067 2068
static ssize_t usb_three_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	u32 state;
	int ret;

	ret = toshiba_usb_three_get(toshiba, &state);
	if (ret < 0)
		return ret;

	return sprintf(buf, "%d\n", state);
}

2081 2082 2083
static ssize_t usb_three_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
2084 2085 2086 2087 2088 2089 2090 2091
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
2092 2093
	/*
	 * Check for USB 3 mode where:
2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
	 * 0 - Disabled (Acts like a USB 2 port, saving power)
	 * 1 - Enabled
	 */
	if (state != 0 && state != 1)
		return -EINVAL;

	ret = toshiba_usb_three_set(toshiba, state);
	if (ret)
		return ret;

	pr_info("Reboot for changes to USB 3 to take effect");

	return count;
}
2108
static DEVICE_ATTR_RW(usb_three);
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128

static struct attribute *toshiba_attributes[] = {
	&dev_attr_version.attr,
	&dev_attr_fan.attr,
	&dev_attr_kbd_backlight_mode.attr,
	&dev_attr_kbd_type.attr,
	&dev_attr_available_kbd_modes.attr,
	&dev_attr_kbd_backlight_timeout.attr,
	&dev_attr_touchpad.attr,
	&dev_attr_position.attr,
	&dev_attr_usb_sleep_charge.attr,
	&dev_attr_sleep_functions_on_battery.attr,
	&dev_attr_usb_rapid_charge.attr,
	&dev_attr_usb_sleep_music.attr,
	&dev_attr_kbd_function_keys.attr,
	&dev_attr_panel_power_on.attr,
	&dev_attr_usb_three.attr,
	NULL,
};

2129 2130 2131 2132 2133 2134 2135
static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
					struct attribute *attr, int idx)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct toshiba_acpi_dev *drv = dev_get_drvdata(dev);
	bool exists = true;

2136 2137 2138
	if (attr == &dev_attr_fan.attr)
		exists = (drv->fan_supported) ? true : false;
	else if (attr == &dev_attr_kbd_backlight_mode.attr)
2139 2140 2141
		exists = (drv->kbd_illum_supported) ? true : false;
	else if (attr == &dev_attr_kbd_backlight_timeout.attr)
		exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false;
2142 2143
	else if (attr == &dev_attr_touchpad.attr)
		exists = (drv->touchpad_supported) ? true : false;
2144 2145
	else if (attr == &dev_attr_position.attr)
		exists = (drv->accelerometer_supported) ? true : false;
2146 2147
	else if (attr == &dev_attr_usb_sleep_charge.attr)
		exists = (drv->usb_sleep_charge_supported) ? true : false;
2148 2149
	else if (attr == &dev_attr_sleep_functions_on_battery.attr)
		exists = (drv->usb_sleep_charge_supported) ? true : false;
2150 2151
	else if (attr == &dev_attr_usb_rapid_charge.attr)
		exists = (drv->usb_rapid_charge_supported) ? true : false;
2152 2153
	else if (attr == &dev_attr_usb_sleep_music.attr)
		exists = (drv->usb_sleep_music_supported) ? true : false;
2154 2155
	else if (attr == &dev_attr_kbd_function_keys.attr)
		exists = (drv->kbd_function_keys_supported) ? true : false;
2156 2157
	else if (attr == &dev_attr_panel_power_on.attr)
		exists = (drv->panel_power_on_supported) ? true : false;
2158 2159
	else if (attr == &dev_attr_usb_three.attr)
		exists = (drv->usb_three_supported) ? true : false;
2160 2161 2162 2163

	return exists ? attr->mode : 0;
}

2164 2165 2166 2167 2168
static struct attribute_group toshiba_attr_group = {
	.is_visible = toshiba_sysfs_is_visible,
	.attrs = toshiba_attributes,
};

2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
/*
 * Misc device
 */
static int toshiba_acpi_smm_bridge(SMMRegisters *regs)
{
	u32 in[TCI_WORDS] = { regs->eax, regs->ebx, regs->ecx,
			      regs->edx, regs->esi, regs->edi };
	u32 out[TCI_WORDS];
	acpi_status status;

	status = tci_raw(toshiba_acpi, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to query SMM registers failed\n");
		return -EIO;
	}

	/* Fillout the SMM struct with the TCI call results */
	regs->eax = out[0];
	regs->ebx = out[1];
	regs->ecx = out[2];
	regs->edx = out[3];
	regs->esi = out[4];
	regs->edi = out[5];

	return 0;
}

static long toshiba_acpi_ioctl(struct file *fp, unsigned int cmd,
			       unsigned long arg)
{
	SMMRegisters __user *argp = (SMMRegisters __user *)arg;
	SMMRegisters regs;
	int ret;

	if (!argp)
		return -EINVAL;

	switch (cmd) {
	case TOSH_SMM:
		if (copy_from_user(&regs, argp, sizeof(SMMRegisters)))
			return -EFAULT;
		ret = toshiba_acpi_smm_bridge(&regs);
		if (ret)
			return ret;
		if (copy_to_user(argp, &regs, sizeof(SMMRegisters)))
			return -EFAULT;
		break;
	case TOSHIBA_ACPI_SCI:
		if (copy_from_user(&regs, argp, sizeof(SMMRegisters)))
			return -EFAULT;
		/* Ensure we are being called with a SCI_{GET, SET} register */
		if (regs.eax != SCI_GET && regs.eax != SCI_SET)
			return -EINVAL;
		if (!sci_open(toshiba_acpi))
			return -EIO;
		ret = toshiba_acpi_smm_bridge(&regs);
		sci_close(toshiba_acpi);
		if (ret)
			return ret;
		if (copy_to_user(argp, &regs, sizeof(SMMRegisters)))
			return -EFAULT;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct file_operations toshiba_acpi_fops = {
	.owner		= THIS_MODULE,
	.unlocked_ioctl = toshiba_acpi_ioctl,
	.llseek		= noop_llseek,
};

2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256
/*
 * Hotkeys
 */
static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
{
	acpi_status status;
	u32 result;

	status = acpi_evaluate_object(dev->acpi_dev->handle,
				      "ENAB", NULL, NULL);
	if (ACPI_FAILURE(status))
		return -ENODEV;

2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
	/*
	 * Enable the "Special Functions" mode only if they are
	 * supported and if they are activated.
	 */
	if (dev->kbd_function_keys_supported && dev->special_functions)
		result = hci_write(dev, HCI_HOTKEY_EVENT,
				   HCI_HOTKEY_SPECIAL_FUNCTIONS);
	else
		result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE);

2267 2268 2269 2270 2271 2272 2273 2274
	if (result == TOS_FAILURE)
		return -EIO;
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

	return 0;
}

2275 2276 2277
static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
				      struct serio *port)
{
2278
	if (str & I8042_STR_AUXDATA)
2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309
		return false;

	if (unlikely(data == 0xe0))
		return false;

	if ((data & 0x7f) == TOS1900_FN_SCAN) {
		schedule_work(&toshiba_acpi->hotkey_work);
		return true;
	}

	return false;
}

static void toshiba_acpi_hotkey_work(struct work_struct *work)
{
	acpi_handle ec_handle = ec_get_handle();
	acpi_status status;

	if (!ec_handle)
		return;

	status = acpi_evaluate_object(ec_handle, "NTFY", NULL, NULL);
	if (ACPI_FAILURE(status))
		pr_err("ACPI NTFY method execution failed\n");
}

/*
 * Returns hotkey scancode, or < 0 on failure.
 */
static int toshiba_acpi_query_hotkey(struct toshiba_acpi_dev *dev)
{
2310
	unsigned long long value;
2311 2312
	acpi_status status;

2313 2314 2315
	status = acpi_evaluate_integer(dev->acpi_dev->handle, "INFO",
				      NULL, &value);
	if (ACPI_FAILURE(status)) {
2316 2317 2318 2319
		pr_err("ACPI INFO method execution failed\n");
		return -EIO;
	}

2320
	return value;
2321 2322 2323 2324 2325 2326 2327 2328
}

static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev,
				       int scancode)
{
	if (scancode == 0x100)
		return;

2329
	/* Act on key press; ignore key release */
2330 2331 2332 2333 2334 2335 2336
	if (scancode & 0x80)
		return;

	if (!sparse_keymap_report_event(dev->hotkey_dev, scancode, 1, true))
		pr_info("Unknown key %x\n", scancode);
}

2337 2338 2339
static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev)
{
	if (dev->info_supported) {
2340 2341 2342
		int scancode = toshiba_acpi_query_hotkey(dev);

		if (scancode < 0) {
2343
			pr_err("Failed to query hotkey event\n");
2344
		} else if (scancode != 0) {
2345
			toshiba_acpi_report_hotkey(dev, scancode);
2346 2347 2348
			dev->key_event_valid = 1;
			dev->last_key_event = scancode;
		}
2349
	} else if (dev->system_event_supported) {
2350 2351 2352 2353
		u32 result;
		u32 value;
		int retries = 3;

2354
		do {
2355 2356
			result = hci_read(dev, HCI_SYSTEM_EVENT, &value);
			switch (result) {
2357 2358
			case TOS_SUCCESS:
				toshiba_acpi_report_hotkey(dev, (int)value);
2359 2360
				dev->key_event_valid = 1;
				dev->last_key_event = value;
2361 2362 2363 2364 2365 2366 2367
				break;
			case TOS_NOT_SUPPORTED:
				/*
				 * This is a workaround for an unresolved
				 * issue on some machines where system events
				 * sporadically become disabled.
				 */
2368 2369 2370
				result = hci_write(dev, HCI_SYSTEM_EVENT, 1);
				if (result == TOS_SUCCESS)
					pr_notice("Re-enabled hotkeys\n");
2371
				/* Fall through */
2372 2373 2374 2375
			default:
				retries--;
				break;
			}
2376
		} while (retries && result != TOS_FIFO_EMPTY);
2377 2378 2379
	}
}

2380
static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
2381
{
2382
	const struct key_entry *keymap = toshiba_acpi_keymap;
2383
	acpi_handle ec_handle;
2384 2385
	int error;

2386 2387 2388 2389 2390
	if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) {
		pr_info("WMI event detected, hotkeys will not be monitored\n");
		return 0;
	}

2391 2392 2393 2394
	error = toshiba_acpi_enable_hotkeys(dev);
	if (error)
		return error;

2395
	if (toshiba_hotkey_event_type_get(dev, &dev->hotkey_event_type))
2396 2397
		pr_notice("Unable to query Hotkey Event Type\n");

2398
	dev->hotkey_dev = input_allocate_device();
2399
	if (!dev->hotkey_dev)
2400 2401
		return -ENOMEM;

2402
	dev->hotkey_dev->name = "Toshiba input device";
2403
	dev->hotkey_dev->phys = "toshiba_acpi/input0";
2404
	dev->hotkey_dev->id.bustype = BUS_HOST;
2405

2406
	if (dev->hotkey_event_type == HCI_SYSTEM_TYPE1 ||
2407 2408
	    !dev->kbd_function_keys_supported)
		keymap = toshiba_acpi_keymap;
2409
	else if (dev->hotkey_event_type == HCI_SYSTEM_TYPE2 ||
2410
		 dev->kbd_function_keys_supported)
2411
		keymap = toshiba_acpi_alt_keymap;
2412
	else
2413 2414
		pr_info("Unknown event type received %x\n",
			dev->hotkey_event_type);
2415
	error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL);
2416 2417 2418
	if (error)
		goto err_free_dev;

2419 2420 2421 2422 2423 2424 2425 2426
	/*
	 * For some machines the SCI responsible for providing hotkey
	 * notification doesn't fire. We can trigger the notification
	 * whenever the Fn key is pressed using the NTFY method, if
	 * supported, so if it's present set up an i8042 key filter
	 * for this purpose.
	 */
	ec_handle = ec_get_handle();
2427
	if (ec_handle && acpi_has_method(ec_handle, "NTFY")) {
2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
		INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work);

		error = i8042_install_filter(toshiba_acpi_i8042_filter);
		if (error) {
			pr_err("Error installing key filter\n");
			goto err_free_keymap;
		}

		dev->ntfy_supported = 1;
	}

	/*
	 * Determine hotkey query interface. Prefer using the INFO
	 * method when it is available.
	 */
2443
	if (acpi_has_method(dev->acpi_dev->handle, "INFO"))
2444
		dev->info_supported = 1;
2445 2446
	else if (hci_write(dev, HCI_SYSTEM_EVENT, 1) == TOS_SUCCESS)
		dev->system_event_supported = 1;
2447 2448 2449 2450 2451 2452

	if (!dev->info_supported && !dev->system_event_supported) {
		pr_warn("No hotkey query interface found\n");
		goto err_remove_filter;
	}

2453
	error = input_register_device(dev->hotkey_dev);
2454
	if (error) {
2455
		pr_info("Unable to register input device\n");
2456
		goto err_remove_filter;
2457 2458 2459
	}

	return 0;
2460

2461 2462 2463
 err_remove_filter:
	if (dev->ntfy_supported)
		i8042_remove_filter(toshiba_acpi_i8042_filter);
2464
 err_free_keymap:
2465
	sparse_keymap_free(dev->hotkey_dev);
2466
 err_free_dev:
2467 2468
	input_free_device(dev->hotkey_dev);
	dev->hotkey_dev = NULL;
2469
	return error;
2470 2471
}

2472
static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492
{
	struct backlight_properties props;
	int brightness;
	int ret;

	/*
	 * Some machines don't support the backlight methods at all, and
	 * others support it read-only. Either of these is pretty useless,
	 * so only register the backlight device if the backlight method
	 * supports both reads and writes.
	 */
	brightness = __get_lcd_brightness(dev);
	if (brightness < 0)
		return 0;
	ret = set_lcd_brightness(dev, brightness);
	if (ret) {
		pr_debug("Backlight method is read-only, disabling backlight support\n");
		return 0;
	}

2493 2494 2495 2496 2497 2498
	/*
	 * Tell acpi-video-detect code to prefer vendor backlight on all
	 * systems with transflective backlight and on dmi matched systems.
	 */
	if (dev->tr_backlight_supported ||
	    dmi_check_system(toshiba_vendor_backlight_dmi))
2499
		acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
2500

2501
	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
2502 2503
		return 0;

M
Matthew Garrett 已提交
2504
	memset(&props, 0, sizeof(props));
2505 2506 2507
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;

2508
	/* Adding an extra level and having 0 change to transflective mode */
2509 2510 2511
	if (dev->tr_backlight_supported)
		props.max_brightness++;

2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527
	dev->backlight_dev = backlight_device_register("toshiba",
						       &dev->acpi_dev->dev,
						       dev,
						       &toshiba_backlight_data,
						       &props);
	if (IS_ERR(dev->backlight_dev)) {
		ret = PTR_ERR(dev->backlight_dev);
		pr_err("Could not register toshiba backlight device\n");
		dev->backlight_dev = NULL;
		return ret;
	}

	dev->backlight_dev->props.brightness = brightness;
	return 0;
}

2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567
static void print_supported_features(struct toshiba_acpi_dev *dev)
{
	pr_info("Supported laptop features:");

	if (dev->hotkey_dev)
		pr_cont(" hotkeys");
	if (dev->backlight_dev)
		pr_cont(" backlight");
	if (dev->video_supported)
		pr_cont(" video-out");
	if (dev->fan_supported)
		pr_cont(" fan");
	if (dev->tr_backlight_supported)
		pr_cont(" transflective-backlight");
	if (dev->illumination_supported)
		pr_cont(" illumination");
	if (dev->kbd_illum_supported)
		pr_cont(" keyboard-backlight");
	if (dev->touchpad_supported)
		pr_cont(" touchpad");
	if (dev->eco_supported)
		pr_cont(" eco-led");
	if (dev->accelerometer_supported)
		pr_cont(" accelerometer-axes");
	if (dev->usb_sleep_charge_supported)
		pr_cont(" usb-sleep-charge");
	if (dev->usb_rapid_charge_supported)
		pr_cont(" usb-rapid-charge");
	if (dev->usb_sleep_music_supported)
		pr_cont(" usb-sleep-music");
	if (dev->kbd_function_keys_supported)
		pr_cont(" special-function-keys");
	if (dev->panel_power_on_supported)
		pr_cont(" panel-power-on");
	if (dev->usb_three_supported)
		pr_cont(" usb3");

	pr_cont("\n");
}

2568
static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
2569
{
2570
	struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
2571

2572 2573
	misc_deregister(&dev->miscdev);

2574
	remove_toshiba_proc_entries(dev);
M
Matthew Garrett 已提交
2575

2576 2577 2578
	if (dev->sysfs_created)
		sysfs_remove_group(&dev->acpi_dev->dev.kobj,
				   &toshiba_attr_group);
2579

2580 2581 2582 2583 2584
	if (dev->ntfy_supported) {
		i8042_remove_filter(toshiba_acpi_i8042_filter);
		cancel_work_sync(&dev->hotkey_work);
	}

2585 2586 2587 2588
	if (dev->hotkey_dev) {
		input_unregister_device(dev->hotkey_dev);
		sparse_keymap_free(dev->hotkey_dev);
	}
2589

2590
	backlight_device_unregister(dev->backlight_dev);
2591

2592
	if (dev->illumination_led_registered)
2593
		led_classdev_unregister(&dev->led_dev);
M
Matthew Garrett 已提交
2594

2595 2596
	if (dev->kbd_led_registered)
		led_classdev_unregister(&dev->kbd_led);
M
Matthew Garrett 已提交
2597

2598
	if (dev->eco_led_registered)
2599
		led_classdev_unregister(&dev->eco_led);
2600

2601 2602 2603
	if (toshiba_acpi)
		toshiba_acpi = NULL;

2604
	kfree(dev);
2605

2606
	return 0;
2607 2608
}

2609
static const char *find_hci_method(acpi_handle handle)
2610
{
2611
	if (acpi_has_method(handle, "GHCI"))
2612 2613
		return "GHCI";

2614
	if (acpi_has_method(handle, "SPFC"))
2615 2616 2617 2618 2619
		return "SPFC";

	return NULL;
}

2620
static int toshiba_acpi_add(struct acpi_device *acpi_dev)
L
Linus Torvalds 已提交
2621
{
2622
	struct toshiba_acpi_dev *dev;
2623
	const char *hci_method;
2624
	u32 dummy;
2625
	int ret = 0;
L
Linus Torvalds 已提交
2626

2627 2628 2629
	if (toshiba_acpi)
		return -EBUSY;

2630 2631 2632
	pr_info("Toshiba Laptop ACPI Extras version %s\n",
	       TOSHIBA_ACPI_VERSION);

2633 2634 2635
	hci_method = find_hci_method(acpi_dev->handle);
	if (!hci_method) {
		pr_err("HCI interface not found\n");
2636
		return -ENODEV;
2637
	}
2638

2639 2640 2641 2642
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;
	dev->acpi_dev = acpi_dev;
2643
	dev->method_hci = hci_method;
2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654
	dev->miscdev.minor = MISC_DYNAMIC_MINOR;
	dev->miscdev.name = "toshiba_acpi";
	dev->miscdev.fops = &toshiba_acpi_fops;

	ret = misc_register(&dev->miscdev);
	if (ret) {
		pr_err("Failed to register miscdevice\n");
		kfree(dev);
		return ret;
	}

2655
	acpi_dev->driver_data = dev;
2656
	dev_set_drvdata(&acpi_dev->dev, dev);
L
Luming Yu 已提交
2657

2658 2659 2660 2661 2662 2663 2664
	/* Query the BIOS for supported features */

	/*
	 * The "Special Functions" are always supported by the laptops
	 * with the new keyboard layout, query for its presence to help
	 * determine the keymap layout to use.
	 */
2665
	ret = toshiba_function_keys_get(dev, &dev->special_functions);
2666 2667
	dev->kbd_function_keys_supported = !ret;

2668
	dev->hotkey_event_type = 0;
2669 2670
	if (toshiba_acpi_setup_keyboard(dev))
		pr_info("Unable to activate hotkeys\n");
2671

2672 2673 2674 2675
	/* Determine whether or not BIOS supports transflective backlight */
	ret = get_tr_backlight_status(dev, &dummy);
	dev->tr_backlight_supported = !ret;

2676 2677
	ret = toshiba_acpi_setup_backlight(dev);
	if (ret)
2678
		goto error;
L
Linus Torvalds 已提交
2679

2680 2681
	toshiba_illumination_available(dev);
	if (dev->illumination_supported) {
2682 2683 2684 2685 2686
		dev->led_dev.name = "toshiba::illumination";
		dev->led_dev.max_brightness = 1;
		dev->led_dev.brightness_set = toshiba_illumination_set;
		dev->led_dev.brightness_get = toshiba_illumination_get;
		if (!led_classdev_register(&acpi_dev->dev, &dev->led_dev))
2687
			dev->illumination_led_registered = true;
2688
	}
M
Matthew Garrett 已提交
2689

2690 2691
	toshiba_eco_mode_available(dev);
	if (dev->eco_supported) {
2692 2693 2694 2695 2696
		dev->eco_led.name = "toshiba::eco_mode";
		dev->eco_led.max_brightness = 1;
		dev->eco_led.brightness_set = toshiba_eco_mode_set_status;
		dev->eco_led.brightness_get = toshiba_eco_mode_get_status;
		if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led))
2697
			dev->eco_led_registered = true;
2698
	}
M
Matthew Garrett 已提交
2699

2700
	toshiba_kbd_illum_available(dev);
2701 2702 2703 2704 2705 2706 2707 2708 2709 2710
	/*
	 * Only register the LED if KBD illumination is supported
	 * and the keyboard backlight operation mode is set to FN-Z
	 */
	if (dev->kbd_illum_supported && dev->kbd_mode == SCI_KBD_MODE_FNZ) {
		dev->kbd_led.name = "toshiba::kbd_backlight";
		dev->kbd_led.max_brightness = 1;
		dev->kbd_led.brightness_set = toshiba_kbd_backlight_set;
		dev->kbd_led.brightness_get = toshiba_kbd_backlight_get;
		if (!led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led))
2711
			dev->kbd_led_registered = true;
2712
	}
M
Matthew Garrett 已提交
2713

2714 2715
	ret = toshiba_touchpad_get(dev, &dummy);
	dev->touchpad_supported = !ret;
M
Matthew Garrett 已提交
2716

2717
	toshiba_accelerometer_available(dev);
2718

2719
	toshiba_usb_sleep_charge_available(dev);
2720

2721 2722 2723
	ret = toshiba_usb_rapid_charge_get(dev, &dummy);
	dev->usb_rapid_charge_supported = !ret;

2724 2725 2726
	ret = toshiba_usb_sleep_music_get(dev, &dummy);
	dev->usb_sleep_music_supported = !ret;

2727 2728 2729
	ret = toshiba_panel_power_on_get(dev, &dummy);
	dev->panel_power_on_supported = !ret;

2730 2731 2732
	ret = toshiba_usb_three_get(dev, &dummy);
	dev->usb_three_supported = !ret;

2733 2734 2735 2736 2737 2738
	ret = get_video_status(dev, &dummy);
	dev->video_supported = !ret;

	ret = get_fan_status(dev, &dummy);
	dev->fan_supported = !ret;

2739 2740
	print_supported_features(dev);

2741 2742 2743 2744 2745 2746 2747 2748
	ret = sysfs_create_group(&dev->acpi_dev->dev.kobj,
				 &toshiba_attr_group);
	if (ret) {
		dev->sysfs_created = 0;
		goto error;
	}
	dev->sysfs_created = !ret;

2749 2750
	create_toshiba_proc_entries(dev);

2751 2752
	toshiba_acpi = dev;

2753
	return 0;
2754 2755

error:
2756
	toshiba_acpi_remove(acpi_dev);
2757 2758 2759 2760 2761 2762
	return ret;
}

static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
{
	struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
2763
	int ret;
2764

2765 2766
	switch (event) {
	case 0x80: /* Hotkeys and some system events */
2767 2768 2769 2770 2771 2772 2773 2774
		/*
		 * Machines with this WMI GUID aren't supported due to bugs in
		 * their AML.
		 *
		 * Return silently to avoid triggering a netlink event.
		 */
		if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
			return;
2775 2776
		toshiba_acpi_process_hotkeys(dev);
		break;
2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791
	case 0x81: /* Dock events */
	case 0x82:
	case 0x83:
		pr_info("Dock event received %x\n", event);
		break;
	case 0x88: /* Thermal events */
		pr_info("Thermal event received\n");
		break;
	case 0x8f: /* LID closed */
	case 0x90: /* LID is closed and Dock has been ejected */
		break;
	case 0x8c: /* SATA power events */
	case 0x8b:
		pr_info("SATA power event received %x\n", event);
		break;
2792 2793 2794 2795 2796 2797 2798
	case 0x92: /* Keyboard backlight mode changed */
		/* Update sysfs entries */
		ret = sysfs_update_group(&acpi_dev->dev.kobj,
					 &toshiba_attr_group);
		if (ret)
			pr_err("Unable to update sysfs entries\n");
		break;
2799 2800
	case 0x85: /* Unknown */
	case 0x8d: /* Unknown */
2801
	case 0x8e: /* Unknown */
2802 2803
	case 0x94: /* Unknown */
	case 0x95: /* Unknown */
2804 2805 2806
	default:
		pr_info("Unknown event received %x\n", event);
		break;
2807
	}
2808 2809 2810 2811

	acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class,
					dev_name(&acpi_dev->dev),
					event, 0);
2812 2813
}

2814
#ifdef CONFIG_PM_SLEEP
2815
static int toshiba_acpi_suspend(struct device *device)
2816
{
2817
	struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));
2818

2819 2820 2821
	if (dev->hotkey_dev) {
		u32 result;

2822
		result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE);
2823 2824 2825
		if (result != TOS_SUCCESS)
			pr_info("Unable to disable hotkeys\n");
	}
2826 2827 2828 2829

	return 0;
}

2830
static int toshiba_acpi_resume(struct device *device)
2831
{
2832
	struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));
2833 2834

	if (dev->hotkey_dev) {
2835 2836
		int error = toshiba_acpi_enable_hotkeys(dev);

2837
		if (error)
2838 2839
			pr_info("Unable to re-enable hotkeys\n");
	}
2840 2841 2842

	return 0;
}
2843
#endif
2844

2845 2846 2847
static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm,
			 toshiba_acpi_suspend, toshiba_acpi_resume);

2848 2849 2850 2851 2852 2853 2854 2855 2856 2857
static struct acpi_driver toshiba_acpi_driver = {
	.name	= "Toshiba ACPI driver",
	.owner	= THIS_MODULE,
	.ids	= toshiba_device_ids,
	.flags	= ACPI_DRIVER_ALL_NOTIFY_EVENTS,
	.ops	= {
		.add		= toshiba_acpi_add,
		.remove		= toshiba_acpi_remove,
		.notify		= toshiba_acpi_notify,
	},
2858
	.drv.pm	= &toshiba_acpi_pm,
2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884
};

static int __init toshiba_acpi_init(void)
{
	int ret;

	toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
	if (!toshiba_proc_dir) {
		pr_err("Unable to create proc dir " PROC_TOSHIBA "\n");
		return -ENODEV;
	}

	ret = acpi_bus_register_driver(&toshiba_acpi_driver);
	if (ret) {
		pr_err("Failed to register ACPI driver: %d\n", ret);
		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
	}

	return ret;
}

static void __exit toshiba_acpi_exit(void)
{
	acpi_bus_unregister_driver(&toshiba_acpi_driver);
	if (toshiba_proc_dir)
		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
L
Linus Torvalds 已提交
2885 2886 2887 2888
}

module_init(toshiba_acpi_init);
module_exit(toshiba_acpi_exit);