// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  toshiba_acpi.c - Toshiba Laptop ACPI Extras
 *
 *  Copyright (C) 2002-2004 John Belmonte
 *  Copyright (C) 2008 Philip Langdale
 *  Copyright (C) 2010 Pierre Ducroquet
 *  Copyright (C) 2014-2016 Azael Avalos
 *
 *  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
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#define TOSHIBA_ACPI_VERSION	"0.24"
#define PROC_INTERFACE_VERSION	1

#include <linux/compiler.h>
#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/backlight.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/i8042.h>
#include <linux/acpi.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/rfkill.h>
#include <linux/hwmon.h>
#include <linux/iio/iio.h>
#include <linux/toshiba.h>
#include <acpi/battery.h>
#include <acpi/video.h>

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

static int turn_on_panel_on_resume = -1;
module_param(turn_on_panel_on_resume, int, 0644);
MODULE_PARM_DESC(turn_on_panel_on_resume,
	"Call HCI_PANEL_POWER_ON on resume (-1 = auto, 0 = no, 1 = yes");

static int hci_hotkey_quickstart = -1;
module_param(hci_hotkey_quickstart, int, 0644);
MODULE_PARM_DESC(hci_hotkey_quickstart,
		 "Call HCI_HOTKEY_EVENT with value 0x5 for quickstart button support (-1 = auto, 0 = no, 1 = yes");

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

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

/* Toshiba ACPI method paths */
#define METHOD_VIDEO_OUT	"\\_SB_.VALX.DSSX"

/*
 * The Toshiba configuration interface is composed of the HCI and the SCI,
 * which are defined as follows:
 *
 * 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.
 *
 * SCI stands for "System Configuration Interface" which aim is to
 * conceal differences in hardware between different models.
 */

#define TCI_WORDS			6

/* Operations */
#define HCI_SET				0xff00
#define HCI_GET				0xfe00
#define SCI_OPEN			0xf100
#define SCI_CLOSE			0xf200
#define SCI_GET				0xf300
#define SCI_SET				0xf400

/* Return codes */
#define TOS_SUCCESS			0x0000
#define TOS_SUCCESS2			0x0001
#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
#define TOS_NOT_INSTALLED		0x8e00

/* Registers */
#define HCI_PANEL_POWER_ON		0x0002
#define HCI_FAN				0x0004
#define HCI_TR_BACKLIGHT		0x0005
#define HCI_SYSTEM_EVENT		0x0016
#define HCI_VIDEO_OUT			0x001c
#define HCI_HOTKEY_EVENT		0x001e
#define HCI_LCD_BRIGHTNESS		0x002a
#define HCI_FAN_RPM			0x0045
#define HCI_WIRELESS			0x0056
#define HCI_ACCELEROMETER		0x006d
#define HCI_COOLING_METHOD		0x007f
#define HCI_KBD_ILLUMINATION		0x0095
#define HCI_ECO_MODE			0x0097
#define HCI_ACCELEROMETER2		0x00a6
#define HCI_BATTERY_CHARGE_MODE		0x00ba
#define HCI_SYSTEM_INFO			0xc000
#define SCI_PANEL_POWER_ON		0x010d
#define SCI_ILLUMINATION		0x014e
#define SCI_USB_SLEEP_CHARGE		0x0150
#define SCI_KBD_ILLUM_STATUS		0x015c
#define SCI_USB_SLEEP_MUSIC		0x015e
#define SCI_USB_THREE			0x0169
#define SCI_TOUCHPAD			0x050e
#define SCI_KBD_FUNCTION_KEYS		0x0522

/* Field definitions */
#define HCI_ACCEL_MASK			0x7fff
#define HCI_ACCEL_DIRECTION_MASK	0x8000
#define HCI_HOTKEY_DISABLE		0x0b
#define HCI_HOTKEY_ENABLE_QUICKSTART	0x05
#define HCI_HOTKEY_ENABLE		0x09
#define HCI_HOTKEY_SPECIAL_FUNCTIONS	0x10
#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)
#define HCI_MISC_SHIFT			0x10
#define HCI_SYSTEM_TYPE1		0x10
#define HCI_SYSTEM_TYPE2		0x11
#define HCI_VIDEO_OUT_LCD		0x1
#define HCI_VIDEO_OUT_CRT		0x2
#define HCI_VIDEO_OUT_TV		0x4
#define SCI_KBD_MODE_MASK		0x1f
#define SCI_KBD_MODE_FNZ		0x1
#define SCI_KBD_MODE_AUTO		0x2
#define SCI_KBD_MODE_ON			0x8
#define SCI_KBD_MODE_OFF		0x10
#define SCI_KBD_TIME_MAX		0x3c001a
#define HCI_WIRELESS_STATUS		0x1
#define HCI_WIRELESS_WWAN		0x3
#define HCI_WIRELESS_WWAN_STATUS	0x2000
#define HCI_WIRELESS_WWAN_POWER		0x4000
#define SCI_USB_CHARGE_MODE_MASK	0xff
#define SCI_USB_CHARGE_DISABLED		0x00
#define SCI_USB_CHARGE_ALTERNATE	0x09
#define SCI_USB_CHARGE_TYPICAL		0x11
#define SCI_USB_CHARGE_AUTO		0x21
#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
#define SCI_USB_CHARGE_RAPID_DSP	0x0300

struct toshiba_acpi_dev {
	struct acpi_device *acpi_dev;
	const char *method_hci;
	struct input_dev *hotkey_dev;
	struct work_struct hotkey_work;
	struct backlight_device *backlight_dev;
	struct led_classdev led_dev;
	struct led_classdev kbd_led;
	struct led_classdev eco_led;
	struct miscdevice miscdev;
	struct rfkill *wwan_rfk;
	struct iio_dev *indio_dev;
#if IS_ENABLED(CONFIG_HWMON)
	struct device *hwmon_device;
#endif

	int force_fan;
	int last_key_event;
	int key_event_valid;
	int kbd_type;
	int kbd_mode;
	int kbd_time;
	int usbsc_bat_level;
	int usbsc_mode_base;
	int hotkey_event_type;
	int max_cooling_method;

	unsigned int illumination_supported:1;
	unsigned int video_supported:1;
	unsigned int fan_supported:1;
	unsigned int fan_rpm_supported:1;
	unsigned int system_event_supported:1;
	unsigned int ntfy_supported:1;
	unsigned int info_supported:1;
	unsigned int tr_backlight_supported:1;
	unsigned int kbd_illum_supported:1;
	unsigned int touchpad_supported:1;
	unsigned int eco_supported:1;
	unsigned int accelerometer_supported:1;
	unsigned int usb_sleep_charge_supported:1;
	unsigned int usb_rapid_charge_supported:1;
	unsigned int usb_sleep_music_supported:1;
	unsigned int kbd_function_keys_supported:1;
	unsigned int panel_power_on_supported:1;
	unsigned int usb_three_supported:1;
	unsigned int wwan_supported:1;
	unsigned int cooling_method_supported:1;
	unsigned int battery_charge_mode_supported:1;
	unsigned int sysfs_created:1;
	unsigned int special_functions;

	bool kbd_event_generated;
	bool killswitch;
};

static struct toshiba_acpi_dev *toshiba_acpi;

static bool disable_hotkeys;
module_param(disable_hotkeys, bool, 0444);
MODULE_PARM_DESC(disable_hotkeys, "Disables the hotkeys activation");

static const struct acpi_device_id toshiba_device_ids[] = {
	{"TOS6200", 0},
	{"TOS6207", 0},
	{"TOS6208", 0},
	{"TOS1900", 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);

static const struct key_entry toshiba_acpi_keymap[] = {
	{ KE_KEY, 0x9e, { KEY_RFKILL } },
	{ KE_KEY, 0x101, { KEY_MUTE } },
	{ KE_KEY, 0x102, { KEY_ZOOMOUT } },
	{ KE_KEY, 0x103, { KEY_ZOOMIN } },
	{ KE_KEY, 0x10f, { KEY_TAB } },
	{ KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
	{ KE_KEY, 0x139, { KEY_ZOOMRESET } },
	{ 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 } },
	{ KE_KEY, 0x143, { KEY_TOUCHPAD_TOGGLE } },
	{ KE_KEY, 0x17f, { KEY_FN } },
	{ 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 } },
	{ KE_IGNORE, 0x0e00, { KEY_RESERVED } }, /* Wake from sleep */
	{ 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 */
	{ KE_END, 0 },
};

static const struct key_entry toshiba_acpi_alt_keymap[] = {
	{ KE_KEY, 0x102, { KEY_ZOOMOUT } },
	{ KE_KEY, 0x103, { KEY_ZOOMIN } },
	{ KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
	{ KE_KEY, 0x139, { KEY_ZOOMRESET } },
	{ KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, 0x13d, { KEY_BRIGHTNESSUP } },
	{ KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x13f, { KEY_TOUCHPAD_TOGGLE } },
	{ KE_KEY, 0x157, { KEY_MUTE } },
	{ KE_KEY, 0x158, { KEY_WLAN } },
	{ KE_END, 0 },
};

/*
 * Utility
 */

static inline void _set_bit(u32 *word, u32 mask, int value)
{
	*word = (*word & ~mask) | (mask * value);
}

/*
 * ACPI interface wrappers
 */

static int write_acpi_int(const char *methodName, int val)
{
	acpi_status status;

	status = acpi_execute_simple_method(NULL, (char *)methodName, val);
	return (status == AE_OK) ? 0 : -EIO;
}

/*
 * Perform a raw configuration call.  Here we don't care about input or output
 * buffer format.
 */
static acpi_status tci_raw(struct toshiba_acpi_dev *dev,
			   const u32 in[TCI_WORDS], u32 out[TCI_WORDS])
{
	union acpi_object in_objs[TCI_WORDS], out_objs[TCI_WORDS + 1];
	struct acpi_object_list params;
	struct acpi_buffer results;
	acpi_status status;
	int i;

	params.count = TCI_WORDS;
	params.pointer = in_objs;
	for (i = 0; i < TCI_WORDS; ++i) {
		in_objs[i].type = ACPI_TYPE_INTEGER;
		in_objs[i].integer.value = in[i];
	}

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

	status = acpi_evaluate_object(dev->acpi_dev->handle,
				      (char *)dev->method_hci, &params,
				      &results);
	if ((status == AE_OK) && (out_objs->package.count <= TCI_WORDS)) {
		for (i = 0; i < out_objs->package.count; ++i)
			out[i] = out_objs->package.elements[i].integer.value;
	}

	return status;
}

/*
 * Common hci tasks
 *
 * In addition to the ACPI status, the HCI system returns a result which
 * may be useful (such as "not supported").
 */

static u32 hci_write(struct toshiba_acpi_dev *dev, u32 reg, u32 in1)
{
	u32 in[TCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);

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

static u32 hci_read(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1)
{
	u32 in[TCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);

	if (ACPI_FAILURE(status))
		return TOS_FAILURE;

	*out1 = out[2];

	return out[0];
}

/*
 * Common sci tasks
 */

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

	if  (ACPI_FAILURE(status)) {
		pr_err("ACPI call to open SCI failed\n");
		return 0;
	}

	if (out[0] == TOS_OPEN_CLOSE_OK) {
		return 1;
	} else if (out[0] == TOS_ALREADY_OPEN) {
		pr_info("Toshiba SCI already opened\n");
		return 1;
	} else if (out[0] == TOS_NOT_SUPPORTED) {
		/*
		 * Some BIOSes do not have the SCI open/close functions
		 * 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;
	} else if (out[0] == TOS_NOT_PRESENT) {
		pr_info("Toshiba SCI is not present\n");
	}

	return 0;
}

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

	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to close SCI failed\n");
		return;
	}

	if (out[0] == TOS_OPEN_CLOSE_OK)
		return;
	else if (out[0] == TOS_NOT_OPENED)
		pr_info("Toshiba SCI not opened\n");
	else if (out[0] == TOS_NOT_PRESENT)
		pr_info("Toshiba SCI is not present\n");
}

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

	if (ACPI_FAILURE(status))
		return TOS_FAILURE;

	*out1 = out[2];

	return out[0];
}

static u32 sci_write(struct toshiba_acpi_dev *dev, u32 reg, u32 in1)
{
	u32 in[TCI_WORDS] = { SCI_SET, reg, in1, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);

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

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

	dev->illumination_supported = 0;

	if (!sci_open(dev))
		return;

	status = tci_raw(dev, in, out);
	sci_close(dev);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to query Illumination support failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS)
		return;

	dev->illumination_supported = 1;
}

static void toshiba_illumination_set(struct led_classdev *cdev,
				     enum led_brightness brightness)
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, led_dev);
	u32 result;
	u32 state;

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

	/* Switch the illumination on/off */
	state = brightness ? 1 : 0;
	result = sci_write(dev, SCI_ILLUMINATION, state);
	sci_close(dev);
	if (result == TOS_FAILURE)
		pr_err("ACPI call for illumination failed\n");
}

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

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

	/* Check the illumination */
	result = sci_read(dev, SCI_ILLUMINATION, &state);
	sci_close(dev);
	if (result == TOS_FAILURE) {
		pr_err("ACPI call for illumination failed\n");
		return LED_OFF;
	} else if (result != TOS_SUCCESS) {
		return LED_OFF;
	}

	return state ? LED_FULL : LED_OFF;
}

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

	dev->kbd_illum_supported = 0;
	dev->kbd_event_generated = false;

	if (!sci_open(dev))
		return;

	status = tci_raw(dev, in, out);
	sci_close(dev);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to query kbd illumination support failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS)
		return;

	/*
	 * 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;
}

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

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

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

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

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

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

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

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

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);
	u32 result;
	u32 state;

	/* Check the keyboard backlight state */
	result = hci_read(dev, HCI_KBD_ILLUMINATION, &state);
	if (result == TOS_FAILURE) {
		pr_err("ACPI call to get the keyboard backlight failed\n");
		return LED_OFF;
	} else if (result != TOS_SUCCESS) {
		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);
	u32 result;
	u32 state;

	/* Set the keyboard backlight state */
	state = brightness ? 1 : 0;
	result = hci_write(dev, HCI_KBD_ILLUMINATION, state);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set KBD Illumination mode failed\n");
}

/* TouchPad support */
static int toshiba_touchpad_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result;

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

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

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

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

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

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

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

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

	dev->eco_supported = 0;

	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get ECO led failed\n");
		return;
	}

	if (out[0] == TOS_INPUT_DATA_ERROR || out[0] == TOS_NOT_SUPPORTED) {
		/*
		 * If we receive 0x8300 (Input Data Error), it means that the
		 * LED device is present, but that we just screwed the input
		 * parameters.
		 *
		 * On some laptops 0x8000 (Not supported) is also returned in
		 * this case, so we need to allow for that as well.
		 *
		 * 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);
		if (ACPI_FAILURE(status)) {
			pr_err("ACPI call to get ECO led failed\n");
			return;
		}

		if (out[0] != TOS_SUCCESS)
			return;

		dev->eco_supported = 1;
	}
}

static enum led_brightness
toshiba_eco_mode_get_status(struct led_classdev *cdev)
{
	struct toshiba_acpi_dev *dev = container_of(cdev,
			struct toshiba_acpi_dev, eco_led);
	u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get ECO led failed\n");
		return LED_OFF;
	}

	if (out[0] != TOS_SUCCESS)
		return LED_OFF;

	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);
	u32 in[TCI_WORDS] = { HCI_SET, HCI_ECO_MODE, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	/* Switch the Eco Mode led on/off */
	in[2] = (brightness) ? 1 : 0;
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status))
		pr_err("ACPI call to set ECO led failed\n");
}

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

	dev->accelerometer_supported = 0;

	/*
	 * Check if the accelerometer call exists,
	 * this call also serves as initialization
	 */
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to query the accelerometer failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS)
		return;

	dev->accelerometer_supported = 1;
}

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

	/* Check the Accelerometer status */
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to query the accelerometer failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS)
		return -EIO;

	*xy = out[2];
	*z = out[4];

	return 0;
}

/* Sleep (Charge and Music) utilities support */
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);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get USB Sleep and Charge mode failed\n");
		sci_close(dev);
		return;
	}

	if (out[0] != TOS_SUCCESS) {
		sci_close(dev);
		return;
	}

	dev->usbsc_mode_base = out[4];

	in[5] = SCI_USB_CHARGE_BAT_LVL;
	status = tci_raw(dev, in, out);
	sci_close(dev);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get USB Sleep and Charge mode failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS)
		return;

	dev->usbsc_bat_level = out[2];
	/* Flag as supported */
	dev->usb_sleep_charge_supported = 1;
}

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set USB S&C mode failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set USB S&C mode failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get USB S&C battery level failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS)
		return -EIO;

	*mode = out[2];

	return 0;

}

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);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to set USB S&C battery level failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get USB Rapid Charge failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS && out[0] != TOS_SUCCESS2)
		return -EIO;

	*state = out[2];

	return 0;
}

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);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to set USB Rapid Charge failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Sleep and Music failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Sleep and Music failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* 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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get KBD function keys failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set KBD function keys failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* 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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Panel Power ON failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Panel Power ON failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* 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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to get USB 3 failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

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);
	if (result == TOS_FAILURE)
		pr_err("ACPI call to set USB 3 failed\n");
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* Hotkey Event type */
static int toshiba_hotkey_event_type_get(struct toshiba_acpi_dev *dev,
					 u32 *type)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_SYSTEM_INFO, 0x03, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get System type failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS)
		return -EIO;

	*type = out[3];

	return 0;
}

/* Wireless status (RFKill, WLAN, BT, WWAN) */
static int toshiba_wireless_status(struct toshiba_acpi_dev *dev)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_WIRELESS, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	in[3] = HCI_WIRELESS_STATUS;
	status = tci_raw(dev, in, out);

	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get Wireless status failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS)
		return -EIO;

	dev->killswitch = !!(out[2] & HCI_WIRELESS_STATUS);

	return 0;
}

/* WWAN */
static void toshiba_wwan_available(struct toshiba_acpi_dev *dev)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_WIRELESS, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	dev->wwan_supported = 0;

	/*
	 * WWAN support can be queried by setting the in[3] value to
	 * HCI_WIRELESS_WWAN (0x03).
	 *
	 * If supported, out[0] contains TOS_SUCCESS and out[2] contains
	 * HCI_WIRELESS_WWAN_STATUS (0x2000).
	 *
	 * If not supported, out[0] contains TOS_INPUT_DATA_ERROR (0x8300)
	 * or TOS_NOT_SUPPORTED (0x8000).
	 */
	in[3] = HCI_WIRELESS_WWAN;
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get WWAN status failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS)
		return;

	dev->wwan_supported = (out[2] == HCI_WIRELESS_WWAN_STATUS);
}

static int toshiba_wwan_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 in[TCI_WORDS] = { HCI_SET, HCI_WIRELESS, state, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	in[3] = HCI_WIRELESS_WWAN_STATUS;
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to set WWAN status failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] != TOS_SUCCESS)
		return -EIO;

	/*
	 * Some devices only need to call HCI_WIRELESS_WWAN_STATUS to
	 * (de)activate the device, but some others need the
	 * HCI_WIRELESS_WWAN_POWER call as well.
	 */
	in[3] = HCI_WIRELESS_WWAN_POWER;
	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to set WWAN power failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* Cooling Method */
static void toshiba_cooling_method_available(struct toshiba_acpi_dev *dev)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_COOLING_METHOD, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	dev->cooling_method_supported = 0;
	dev->max_cooling_method = 0;

	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get Cooling Method failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS && out[0] != TOS_SUCCESS2)
		return;

	dev->cooling_method_supported = 1;
	dev->max_cooling_method = out[3];
}

static int toshiba_cooling_method_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 result = hci_read(dev, HCI_COOLING_METHOD, state);

	if (result == TOS_FAILURE)
		pr_err("ACPI call to get Cooling Method failed\n");

	if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

static int toshiba_cooling_method_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result = hci_write(dev, HCI_COOLING_METHOD, state);

	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Cooling Method failed\n");

	if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* Battery charge control */
static void toshiba_battery_charge_mode_available(struct toshiba_acpi_dev *dev)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_BATTERY_CHARGE_MODE, 0, 0, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status;

	dev->battery_charge_mode_supported = 0;

	status = tci_raw(dev, in, out);
	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get Battery Charge Mode failed\n");
		return;
	}

	if (out[0] != TOS_SUCCESS && out[0] != TOS_SUCCESS2)
		return;

	dev->battery_charge_mode_supported = 1;
}

static int toshiba_battery_charge_mode_get(struct toshiba_acpi_dev *dev, u32 *state)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_BATTERY_CHARGE_MODE, 0, 0, 0, 0x1 };
	u32 out[TCI_WORDS];
	int retries = 3;

	do {
		acpi_status status = tci_raw(dev, in, out);

		if (ACPI_FAILURE(status))
			pr_err("ACPI call to get Battery Charge Mode failed\n");
		switch (out[0]) {
		case TOS_SUCCESS:
		case TOS_SUCCESS2:
			*state = out[2];
			return 0;
		case TOS_NOT_SUPPORTED:
			return -ENODEV;
		case TOS_DATA_NOT_AVAILABLE:
			retries--;
			break;
		default:
			return -EIO;
		}
	} while (retries);

	return -EIO;
}

static int toshiba_battery_charge_mode_set(struct toshiba_acpi_dev *dev, u32 state)
{
	u32 result = hci_write(dev, HCI_BATTERY_CHARGE_MODE, state);

	if (result == TOS_FAILURE)
		pr_err("ACPI call to set Battery Charge Mode failed\n");

	if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

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

/* Transflective Backlight */
static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 *status)
{
	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;

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

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

	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;
}

static struct proc_dir_entry *toshiba_proc_dir;

/* LCD Brightness */
static int __get_lcd_brightness(struct toshiba_acpi_dev *dev)
{
	int brightness = 0;
	u32 result;
	u32 value;

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

		if (ret)
			return ret;
		if (value)
			return 0;
		brightness++;
	}

	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;

	return result == TOS_SUCCESS ?
			brightness + (value >> HCI_LCD_BRIGHTNESS_SHIFT) :
			-EIO;
}

static int get_lcd_brightness(struct backlight_device *bd)
{
	struct toshiba_acpi_dev *dev = bl_get_data(bd);

	return __get_lcd_brightness(dev);
}

static int lcd_proc_show(struct seq_file *m, void *v)
{
	struct toshiba_acpi_dev *dev = m->private;
	int levels;
	int value;

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

	levels = dev->backlight_dev->props.max_brightness + 1;
	value = get_lcd_brightness(dev->backlight_dev);
	if (value < 0) {
		pr_err("Error reading LCD brightness\n");
		return value;
	}

	seq_printf(m, "brightness:              %d\n", value);
	seq_printf(m, "brightness_levels:       %d\n", levels);

	return 0;
}

static int lcd_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, lcd_proc_show, pde_data(inode));
}

static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
{
	u32 result;

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

		if (ret)
			return ret;
		if (value)
			value--;
	}

	value = value << HCI_LCD_BRIGHTNESS_SHIFT;
	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;
}

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

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

static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *pos)
{
	struct toshiba_acpi_dev *dev = pde_data(file_inode(file));
	char cmd[42];
	size_t len;
	int levels;
	int value;

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

	levels = dev->backlight_dev->props.max_brightness + 1;
	if (sscanf(cmd, " brightness : %i", &value) != 1 &&
	    value < 0 && value > levels)
		return -EINVAL;

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

	return count;
}

static const struct proc_ops lcd_proc_ops = {
	.proc_open	= lcd_proc_open,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_release	= single_release,
	.proc_write	= lcd_proc_write,
};

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

	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;
}

static int video_proc_show(struct seq_file *m, void *v)
{
	struct toshiba_acpi_dev *dev = m->private;
	int is_lcd, is_crt, is_tv;
	u32 value;

	if (get_video_status(dev, &value))
		return -EIO;

	is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
	is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
	is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;

	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);

	return 0;
}

static int video_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, video_proc_show, pde_data(inode));
}

static ssize_t video_proc_write(struct file *file, const char __user *buf,
				size_t count, loff_t *pos)
{
	struct toshiba_acpi_dev *dev = pde_data(file_inode(file));
	char *buffer;
	char *cmd;
	int lcd_out = -1, crt_out = -1, tv_out = -1;
	int remain = count;
	int value;
	int ret;
	u32 video_out;

	cmd = memdup_user_nul(buf, count);
	if (IS_ERR(cmd))
		return PTR_ERR(cmd);

	buffer = cmd;

	/*
	 * Scan expression.  Multiple expressions may be delimited with ;
	 * NOTE: To keep scanning simple, invalid fields are ignored.
	 */
	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;
		/* Advance to one character past the next ; */
		do {
			++buffer;
			--remain;
		} while (remain && *(buffer - 1) != ';');
	}

	kfree(cmd);

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

		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);
		/*
		 * To avoid unnecessary video disruption, only write the new
		 * video setting if something changed.
		 */
		if (new_video_out != video_out)
			ret = write_acpi_int(METHOD_VIDEO_OUT, new_video_out);
	}

	return ret ? -EIO : count;
}

static const struct proc_ops video_proc_ops = {
	.proc_open	= video_proc_open,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_release	= single_release,
	.proc_write	= video_proc_write,
};

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

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

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

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;

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

static int fan_proc_show(struct seq_file *m, void *v)
{
	struct toshiba_acpi_dev *dev = m->private;
	u32 value;

	if (get_fan_status(dev, &value))
		return -EIO;

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

	return 0;
}

static int fan_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, fan_proc_show, pde_data(inode));
}

static ssize_t fan_proc_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *pos)
{
	struct toshiba_acpi_dev *dev = pde_data(file_inode(file));
	char cmd[42];
	size_t len;
	int value;

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

	if (sscanf(cmd, " force_on : %i", &value) != 1 &&
	    value != 0 && value != 1)
		return -EINVAL;

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

	dev->force_fan = value;

	return count;
}

static const struct proc_ops fan_proc_ops = {
	.proc_open	= fan_proc_open,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_release	= single_release,
	.proc_write	= fan_proc_write,
};

/* Fan RPM */
static int get_fan_rpm(struct toshiba_acpi_dev *dev, u32 *rpm)
{
	u32 in[TCI_WORDS] = { HCI_GET, HCI_FAN_RPM, 0, 1, 0, 0 };
	u32 out[TCI_WORDS];
	acpi_status status = tci_raw(dev, in, out);

	if (ACPI_FAILURE(status)) {
		pr_err("ACPI call to get Fan speed failed\n");
		return -EIO;
	}

	if (out[0] == TOS_NOT_SUPPORTED)
		return -ENODEV;

	if (out[0] == TOS_SUCCESS) {
		*rpm = out[2];
		return 0;
	}

	return -EIO;
}

static int keys_proc_show(struct seq_file *m, void *v)
{
	struct toshiba_acpi_dev *dev = m->private;

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

	return 0;
}

static int keys_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, keys_proc_show, pde_data(inode));
}

static ssize_t keys_proc_write(struct file *file, const char __user *buf,
			       size_t count, loff_t *pos)
{
	struct toshiba_acpi_dev *dev = pde_data(file_inode(file));
	char cmd[42];
	size_t len;
	int value;

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

	if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0)
		dev->key_event_valid = 0;
	else
		return -EINVAL;

	return count;
}

static const struct proc_ops keys_proc_ops = {
	.proc_open	= keys_proc_open,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_release	= single_release,
	.proc_write	= keys_proc_write,
};

static int __maybe_unused version_proc_show(struct seq_file *m, void *v)
{
	seq_printf(m, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
	seq_printf(m, "proc_interface:          %d\n", PROC_INTERFACE_VERSION);
	return 0;
}

/*
 * Proc and module init
 */

#define PROC_TOSHIBA		"toshiba"

static void create_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
{
	if (dev->backlight_dev)
		proc_create_data("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &lcd_proc_ops, dev);
	if (dev->video_supported)
		proc_create_data("video", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &video_proc_ops, dev);
	if (dev->fan_supported)
		proc_create_data("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &fan_proc_ops, dev);
	if (dev->hotkey_dev)
		proc_create_data("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir,
				 &keys_proc_ops, dev);
	proc_create_single_data("version", S_IRUGO, toshiba_proc_dir,
			version_proc_show, dev);
}

static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
{
	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);
	remove_proc_entry("version", toshiba_proc_dir);
}

static const struct backlight_ops toshiba_backlight_data = {
	.options = BL_CORE_SUSPENDRESUME,
	.get_brightness = get_lcd_brightness,
	.update_status  = set_lcd_status,
};

/* Keyboard backlight work */
static void toshiba_acpi_kbd_bl_work(struct work_struct *work);

static DECLARE_WORK(kbd_bl_work, toshiba_acpi_kbd_bl_work);

/*
 * Sysfs files
 */
static DEVICE_STRING_ATTR_RO(version, 0444, TOSHIBA_ACPI_VERSION);

static ssize_t fan_store(struct device *dev,
			 struct device_attribute *attr,
			 const char *buf, size_t count)
{
	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 = set_fan_status(toshiba, state);
	if (ret)
		return ret;

	return count;
}

static ssize_t fan_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	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);
}
static DEVICE_ATTR_RW(fan);

static ssize_t kbd_backlight_mode_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int mode;
	int ret;


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

	/* 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;
	}

	/*
	 * Set the Keyboard Backlight Mode where:
	 *	Auto - KBD backlight turns off automatically in given time
	 *	FN-Z - KBD backlight "toggles" when hotkey pressed
	 *	ON   - KBD backlight is always on
	 *	OFF  - KBD backlight is always off
	 */

	/* Only make a change if the actual mode has changed */
	if (toshiba->kbd_mode != mode) {
		/* Shift the time to "base time" (0x3c0000 == 60 seconds) */
		int time = toshiba->kbd_time << HCI_MISC_SHIFT;

		/* 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;
		}

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

		toshiba->kbd_mode = mode;
		toshiba_acpi->kbd_mode = mode;

		/*
		 * Some laptop models with the second generation backlit
		 * keyboard (type 2) do not generate the keyboard backlight
		 * changed event (0x92), and thus, the driver will never update
		 * the sysfs entries.
		 *
		 * The event is generated right when changing the keyboard
		 * backlight mode and the *notify function will set the
		 * kbd_event_generated to true.
		 *
		 * In case the event is not generated, schedule the keyboard
		 * backlight work to update the sysfs entries and emulate the
		 * event via genetlink.
		 */
		if (toshiba->kbd_type == 2 &&
		    !toshiba->kbd_event_generated)
			schedule_work(&kbd_bl_work);
	}

	return count;
}

static ssize_t kbd_backlight_mode_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
	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 & SCI_KBD_MODE_MASK);
}
static DEVICE_ATTR_RW(kbd_backlight_mode);

static ssize_t kbd_type_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);

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

static ssize_t available_kbd_modes_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);

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

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

static ssize_t kbd_backlight_timeout_store(struct device *dev,
					   struct device_attribute *attr,
					   const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int time;
	int ret;

	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 */

	/* Only make a change if the actual timeout has changed */
	if (toshiba->kbd_time != time) {
		/* Shift the time to "base time" (0x3c0000 == 60 seconds) */
		time = time << HCI_MISC_SHIFT;
		/* 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;

		toshiba->kbd_time = time >> HCI_MISC_SHIFT;
	}

	return count;
}

static ssize_t kbd_backlight_timeout_show(struct device *dev,
					  struct device_attribute *attr,
					  char *buf)
{
	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);
}
static DEVICE_ATTR_RW(kbd_backlight_timeout);

static ssize_t touchpad_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	/* Set the TouchPad on/off, 0 - Disable | 1 - Enable */
	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;

	return count;
}

static ssize_t touchpad_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	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);
}
static DEVICE_ATTR_RW(touchpad);

static ssize_t usb_sleep_charge_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t usb_sleep_charge_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	u32 mode;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	/*
	 * Check for supported values, where:
	 * 0 - Disabled
	 * 1 - Alternate (Non USB conformant devices that require more power)
	 * 2 - Auto (USB conformant devices)
	 * 3 - Typical
	 */
	if (state != 0 && state != 1 && state != 2 && state != 3)
		return -EINVAL;

	/* Set the USB charging mode to internal value */
	mode = toshiba->usbsc_mode_base;
	if (state == 0)
		mode |= SCI_USB_CHARGE_DISABLED;
	else if (state == 1)
		mode |= SCI_USB_CHARGE_ALTERNATE;
	else if (state == 2)
		mode |= SCI_USB_CHARGE_AUTO;
	else if (state == 3)
		mode |= SCI_USB_CHARGE_TYPICAL;

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

	return count;
}
static DEVICE_ATTR_RW(usb_sleep_charge);

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);
	int bat_lvl, status;
	u32 state;
	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;

	/*
	 * Set the status of the function:
	 * 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;
}
static DEVICE_ATTR_RW(sleep_functions_on_battery);

static ssize_t usb_rapid_charge_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t usb_rapid_charge_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	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;
}
static DEVICE_ATTR_RW(usb_rapid_charge);

static ssize_t usb_sleep_music_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t usb_sleep_music_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	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;
}
static DEVICE_ATTR_RW(usb_sleep_music);

static ssize_t kbd_function_keys_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t kbd_function_keys_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int mode;
	int ret;

	ret = kstrtoint(buf, 0, &mode);
	if (ret)
		return ret;
	/*
	 * Check for the function keys mode where:
	 * 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;
}
static DEVICE_ATTR_RW(kbd_function_keys);

static ssize_t panel_power_on_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t panel_power_on_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	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;
}
static DEVICE_ATTR_RW(panel_power_on);

static ssize_t usb_three_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	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);
}

static ssize_t usb_three_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

	ret = kstrtoint(buf, 0, &state);
	if (ret)
		return ret;
	/*
	 * Check for USB 3 mode where:
	 * 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;
}
static DEVICE_ATTR_RW(usb_three);

static ssize_t cooling_method_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

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

	return sprintf(buf, "%d %d\n", state, toshiba->max_cooling_method);
}

static ssize_t cooling_method_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
	int state;
	int ret;

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

	/*
	 * Check for supported values
	 * Depending on the laptop model, some only support these two:
	 * 0 - Maximum Performance
	 * 1 - Battery Optimized
	 *
	 * While some others support all three methods:
	 * 0 - Maximum Performance
	 * 1 - Performance
	 * 2 - Battery Optimized
	 */
	if (state < 0 || state > toshiba->max_cooling_method)
		return -EINVAL;

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

	return count;
}
static DEVICE_ATTR_RW(cooling_method);

static struct attribute *toshiba_attributes[] = {
	&dev_attr_version.attr.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_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,
	&dev_attr_cooling_method.attr,
	NULL,
};

static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
					struct attribute *attr, int idx)
{
	struct device *dev = kobj_to_dev(kobj);
	struct toshiba_acpi_dev *drv = dev_get_drvdata(dev);
	bool exists = true;

	if (attr == &dev_attr_fan.attr)
		exists = (drv->fan_supported) ? true : false;
	else if (attr == &dev_attr_kbd_backlight_mode.attr)
		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;
	else if (attr == &dev_attr_touchpad.attr)
		exists = (drv->touchpad_supported) ? true : false;
	else if (attr == &dev_attr_usb_sleep_charge.attr)
		exists = (drv->usb_sleep_charge_supported) ? true : false;
	else if (attr == &dev_attr_sleep_functions_on_battery.attr)
		exists = (drv->usb_sleep_charge_supported) ? true : false;
	else if (attr == &dev_attr_usb_rapid_charge.attr)
		exists = (drv->usb_rapid_charge_supported) ? true : false;
	else if (attr == &dev_attr_usb_sleep_music.attr)
		exists = (drv->usb_sleep_music_supported) ? true : false;
	else if (attr == &dev_attr_kbd_function_keys.attr)
		exists = (drv->kbd_function_keys_supported) ? true : false;
	else if (attr == &dev_attr_panel_power_on.attr)
		exists = (drv->panel_power_on_supported) ? true : false;
	else if (attr == &dev_attr_usb_three.attr)
		exists = (drv->usb_three_supported) ? true : false;
	else if (attr == &dev_attr_cooling_method.attr)
		exists = (drv->cooling_method_supported) ? true : false;

	return exists ? attr->mode : 0;
}

static const struct attribute_group toshiba_attr_group = {
	.is_visible = toshiba_sysfs_is_visible,
	.attrs = toshiba_attributes,
};

static void toshiba_acpi_kbd_bl_work(struct work_struct *work)
{
	/* Update the sysfs entries */
	if (sysfs_update_group(&toshiba_acpi->acpi_dev->dev.kobj,
			       &toshiba_attr_group))
		pr_err("Unable to update sysfs entries\n");

	/* Notify LED subsystem about keyboard backlight change */
	if (toshiba_acpi->kbd_type == 2 &&
	    toshiba_acpi->kbd_mode != SCI_KBD_MODE_AUTO)
		led_classdev_notify_brightness_hw_changed(&toshiba_acpi->kbd_led,
				(toshiba_acpi->kbd_mode == SCI_KBD_MODE_ON) ?
				LED_FULL : LED_OFF);

	/* Emulate the keyboard backlight event */
	acpi_bus_generate_netlink_event(toshiba_acpi->acpi_dev->pnp.device_class,
					dev_name(&toshiba_acpi->acpi_dev->dev),
					0x92, 0);
}

/*
 * IIO device
 */

enum toshiba_iio_accel_chan {
	AXIS_X,
	AXIS_Y,
	AXIS_Z
};

static int toshiba_iio_accel_get_axis(enum toshiba_iio_accel_chan chan)
{
	u32 xyval, zval;
	int ret;

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

	switch (chan) {
	case AXIS_X:
		return xyval & HCI_ACCEL_DIRECTION_MASK ?
			-(xyval & HCI_ACCEL_MASK) : xyval & HCI_ACCEL_MASK;
	case AXIS_Y:
		return (xyval >> HCI_MISC_SHIFT) & HCI_ACCEL_DIRECTION_MASK ?
			-((xyval >> HCI_MISC_SHIFT) & HCI_ACCEL_MASK) :
			(xyval >> HCI_MISC_SHIFT) & HCI_ACCEL_MASK;
	case AXIS_Z:
		return zval & HCI_ACCEL_DIRECTION_MASK ?
			-(zval & HCI_ACCEL_MASK) : zval & HCI_ACCEL_MASK;
	}

	return ret;
}

static int toshiba_iio_accel_read_raw(struct iio_dev *indio_dev,
				      struct iio_chan_spec const *chan,
				      int *val, int *val2, long mask)
{
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = toshiba_iio_accel_get_axis(chan->channel);
		if (ret == -EIO || ret == -ENODEV)
			return ret;

		*val = ret;

		return IIO_VAL_INT;
	}

	return -EINVAL;
}

#define TOSHIBA_IIO_ACCEL_CHANNEL(axis, chan) { \
	.type = IIO_ACCEL, \
	.modified = 1, \
	.channel = chan, \
	.channel2 = IIO_MOD_##axis, \
	.output = 1, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
}

static const struct iio_chan_spec toshiba_iio_accel_channels[] = {
	TOSHIBA_IIO_ACCEL_CHANNEL(X, AXIS_X),
	TOSHIBA_IIO_ACCEL_CHANNEL(Y, AXIS_Y),
	TOSHIBA_IIO_ACCEL_CHANNEL(Z, AXIS_Z),
};

static const struct iio_info toshiba_iio_accel_info = {
	.read_raw = &toshiba_iio_accel_read_raw,
};

/*
 * 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,
};

/*
 * WWAN RFKill handlers
 */
static int toshiba_acpi_wwan_set_block(void *data, bool blocked)
{
	struct toshiba_acpi_dev *dev = data;
	int ret;

	ret = toshiba_wireless_status(dev);
	if (ret)
		return ret;

	if (!dev->killswitch)
		return 0;

	return toshiba_wwan_set(dev, !blocked);
}

static void toshiba_acpi_wwan_poll(struct rfkill *rfkill, void *data)
{
	struct toshiba_acpi_dev *dev = data;

	if (toshiba_wireless_status(dev))
		return;

	rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);
}

static const struct rfkill_ops wwan_rfk_ops = {
	.set_block = toshiba_acpi_wwan_set_block,
	.poll = toshiba_acpi_wwan_poll,
};

static int toshiba_acpi_setup_wwan_rfkill(struct toshiba_acpi_dev *dev)
{
	int ret = toshiba_wireless_status(dev);

	if (ret)
		return ret;

	dev->wwan_rfk = rfkill_alloc("Toshiba WWAN",
				     &dev->acpi_dev->dev,
				     RFKILL_TYPE_WWAN,
				     &wwan_rfk_ops,
				     dev);
	if (!dev->wwan_rfk) {
		pr_err("Unable to allocate WWAN rfkill device\n");
		return -ENOMEM;
	}

	rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);

	ret = rfkill_register(dev->wwan_rfk);
	if (ret) {
		pr_err("Unable to register WWAN rfkill device\n");
		rfkill_destroy(dev->wwan_rfk);
	}

	return ret;
}

/*
 * 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;

	/*
	 * Enable quickstart buttons if supported.
	 *
	 * Enable the "Special Functions" mode only if they are
	 * supported and if they are activated.
	 */
	if (hci_hotkey_quickstart)
		result = hci_write(dev, HCI_HOTKEY_EVENT,
				   HCI_HOTKEY_ENABLE_QUICKSTART);
	else 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);

	if (result == TOS_FAILURE)
		return -EIO;
	else if (result == TOS_NOT_SUPPORTED)
		return -ENODEV;

	return 0;
}

static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
				      struct serio *port)
{
	if (str & I8042_STR_AUXDATA)
		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)
{
	unsigned long long value;
	acpi_status status;

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

	return value;
}

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

	/* Act on key press; ignore key release */
	if (scancode & 0x80)
		return;

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

static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev)
{
	if (dev->info_supported) {
		int scancode = toshiba_acpi_query_hotkey(dev);

		if (scancode < 0) {
			pr_err("Failed to query hotkey event\n");
		} else if (scancode != 0) {
			toshiba_acpi_report_hotkey(dev, scancode);
			dev->key_event_valid = 1;
			dev->last_key_event = scancode;
		}
	} else if (dev->system_event_supported) {
		u32 result;
		u32 value;
		int retries = 3;

		do {
			result = hci_read(dev, HCI_SYSTEM_EVENT, &value);
			switch (result) {
			case TOS_SUCCESS:
				toshiba_acpi_report_hotkey(dev, (int)value);
				dev->key_event_valid = 1;
				dev->last_key_event = value;
				break;
			case TOS_NOT_SUPPORTED:
				/*
				 * This is a workaround for an unresolved
				 * issue on some machines where system events
				 * sporadically become disabled.
				 */
				result = hci_write(dev, HCI_SYSTEM_EVENT, 1);
				if (result == TOS_SUCCESS)
					pr_notice("Re-enabled hotkeys\n");
				fallthrough;
			default:
				retries--;
				break;
			}
		} while (retries && result != TOS_FIFO_EMPTY);
	}
}

static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
{
	const struct key_entry *keymap = toshiba_acpi_keymap;
	acpi_handle ec_handle;
	int error;

	if (disable_hotkeys) {
		pr_info("Hotkeys disabled by module parameter\n");
		return 0;
	}

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

	error = toshiba_acpi_enable_hotkeys(dev);
	if (error)
		return error;

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

	dev->hotkey_dev = input_allocate_device();
	if (!dev->hotkey_dev)
		return -ENOMEM;

	dev->hotkey_dev->name = "Toshiba input device";
	dev->hotkey_dev->phys = "toshiba_acpi/input0";
	dev->hotkey_dev->id.bustype = BUS_HOST;
	dev->hotkey_dev->dev.parent = &dev->acpi_dev->dev;

	if (dev->hotkey_event_type == HCI_SYSTEM_TYPE1 ||
	    !dev->kbd_function_keys_supported)
		keymap = toshiba_acpi_keymap;
	else if (dev->hotkey_event_type == HCI_SYSTEM_TYPE2 ||
		 dev->kbd_function_keys_supported)
		keymap = toshiba_acpi_alt_keymap;
	else
		pr_info("Unknown event type received %x\n",
			dev->hotkey_event_type);
	error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL);
	if (error)
		goto err_free_dev;

	/*
	 * 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();
	if (ec_handle && acpi_has_method(ec_handle, "NTFY")) {
		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_dev;
		}

		dev->ntfy_supported = 1;
	}

	/*
	 * Determine hotkey query interface. Prefer using the INFO
	 * method when it is available.
	 */
	if (acpi_has_method(dev->acpi_dev->handle, "INFO"))
		dev->info_supported = 1;
	else if (hci_write(dev, HCI_SYSTEM_EVENT, 1) == TOS_SUCCESS)
		dev->system_event_supported = 1;

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

	error = input_register_device(dev->hotkey_dev);
	if (error) {
		pr_info("Unable to register input device\n");
		goto err_remove_filter;
	}

	return 0;

 err_remove_filter:
	if (dev->ntfy_supported)
		i8042_remove_filter(toshiba_acpi_i8042_filter);
 err_free_dev:
	input_free_device(dev->hotkey_dev);
	dev->hotkey_dev = NULL;
	return error;
}

static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
{
	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;
	/*
	 * If transflective backlight is supported and the brightness is zero
	 * (lowest brightness level), the set_lcd_brightness function will
	 * activate the transflective backlight, making the LCD appear to be
	 * turned off, simply increment the brightness level to avoid that.
	 */
	if (dev->tr_backlight_supported && brightness == 0)
		brightness++;
	ret = set_lcd_brightness(dev, brightness);
	if (ret) {
		pr_debug("Backlight method is read-only, disabling backlight support\n");
		return 0;
	}

	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
		return 0;

	memset(&props, 0, sizeof(props));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;

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

	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;
}

/* HWMON support for fan */
#if IS_ENABLED(CONFIG_HWMON)
static umode_t toshiba_acpi_hwmon_is_visible(const void *drvdata,
					     enum hwmon_sensor_types type,
					     u32 attr, int channel)
{
	return 0444;
}

static int toshiba_acpi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
				   u32 attr, int channel, long *val)
{
	/*
	 * There is only a single channel and single attribute (for the
	 * fan) at this point.
	 * This can be replaced with more advanced logic in the future,
	 * should the need arise.
	 */
	if (type == hwmon_fan && channel == 0 && attr == hwmon_fan_input) {
		u32 value;
		int ret;

		ret = get_fan_rpm(toshiba_acpi, &value);
		if (ret)
			return ret;

		*val = value;
		return 0;
	}
	return -EOPNOTSUPP;
}

static const struct hwmon_channel_info * const toshiba_acpi_hwmon_info[] = {
	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT),
	NULL
};

static const struct hwmon_ops toshiba_acpi_hwmon_ops = {
	.is_visible = toshiba_acpi_hwmon_is_visible,
	.read = toshiba_acpi_hwmon_read,
};

static const struct hwmon_chip_info toshiba_acpi_hwmon_chip_info = {
	.ops = &toshiba_acpi_hwmon_ops,
	.info = toshiba_acpi_hwmon_info,
};
#endif

/* ACPI battery hooking */
static ssize_t charge_control_end_threshold_show(struct device *device,
						 struct device_attribute *attr,
						 char *buf)
{
	u32 state;
	int status;

	if (toshiba_acpi == NULL) {
		pr_err("Toshiba ACPI object invalid\n");
		return -ENODEV;
	}

	status = toshiba_battery_charge_mode_get(toshiba_acpi, &state);

	if (status != 0)
		return status;

	if (state == 1)
		return sprintf(buf, "80\n");
	else
		return sprintf(buf, "100\n");
}

static ssize_t charge_control_end_threshold_store(struct device *dev,
						  struct device_attribute *attr,
						  const char *buf,
						  size_t count)
{
	u32 value;
	int rval;

	if (toshiba_acpi == NULL) {
		pr_err("Toshiba ACPI object invalid\n");
		return -ENODEV;
	}

	rval = kstrtou32(buf, 10, &value);
	if (rval)
		return rval;

	if (value < 1 || value > 100)
		return -EINVAL;
	rval = toshiba_battery_charge_mode_set(toshiba_acpi,
					       (value < 90) ? 1 : 0);
	if (rval < 0)
		return rval;
	else
		return count;
}

static DEVICE_ATTR_RW(charge_control_end_threshold);

static struct attribute *toshiba_acpi_battery_attrs[] = {
	&dev_attr_charge_control_end_threshold.attr,
	NULL,
};

ATTRIBUTE_GROUPS(toshiba_acpi_battery);

static int toshiba_acpi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
{
	if (toshiba_acpi == NULL) {
		pr_err("Init order issue\n");
		return -ENODEV;
	}
	if (!toshiba_acpi->battery_charge_mode_supported)
		return -ENODEV;
	if (device_add_groups(&battery->dev, toshiba_acpi_battery_groups))
		return -ENODEV;
	return 0;
}

static int toshiba_acpi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)
{
	device_remove_groups(&battery->dev, toshiba_acpi_battery_groups);
	return 0;
}

static struct acpi_battery_hook battery_hook = {
	.add_battery = toshiba_acpi_battery_add,
	.remove_battery = toshiba_acpi_battery_remove,
	.name = "Toshiba Battery Extension",
};

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->fan_rpm_supported)
		pr_cont(" fan-rpm");
	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");
	if (dev->wwan_supported)
		pr_cont(" wwan");
	if (dev->cooling_method_supported)
		pr_cont(" cooling-method");
	if (dev->battery_charge_mode_supported)
		pr_cont(" battery-charge-mode");

	pr_cont("\n");
}

static void toshiba_acpi_remove(struct acpi_device *acpi_dev)
{
	struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);

	misc_deregister(&dev->miscdev);

	remove_toshiba_proc_entries(dev);

#if IS_ENABLED(CONFIG_HWMON)
	if (dev->hwmon_device)
		hwmon_device_unregister(dev->hwmon_device);
#endif

	if (dev->accelerometer_supported && dev->indio_dev) {
		iio_device_unregister(dev->indio_dev);
		iio_device_free(dev->indio_dev);
	}

	if (dev->sysfs_created)
		sysfs_remove_group(&dev->acpi_dev->dev.kobj,
				   &toshiba_attr_group);

	if (dev->ntfy_supported) {
		i8042_remove_filter(toshiba_acpi_i8042_filter);
		cancel_work_sync(&dev->hotkey_work);
	}

	if (dev->hotkey_dev)
		input_unregister_device(dev->hotkey_dev);

	backlight_device_unregister(dev->backlight_dev);

	led_classdev_unregister(&dev->led_dev);
	led_classdev_unregister(&dev->kbd_led);
	led_classdev_unregister(&dev->eco_led);

	if (dev->wwan_rfk) {
		rfkill_unregister(dev->wwan_rfk);
		rfkill_destroy(dev->wwan_rfk);
	}

	if (dev->battery_charge_mode_supported)
		battery_hook_unregister(&battery_hook);

	if (toshiba_acpi)
		toshiba_acpi = NULL;

	kfree(dev);
}

static const char *find_hci_method(acpi_handle handle)
{
	if (acpi_has_method(handle, "GHCI"))
		return "GHCI";

	if (acpi_has_method(handle, "SPFC"))
		return "SPFC";

	return NULL;
}

/*
 * Some Toshibas have a broken acpi-video interface for brightness control,
 * these are quirked in drivers/acpi/video_detect.c to use the GPU native
 * (/sys/class/backlight/intel_backlight) instead.
 * But these need a HCI_SET call to actually turn the panel back on at resume,
 * without this call the screen stays black at resume.
 * Either HCI_LCD_BRIGHTNESS (used by acpi_video's _BCM) or HCI_PANEL_POWER_ON
 * works. toshiba_acpi_resume() uses HCI_PANEL_POWER_ON to avoid changing
 * the configured brightness level.
 */
#define QUIRK_TURN_ON_PANEL_ON_RESUME		BIT(0)
/*
 * Some Toshibas use "quickstart" keys. On these, HCI_HOTKEY_EVENT must use
 * the value HCI_HOTKEY_ENABLE_QUICKSTART.
 */
#define QUIRK_HCI_HOTKEY_QUICKSTART		BIT(1)

static const struct dmi_system_id toshiba_dmi_quirks[] __initconst = {
	{
	 /* Toshiba Portégé R700 */
	 /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
	 .matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
		DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
		},
	 .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
	},
	{
	 /* Toshiba Satellite/Portégé R830 */
	 /* Portégé: https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
	 /* Satellite: https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
	 .matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
		DMI_MATCH(DMI_PRODUCT_NAME, "R830"),
		},
	 .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
	},
	{
	 /* Toshiba Satellite/Portégé Z830 */
	 .matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
		DMI_MATCH(DMI_PRODUCT_NAME, "Z830"),
		},
	 .driver_data = (void *)(QUIRK_TURN_ON_PANEL_ON_RESUME | QUIRK_HCI_HOTKEY_QUICKSTART),
	},
	{ }
};

static int toshiba_acpi_add(struct acpi_device *acpi_dev)
{
	struct toshiba_acpi_dev *dev;
	const char *hci_method;
	u32 dummy;
	int ret = 0;

	if (toshiba_acpi)
		return -EBUSY;

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

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

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;
	dev->acpi_dev = acpi_dev;
	dev->method_hci = hci_method;
	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;
	}

	acpi_dev->driver_data = dev;
	dev_set_drvdata(&acpi_dev->dev, dev);

	/* 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.
	 */
	ret = toshiba_function_keys_get(dev, &dev->special_functions);
	dev->kbd_function_keys_supported = !ret;

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

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

	ret = toshiba_acpi_setup_backlight(dev);
	if (ret)
		goto error;

	toshiba_illumination_available(dev);
	if (dev->illumination_supported) {
		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;
		led_classdev_register(&acpi_dev->dev, &dev->led_dev);
	}

	toshiba_eco_mode_available(dev);
	if (dev->eco_supported) {
		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;
		led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led);
	}

	toshiba_kbd_illum_available(dev);
	/*
	 * Only register the LED if KBD illumination is supported
	 * and the keyboard backlight operation mode is set to FN-Z
	 * or we detect a second gen keyboard backlight
	 */
	if (dev->kbd_illum_supported &&
	    (dev->kbd_mode == SCI_KBD_MODE_FNZ || dev->kbd_type == 2)) {
		dev->kbd_led.name = "toshiba::kbd_backlight";
		dev->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
		dev->kbd_led.max_brightness = 1;
		dev->kbd_led.brightness_set = toshiba_kbd_backlight_set;
		dev->kbd_led.brightness_get = toshiba_kbd_backlight_get;
		led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led);
	}

	ret = toshiba_touchpad_get(dev, &dummy);
	dev->touchpad_supported = !ret;

	toshiba_accelerometer_available(dev);
	if (dev->accelerometer_supported) {
		dev->indio_dev = iio_device_alloc(&acpi_dev->dev, sizeof(*dev));
		if (!dev->indio_dev) {
			pr_err("Unable to allocate iio device\n");
			goto iio_error;
		}

		pr_info("Registering Toshiba accelerometer iio device\n");

		dev->indio_dev->info = &toshiba_iio_accel_info;
		dev->indio_dev->name = "Toshiba accelerometer";
		dev->indio_dev->modes = INDIO_DIRECT_MODE;
		dev->indio_dev->channels = toshiba_iio_accel_channels;
		dev->indio_dev->num_channels =
					ARRAY_SIZE(toshiba_iio_accel_channels);

		ret = iio_device_register(dev->indio_dev);
		if (ret < 0) {
			pr_err("Unable to register iio device\n");
			iio_device_free(dev->indio_dev);
		}
	}
iio_error:

	toshiba_usb_sleep_charge_available(dev);

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

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

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

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

	ret = get_video_status(dev, &dummy);
	dev->video_supported = !ret;

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

	ret = get_fan_rpm(dev, &dummy);
	dev->fan_rpm_supported = !ret;

#if IS_ENABLED(CONFIG_HWMON)
	if (dev->fan_rpm_supported) {
		dev->hwmon_device = hwmon_device_register_with_info(
			&dev->acpi_dev->dev, "toshiba_acpi_sensors", NULL,
			&toshiba_acpi_hwmon_chip_info, NULL);
		if (IS_ERR(dev->hwmon_device)) {
			dev->hwmon_device = NULL;
			pr_warn("unable to register hwmon device, skipping\n");
		}
	}
#endif

	toshiba_wwan_available(dev);
	if (dev->wwan_supported)
		toshiba_acpi_setup_wwan_rfkill(dev);

	toshiba_cooling_method_available(dev);

	toshiba_battery_charge_mode_available(dev);

	print_supported_features(dev);

	ret = sysfs_create_group(&dev->acpi_dev->dev.kobj,
				 &toshiba_attr_group);
	if (ret) {
		dev->sysfs_created = 0;
		goto error;
	}
	dev->sysfs_created = !ret;

	create_toshiba_proc_entries(dev);

	toshiba_acpi = dev;

	/*
	 * As the battery hook relies on the static variable toshiba_acpi being
	 * set, this must be done after toshiba_acpi is assigned.
	 */
	if (dev->battery_charge_mode_supported)
		battery_hook_register(&battery_hook);

	return 0;

error:
	toshiba_acpi_remove(acpi_dev);
	return ret;
}

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

	switch (event) {
	case 0x80: /* Hotkeys and some system events */
		/*
		 * 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;
		toshiba_acpi_process_hotkeys(dev);
		break;
	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;
	case 0x92: /* Keyboard backlight mode changed */
		dev->kbd_event_generated = true;
		/* Update sysfs entries */
		if (sysfs_update_group(&acpi_dev->dev.kobj,
				       &toshiba_attr_group))
			pr_err("Unable to update sysfs entries\n");
		/* Notify LED subsystem about keyboard backlight change */
		if (dev->kbd_type == 2 && dev->kbd_mode != SCI_KBD_MODE_AUTO)
			led_classdev_notify_brightness_hw_changed(&dev->kbd_led,
					(dev->kbd_mode == SCI_KBD_MODE_ON) ?
					LED_FULL : LED_OFF);
		break;
	case 0x8e: /* Power button pressed */
		break;
	case 0x85: /* Unknown */
	case 0x8d: /* Unknown */
	case 0x94: /* Unknown */
	case 0x95: /* Unknown */
	default:
		pr_info("Unknown event received %x\n", event);
		break;
	}

	acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class,
					dev_name(&acpi_dev->dev),
					event, (event == 0x80) ?
					dev->last_key_event : 0);
}

#ifdef CONFIG_PM_SLEEP
static int toshiba_acpi_suspend(struct device *device)
{
	struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));

	if (dev->hotkey_dev) {
		u32 result;

		result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE);
		if (result != TOS_SUCCESS)
			pr_info("Unable to disable hotkeys\n");
	}

	return 0;
}

static int toshiba_acpi_resume(struct device *device)
{
	struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));

	if (dev->hotkey_dev) {
		if (toshiba_acpi_enable_hotkeys(dev))
			pr_info("Unable to re-enable hotkeys\n");
	}

	if (dev->wwan_rfk) {
		if (!toshiba_wireless_status(dev))
			rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);
	}

	if (turn_on_panel_on_resume)
		hci_write(dev, HCI_PANEL_POWER_ON, 1);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm,
			 toshiba_acpi_suspend, toshiba_acpi_resume);

static struct acpi_driver toshiba_acpi_driver = {
	.name	= "Toshiba ACPI driver",
	.ids	= toshiba_device_ids,
	.flags	= ACPI_DRIVER_ALL_NOTIFY_EVENTS,
	.ops	= {
		.add		= toshiba_acpi_add,
		.remove		= toshiba_acpi_remove,
		.notify		= toshiba_acpi_notify,
	},
	.drv.pm	= &toshiba_acpi_pm,
};

static void __init toshiba_dmi_init(void)
{
	const struct dmi_system_id *dmi_id;
	long quirks = 0;

	dmi_id = dmi_first_match(toshiba_dmi_quirks);
	if (dmi_id)
		quirks = (long)dmi_id->driver_data;

	if (turn_on_panel_on_resume == -1)
		turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME);

	if (hci_hotkey_quickstart == -1)
		hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART);
}

static int __init toshiba_acpi_init(void)
{
	int ret;

	toshiba_dmi_init();
	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);
}

module_init(toshiba_acpi_init);
module_exit(toshiba_acpi_exit);
