From e26ffe5124189bce99235fee403a71b719e10b6a Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Sun, 18 Jan 2015 18:30:22 -0700 Subject: toshiba_acpi: Add support for USB Sleep and Charge function Newer Toshiba models now come with a feature called Sleep and Charge, where the computer USB ports remain powered when the computer is asleep or turned off. This patch adds support to such feature, creating a sysfs entry called "usb_sleep_charge" to set the desired charging mode or to disable it. The sysfs entry accepts three parameters, 0, 1 and 2, beign disabled, alternate and auto respectively. The auto mode stands for USB conformant devices (which most are), and the alternate mode stands for those non USB conformant devices that require more power. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index fc34a71..6c3e25c 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -122,6 +122,7 @@ MODULE_LICENSE("GPL"); #define HCI_ECO_MODE 0x0097 #define HCI_ACCELEROMETER2 0x00a6 #define SCI_ILLUMINATION 0x014e +#define SCI_USB_SLEEP_CHARGE 0x0150 #define SCI_KBD_ILLUM_STATUS 0x015c #define SCI_TOUCHPAD 0x050e @@ -146,6 +147,10 @@ MODULE_LICENSE("GPL"); #define SCI_KBD_MODE_ON 0x8 #define SCI_KBD_MODE_OFF 0x10 #define SCI_KBD_TIME_MAX 0x3c001a +#define SCI_USB_CHARGE_MODE_MASK 0xff +#define SCI_USB_CHARGE_DISABLED 0x30000 +#define SCI_USB_CHARGE_ALTERNATE 0x30009 +#define SCI_USB_CHARGE_AUTO 0x30021 struct toshiba_acpi_dev { struct acpi_device *acpi_dev; @@ -177,6 +182,7 @@ struct toshiba_acpi_dev { unsigned int touchpad_supported:1; unsigned int eco_supported:1; unsigned int accelerometer_supported:1; + unsigned int usb_sleep_charge_supported:1; unsigned int sysfs_created:1; struct mutex mutex; @@ -760,6 +766,53 @@ static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, return 0; } +/* Sleep (Charge and Music) utilities support */ +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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + +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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1313,6 +1366,12 @@ static ssize_t toshiba_touchpad_show(struct device *dev, static ssize_t toshiba_position_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t toshiba_usb_sleep_charge_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_usb_sleep_charge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); @@ -1324,6 +1383,9 @@ static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, toshiba_touchpad_show, toshiba_touchpad_store); static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); +static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, + toshiba_usb_sleep_charge_show, + toshiba_usb_sleep_charge_store); static struct attribute *toshiba_attributes[] = { &dev_attr_kbd_backlight_mode.attr, @@ -1332,6 +1394,7 @@ static struct attribute *toshiba_attributes[] = { &dev_attr_kbd_backlight_timeout.attr, &dev_attr_touchpad.attr, &dev_attr_position.attr, + &dev_attr_usb_sleep_charge.attr, NULL, }; @@ -1549,6 +1612,56 @@ static ssize_t toshiba_position_show(struct device *dev, return sprintf(buf, "%d %d %d\n", x, y, z); } +static ssize_t toshiba_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 toshiba_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); + u32 mode; + int state; + 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) + */ + if (state != 0 && state != 1 && state != 2) + return -EINVAL; + + /* Set the USB charging mode to internal value */ + 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; + + ret = toshiba_usb_sleep_charge_set(toshiba, mode); + if (ret) + return ret; + + return count; +} + static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -1564,6 +1677,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, exists = (drv->touchpad_supported) ? true : false; else if (attr == &dev_attr_position.attr) exists = (drv->accelerometer_supported) ? true : false; + else if (attr == &dev_attr_usb_sleep_charge.attr) + exists = (drv->usb_sleep_charge_supported) ? true : false; return exists ? attr->mode : 0; } @@ -1973,6 +2088,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) ret = toshiba_accelerometer_supported(dev); dev->accelerometer_supported = !ret; + ret = toshiba_usb_sleep_charge_get(dev, &dummy); + dev->usb_sleep_charge_supported = !ret; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 182bcaa5c90a66429fcf00a6a02a7bf845bf27c5 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Sun, 18 Jan 2015 18:30:23 -0700 Subject: toshiba_acpi: Add support for USB Sleep functions under battery Toshiba laptops supporting USB Sleep and Charge also come with a feature called "USB functions under battery", which what it does when enabled, is allows the USB Sleep functions when the computer is under battery power. This patch adds support to that function, creating a sysfs entry named "sleep_functions_on_battery", accepting values from 0-100, where zero disables the function and 1-100 sets the battery level at which point the USB Sleep functions will be disabled, and printing the current state of the functon and also the battery level currently set. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 6c3e25c..a8b719f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -151,6 +151,10 @@ MODULE_LICENSE("GPL"); #define SCI_USB_CHARGE_DISABLED 0x30000 #define SCI_USB_CHARGE_ALTERNATE 0x30009 #define SCI_USB_CHARGE_AUTO 0x30021 +#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 struct toshiba_acpi_dev { struct acpi_device *acpi_dev; @@ -169,6 +173,7 @@ struct toshiba_acpi_dev { int kbd_type; int kbd_mode; int kbd_time; + int usbsc_bat_level; unsigned int illumination_supported:1; unsigned int video_supported:1; @@ -813,6 +818,61 @@ static int toshiba_usb_sleep_charge_set(struct toshiba_acpi_dev *dev, return 0; } +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) || out[0] == TOS_FAILURE) { + pr_err("ACPI call to get USB S&C battery level failed\n"); + return -EIO; + } else if (out[0] == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (out[0] == TOS_INPUT_DATA_ERROR) { + 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) || out[0] == TOS_FAILURE) { + pr_err("ACPI call to set USB S&C battery level failed\n"); + return -EIO; + } else if (out[0] == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (out[0] == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1372,6 +1432,12 @@ static ssize_t toshiba_usb_sleep_charge_show(struct device *dev, static ssize_t toshiba_usb_sleep_charge_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t sleep_functions_on_battery_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t sleep_functions_on_battery_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); @@ -1386,6 +1452,9 @@ static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, toshiba_usb_sleep_charge_show, toshiba_usb_sleep_charge_store); +static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, + sleep_functions_on_battery_show, + sleep_functions_on_battery_store); static struct attribute *toshiba_attributes[] = { &dev_attr_kbd_backlight_mode.attr, @@ -1395,6 +1464,7 @@ static struct attribute *toshiba_attributes[] = { &dev_attr_touchpad.attr, &dev_attr_position.attr, &dev_attr_usb_sleep_charge.attr, + &dev_attr_sleep_functions_on_battery.attr, NULL, }; @@ -1662,6 +1732,67 @@ static ssize_t toshiba_usb_sleep_charge_store(struct device *dev, return count; } +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; + + /* 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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -1679,6 +1810,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, exists = (drv->accelerometer_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; return exists ? attr->mode : 0; } -- cgit v0.10.2 From bb3fe01ff693cbc05d4d06edbe9ec868050a262c Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Sun, 18 Jan 2015 18:30:24 -0700 Subject: toshiba_acpi: Add support for USB Rapid Charge Newer Toshiba laptops equipped with USB 3.0 ports now have the functionality of rapid charging devices connected to their USB hubs. This patch adds support to use such feature by creating a sysfs entry named "usb_rapid_charge", accepting only two values, 0 to disable and 1 to enable, however, the machine needs a restart everytime the function is toggled. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index a8b719f..0f1b7a8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -155,6 +155,7 @@ MODULE_LICENSE("GPL"); #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; @@ -188,6 +189,7 @@ struct toshiba_acpi_dev { 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 sysfs_created:1; struct mutex mutex; @@ -873,6 +875,60 @@ static int toshiba_sleep_functions_status_set(struct toshiba_acpi_dev *dev, return 0; } +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) || out[0] == TOS_FAILURE) { + pr_err("ACPI call to get USB S&C battery level failed\n"); + return -EIO; + } else if (out[0] == TOS_NOT_SUPPORTED || + out[0] == TOS_INPUT_DATA_ERROR) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } + + *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) || out[0] == TOS_FAILURE) { + pr_err("ACPI call to set USB S&C battery level failed\n"); + return -EIO; + } else if (out[0] == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (out[0] == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1438,6 +1494,12 @@ static ssize_t sleep_functions_on_battery_show(struct device *dev, static ssize_t sleep_functions_on_battery_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t toshiba_usb_rapid_charge_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); @@ -1455,6 +1517,9 @@ static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, sleep_functions_on_battery_show, sleep_functions_on_battery_store); +static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, + toshiba_usb_rapid_charge_show, + toshiba_usb_rapid_charge_store); static struct attribute *toshiba_attributes[] = { &dev_attr_kbd_backlight_mode.attr, @@ -1465,6 +1530,7 @@ static struct attribute *toshiba_attributes[] = { &dev_attr_position.attr, &dev_attr_usb_sleep_charge.attr, &dev_attr_sleep_functions_on_battery.attr, + &dev_attr_usb_rapid_charge.attr, NULL, }; @@ -1793,6 +1859,42 @@ static ssize_t sleep_functions_on_battery_store(struct device *dev, return count; } +static ssize_t toshiba_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 toshiba_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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -1812,6 +1914,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 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; return exists ? attr->mode : 0; } @@ -2224,6 +2328,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) ret = toshiba_usb_sleep_charge_get(dev, &dummy); dev->usb_sleep_charge_supported = !ret; + ret = toshiba_usb_rapid_charge_get(dev, &dummy); + dev->usb_rapid_charge_supported = !ret; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 172ce0a9f6bf4460fae74026014650cc4a90d37c Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Sun, 18 Jan 2015 18:30:25 -0700 Subject: toshiba_acpi: Add support for USB Sleep and Music Newer Toshiba laptops now come with a feature called USB Sleep and Music, where the laptop speakers remain powered and the line-in jack is used to connect an external device to use the laptop speakers when the computer is asleep or turned off. This patchs adds support to such feature, by creating a sysfs entry named "usb_sleep_music", accepting only two values, 0 to disable and 1 to enable. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 0f1b7a8..446ddc1 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -124,6 +124,7 @@ MODULE_LICENSE("GPL"); #define SCI_ILLUMINATION 0x014e #define SCI_USB_SLEEP_CHARGE 0x0150 #define SCI_KBD_ILLUM_STATUS 0x015c +#define SCI_USB_SLEEP_MUSIC 0x015e #define SCI_TOUCHPAD 0x050e /* field definitions */ @@ -190,6 +191,7 @@ struct toshiba_acpi_dev { 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 sysfs_created:1; struct mutex mutex; @@ -929,6 +931,50 @@ static int toshiba_usb_rapid_charge_set(struct toshiba_acpi_dev *dev, return 0; } +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 set USB S&C mode failed\n"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + +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 USB S&C mode failed\n"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB Sleep and Charge not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1500,6 +1546,12 @@ static ssize_t toshiba_usb_rapid_charge_show(struct device *dev, static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t toshiba_usb_sleep_music_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_usb_sleep_music_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); @@ -1520,6 +1572,9 @@ static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, toshiba_usb_rapid_charge_show, toshiba_usb_rapid_charge_store); +static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, + toshiba_usb_sleep_music_show, + toshiba_usb_sleep_music_store); static struct attribute *toshiba_attributes[] = { &dev_attr_kbd_backlight_mode.attr, @@ -1531,6 +1586,7 @@ static struct attribute *toshiba_attributes[] = { &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, NULL, }; @@ -1895,6 +1951,42 @@ static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, return count; } +static ssize_t toshiba_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 toshiba_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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -1916,6 +2008,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 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; return exists ? attr->mode : 0; } @@ -2331,6 +2425,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_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; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 4690555e13c48fef07f2762f6b0cd6b181e326d0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 9 Jan 2015 15:10:01 +0100 Subject: samsung-laptop: Add use_native_backlight quirk, and enable it on some models Since kernel 3.14 the backlight control has been broken on various Samsung Atom based netbooks. This has been bisected and this problem happens since commit b35684b8fa94 ("drm/i915: do full backlight setup at enable time") This has been reported and discussed in detail here: http://lists.freedesktop.org/archives/intel-gfx/2014-July/049395.html Unfortunately no-one has been able to fix this. This only affects Samsung Atom netbooks, and the Linux kernel and the BIOS of those laptops have never worked well together. All affected laptops already have a quirk to avoid using the standard acpi-video interface and instead use the samsung specific SABI interface which samsung-laptop uses. It seems that recent fixes to the i915 driver have also broken backlight control through the SABI interface. The intel_backlight driver OTOH works fine, and also allows for finer grained backlight control. So add a new use_native_backlight quirk, and replace the broken_acpi_video quirk with this quirk for affected models. This new quirk disables acpi-video as before and also stops samsung-laptop from registering the SABI based samsung_laptop backlight interface, leaving only the working intel_backlight interface. This commit enables this new quirk for 3 models which are known to be affected, chances are that it needs to be used on other models too. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1094948 # N145P BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1115713 # N250P Reported-by: Bertrik Sikken # N150P Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Hans de Goede Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index ff765d8..ce364a4 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -353,6 +353,7 @@ struct samsung_quirks { bool broken_acpi_video; bool four_kbd_backlight_levels; bool enable_kbd_backlight; + bool use_native_backlight; }; static struct samsung_quirks samsung_unknown = {}; @@ -361,6 +362,10 @@ static struct samsung_quirks samsung_broken_acpi_video = { .broken_acpi_video = true, }; +static struct samsung_quirks samsung_use_native_backlight = { + .use_native_backlight = true, +}; + static struct samsung_quirks samsung_np740u3e = { .four_kbd_backlight_levels = true, .enable_kbd_backlight = true, @@ -1507,7 +1512,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "N150P"), DMI_MATCH(DMI_BOARD_NAME, "N150P"), }, - .driver_data = &samsung_broken_acpi_video, + .driver_data = &samsung_use_native_backlight, }, { .callback = samsung_dmi_matched, @@ -1517,7 +1522,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), }, - .driver_data = &samsung_broken_acpi_video, + .driver_data = &samsung_use_native_backlight, }, { .callback = samsung_dmi_matched, @@ -1557,7 +1562,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), DMI_MATCH(DMI_BOARD_NAME, "N250P"), }, - .driver_data = &samsung_broken_acpi_video, + .driver_data = &samsung_use_native_backlight, }, { .callback = samsung_dmi_matched, @@ -1616,6 +1621,15 @@ static int __init samsung_init(void) pr_info("Disabling ACPI video driver\n"); acpi_video_unregister(); } + + if (samsung->quirks->use_native_backlight) { + pr_info("Using native backlight driver\n"); + /* Tell acpi-video to not handle the backlight */ + acpi_video_dmi_promote_vendor(); + acpi_video_unregister(); + /* And also do not handle it ourselves */ + samsung->handle_backlight = false; + } #endif ret = samsung_platform_init(samsung); -- cgit v0.10.2 From e8549e2cf3dc3ab3222a71eac551eea9769ce86b Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Sun, 18 Jan 2015 20:28:46 +0100 Subject: fujitsu-laptop: use FB_BLANK_* constants Replace the magic numbers in fujitsu-laptop.c by the appropriate FB_BLANK constants, as indicated by the comment for backlight_properties.power in include/linux/backlight.h. Signed-off-by: Michael Karcher Acked-by: Jonathan Woithe Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 7c21c1c..2a9afa2 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -398,7 +399,7 @@ static int bl_get_brightness(struct backlight_device *b) static int bl_update_status(struct backlight_device *b) { int ret; - if (b->props.power == 4) + if (b->props.power == FB_BLANK_POWERDOWN) ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x3); else ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x0); @@ -1139,9 +1140,9 @@ static int __init fujitsu_init(void) if (!acpi_video_backlight_support()) { if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) - fujitsu->bl_device->props.power = 4; + fujitsu->bl_device->props.power = FB_BLANK_POWERDOWN; else - fujitsu->bl_device->props.power = 0; + fujitsu->bl_device->props.power = FB_BLANK_UNBLANK; } pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); -- cgit v0.10.2 From 03070e7c9d2dde754e49b189a195a7f5cc1ac7a1 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sun, 18 Jan 2015 18:25:24 -0500 Subject: asus-laptop: Fix is_visible return value With a Lucid platform, asus_sysfs_is_visible() returned a boolean for ls_switch and ls_level attributes. Signed-off-by: Vivien Didelot Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index f71700e..00f5e82 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1616,7 +1616,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, else goto normal; - return supported; + return supported ? attr->mode : 0; } normal: -- cgit v0.10.2 From 7c2e3c74767cf108635d1a5bd9fe014474c61ebf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 21 Jan 2015 21:38:09 +0200 Subject: intel_scu_ipc: fix indentation in few places While here, do couple of amendments: - move platform variable to the function where it's used - define intel_scu_ipc_check_status() static Signed-off-by: Andy Shevchenko Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 66a4d32..8938c31 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -1,7 +1,7 @@ /* * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism * - * (C) Copyright 2008-2010 Intel Corporation + * (C) Copyright 2008-2010,2015 Intel Corporation * Author: Sreedhara DS (sreedhara.ds@intel.com) * * This program is free software; you can redistribute it and/or @@ -67,7 +67,7 @@ #define PCI_DEVICE_ID_CLOVERVIEW 0x08ea #define PCI_DEVICE_ID_TANGIER 0x11a0 -/* intel scu ipc driver data*/ +/* intel scu ipc driver data */ struct intel_scu_ipc_pdata_t { u32 ipc_base; u32 i2c_base; @@ -114,8 +114,6 @@ struct intel_scu_ipc_dev { static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ -static int platform; /* Platform type */ - /* * IPC Read Buffer (Read Only): * 16 byte buffer for receiving data from SCU, if IPC command @@ -160,7 +158,6 @@ static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ * Format: * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| */ - static inline u8 ipc_read_status(void) { return __raw_readl(ipcdev.ipc_base + 0x04); @@ -176,7 +173,8 @@ static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */ return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); } -static inline int busy_loop(void) /* Wait till scu status is busy */ +/* Wait till scu status is busy */ +static inline int busy_loop(void) { u32 status = 0; u32 loop_count = 0; @@ -217,7 +215,7 @@ static inline int ipc_wait_for_interrupt(void) return 0; } -int intel_scu_ipc_check_status(void) +static int intel_scu_ipc_check_status(void) { return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); } @@ -248,18 +246,18 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) if (id == IPC_CMD_PCNTRL_R) { for (nc = 0, offset = 0; nc < count; nc++, offset += 4) ipc_data_writel(wbuf[nc], offset); - ipc_command((count*2) << 16 | id << 12 | 0 << 8 | op); + ipc_command((count * 2) << 16 | id << 12 | 0 << 8 | op); } else if (id == IPC_CMD_PCNTRL_W) { for (nc = 0; nc < count; nc++, offset += 1) cbuf[offset] = data[nc]; for (nc = 0, offset = 0; nc < count; nc++, offset += 4) ipc_data_writel(wbuf[nc], offset); - ipc_command((count*3) << 16 | id << 12 | 0 << 8 | op); + ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); } else if (id == IPC_CMD_PCNTRL_M) { cbuf[offset] = data[0]; cbuf[offset + 1] = data[1]; ipc_data_writel(wbuf[0], 0); /* Write wbuff */ - ipc_command(4 << 16 | id << 12 | 0 << 8 | op); + ipc_command(4 << 16 | id << 12 | 0 << 8 | op); } err = intel_scu_ipc_check_status(); @@ -301,7 +299,7 @@ EXPORT_SYMBOL(intel_scu_ipc_ioread8); */ int intel_scu_ipc_ioread16(u16 addr, u16 *data) { - u16 x[2] = {addr, addr + 1 }; + u16 x[2] = {addr, addr + 1}; return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); } EXPORT_SYMBOL(intel_scu_ipc_ioread16); @@ -351,7 +349,7 @@ EXPORT_SYMBOL(intel_scu_ipc_iowrite8); */ int intel_scu_ipc_iowrite16(u16 addr, u16 data) { - u16 x[2] = {addr, addr + 1 }; + u16 x[2] = {addr, addr + 1}; return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); } EXPORT_SYMBOL(intel_scu_ipc_iowrite16); @@ -412,7 +410,6 @@ int intel_scu_ipc_writev(u16 *addr, u8 *data, int len) } EXPORT_SYMBOL(intel_scu_ipc_writev); - /** * intel_scu_ipc_update_register - r/m/w a register * @addr: register address @@ -475,9 +472,8 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command); * Issue a command to the SCU which involves data transfers. Do the * data copies under the lock but leave it for the caller to interpret */ - int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, - u32 *out, int outlen) + u32 *out, int outlen) { int i, err; @@ -503,7 +499,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, } EXPORT_SYMBOL(intel_scu_ipc_command); -/*I2C commands */ +/* I2C commands */ #define IPC_I2C_WRITE 1 /* I2C Write command */ #define IPC_I2C_READ 2 /* I2C Read command */ @@ -666,9 +662,10 @@ static struct pci_driver ipc_driver = { .remove = ipc_remove, }; - static int __init intel_scu_ipc_init(void) { + int platform; /* Platform type */ + platform = intel_mid_identify_cpu(); if (platform == 0) return -ENODEV; -- cgit v0.10.2 From f0295a36dc31774019be278468e22c254f9626e4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 21 Jan 2015 21:38:10 +0200 Subject: intel_scu_ipc: move error check out of the loop This is small performance optimization of the busy_loop(). While here, use BIT() macro instead of plain integers when check the status. Signed-off-by: Andy Shevchenko Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 8938c31..e6430a3 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -176,21 +176,21 @@ static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */ /* Wait till scu status is busy */ static inline int busy_loop(void) { - u32 status = 0; - u32 loop_count = 0; + u32 status = ipc_read_status(); + u32 loop_count = 100000; - status = ipc_read_status(); - while (status & 1) { + /* break if scu doesn't reset busy bit after huge retry */ + while ((status & BIT(0)) && --loop_count) { udelay(1); /* scu processing time is in few u secods */ status = ipc_read_status(); - loop_count++; - /* break if scu doesn't reset busy bit after huge retry */ - if (loop_count > 100000) { - dev_err(&ipcdev.pdev->dev, "IPC timed out"); - return -ETIMEDOUT; - } } - if ((status >> 1) & 1) + + if (status & BIT(0)) { + dev_err(&ipcdev.pdev->dev, "IPC timed out"); + return -ETIMEDOUT; + } + + if (status & BIT(1)) return -EIO; return 0; @@ -208,8 +208,7 @@ static inline int ipc_wait_for_interrupt(void) } status = ipc_read_status(); - - if ((status >> 1) & 1) + if (status & BIT(1)) return -EIO; return 0; -- cgit v0.10.2 From 32d0e4a33773ad68c582999a5b945cc47bb02809 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 21 Jan 2015 21:38:11 +0200 Subject: intel_scu_ipc: Read resources from PCI configuration Read the resources from PCI BAR0 instead of using hardcoded values. Signed-off-by: Andy Shevchenko Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index e6430a3..001b199 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -43,10 +43,9 @@ /* * IPC register summary * - * IPC register blocks are memory mapped at fixed address of 0xFF11C000 + * IPC register blocks are memory mapped at fixed address of PCI BAR 0. * To read or write information to the SCU, driver writes to IPC-1 memory - * mapped registers (base address 0xFF11C000). The following is the IPC - * mechanism + * mapped registers. The following is the IPC mechanism * * 1. IA core cDMI interface claims this transaction and converts it to a * Transaction Layer Packet (TLP) message which is sent across the cDMI. @@ -69,34 +68,26 @@ /* intel scu ipc driver data */ struct intel_scu_ipc_pdata_t { - u32 ipc_base; u32 i2c_base; - u32 ipc_len; u32 i2c_len; u8 irq_mode; }; static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { - .ipc_base = 0xff11c000, .i2c_base = 0xff12b000, - .ipc_len = 0x100, .i2c_len = 0x10, .irq_mode = 0, }; /* Penwell and Cloverview */ static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { - .ipc_base = 0xff11c000, .i2c_base = 0xff12b000, - .ipc_len = 0x100, .i2c_len = 0x10, .irq_mode = 1, }; static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { - .ipc_base = 0xff009000, .i2c_base = 0xff00d000, - .ipc_len = 0x100, .i2c_len = 0x10, .irq_mode = 0, }; @@ -572,7 +563,7 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) { int err; struct intel_scu_ipc_pdata_t *pdata; - resource_size_t pci_resource; + resource_size_t base; if (ipcdev.pdev) /* We support only one SCU */ return -EBUSY; @@ -590,8 +581,8 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) if (err) return err; - pci_resource = pci_resource_start(dev, 0); - if (!pci_resource) + base = pci_resource_start(dev, 0); + if (!base) return -ENOMEM; init_completion(&ipcdev.cmd_complete); @@ -599,7 +590,7 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) return -EBUSY; - ipcdev.ipc_base = ioremap_nocache(pdata->ipc_base, pdata->ipc_len); + ipcdev.ipc_base = ioremap_nocache(base, pci_resource_len(dev, 0)); if (!ipcdev.ipc_base) return -ENOMEM; -- cgit v0.10.2 From ed52ccbce7ffdde51f116e2cc9de00251f1ff7c5 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 23 Jan 2015 09:01:10 -0500 Subject: asus-laptop: use DEVICE_ATTR_xx macros Use DEVICE_ATTR_{RO,WO,RW} macros to simplify sysfs attributes declaration. To declare a "foo" attribute, DEVICE_ATTR_RW() requires foo_show() and foo_store(), so rename a few functions to satisfy this requirement. Also put the macro below each related show/store functions for clarity. Signed-off-by: Vivien Didelot Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 00f5e82..46b2746 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -856,8 +856,8 @@ static void asus_backlight_exit(struct asus_laptop *asus) * than count bytes. We set eof to 1 if we handle those 2 values. We return the * number of bytes written in page */ -static ssize_t show_infos(struct device *dev, - struct device_attribute *attr, char *page) +static ssize_t infos_show(struct device *dev, struct device_attribute *attr, + char *page) { struct asus_laptop *asus = dev_get_drvdata(dev); int len = 0; @@ -926,6 +926,7 @@ static ssize_t show_infos(struct device *dev, return len; } +static DEVICE_ATTR_RO(infos); static int parse_arg(const char *buf, unsigned long count, int *val) { @@ -957,15 +958,15 @@ static ssize_t sysfs_acpi_set(struct asus_laptop *asus, /* * LEDD display */ -static ssize_t show_ledd(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ledd_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "0x%08x\n", asus->ledd_status); } -static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, +static ssize_t ledd_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); @@ -981,6 +982,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, } return rv; } +static DEVICE_ATTR_RW(ledd); /* * Wireless @@ -1014,21 +1016,22 @@ static int asus_wlan_set(struct asus_laptop *asus, int status) return 0; } -static ssize_t show_wlan(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t wlan_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus_wireless_status(asus, WL_RSTS)); } -static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, +static ssize_t wlan_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); return sysfs_acpi_set(asus, buf, count, METHOD_WLAN); } +static DEVICE_ATTR_RW(wlan); /*e * Bluetooth @@ -1042,15 +1045,15 @@ static int asus_bluetooth_set(struct asus_laptop *asus, int status) return 0; } -static ssize_t show_bluetooth(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t bluetooth_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus_wireless_status(asus, BT_RSTS)); } -static ssize_t store_bluetooth(struct device *dev, +static ssize_t bluetooth_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -1058,6 +1061,7 @@ static ssize_t store_bluetooth(struct device *dev, return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH); } +static DEVICE_ATTR_RW(bluetooth); /* * Wimax @@ -1071,22 +1075,22 @@ static int asus_wimax_set(struct asus_laptop *asus, int status) return 0; } -static ssize_t show_wimax(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t wimax_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS)); } -static ssize_t store_wimax(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t wimax_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX); } +static DEVICE_ATTR_RW(wimax); /* * Wwan @@ -1100,22 +1104,22 @@ static int asus_wwan_set(struct asus_laptop *asus, int status) return 0; } -static ssize_t show_wwan(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t wwan_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS)); } -static ssize_t store_wwan(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t wwan_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); return sysfs_acpi_set(asus, buf, count, METHOD_WWAN); } +static DEVICE_ATTR_RW(wwan); /* * Display @@ -1135,8 +1139,8 @@ static void asus_set_display(struct asus_laptop *asus, int value) * displays hooked up simultaneously, so be warned. See the acpi4asus README * for more info. */ -static ssize_t store_disp(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t display_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); int rv, value; @@ -1146,6 +1150,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, asus_set_display(asus, value); return rv; } +static DEVICE_ATTR_WO(display); /* * Light Sens @@ -1167,16 +1172,17 @@ static void asus_als_switch(struct asus_laptop *asus, int value) asus->light_switch = value; } -static ssize_t show_lssw(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ls_switch_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus->light_switch); } -static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t ls_switch_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); int rv, value; @@ -1187,6 +1193,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, return rv; } +static DEVICE_ATTR_RW(ls_switch); static void asus_als_level(struct asus_laptop *asus, int value) { @@ -1195,16 +1202,16 @@ static void asus_als_level(struct asus_laptop *asus, int value) asus->light_level = value; } -static ssize_t show_lslvl(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ls_level_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus->light_level); } -static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t ls_level_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); int rv, value; @@ -1218,6 +1225,7 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, return rv; } +static DEVICE_ATTR_RW(ls_level); static int pega_int_read(struct asus_laptop *asus, int arg, int *result) { @@ -1234,8 +1242,8 @@ static int pega_int_read(struct asus_laptop *asus, int arg, int *result) return err; } -static ssize_t show_lsvalue(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ls_value_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); int err, hi, lo; @@ -1247,6 +1255,7 @@ static ssize_t show_lsvalue(struct device *dev, return sprintf(buf, "%d\n", 10 * hi + lo); return err; } +static DEVICE_ATTR_RO(ls_value); /* * GPS @@ -1274,15 +1283,15 @@ static int asus_gps_switch(struct asus_laptop *asus, int status) return 0; } -static ssize_t show_gps(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t gps_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct asus_laptop *asus = dev_get_drvdata(dev); return sprintf(buf, "%d\n", asus_gps_status(asus)); } -static ssize_t store_gps(struct device *dev, struct device_attribute *attr, +static ssize_t gps_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asus_laptop *asus = dev_get_drvdata(dev); @@ -1298,6 +1307,7 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, rfkill_set_sw_state(asus->gps.rfkill, !value); return rv; } +static DEVICE_ATTR_RW(gps); /* * rfkill @@ -1569,19 +1579,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) asus_input_notify(asus, event); } -static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); -static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); -static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, - show_bluetooth, store_bluetooth); -static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); -static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); -static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp); -static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); -static DEVICE_ATTR(ls_value, S_IRUGO, show_lsvalue, NULL); -static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); -static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); -static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps); - static struct attribute *asus_attributes[] = { &dev_attr_infos.attr, &dev_attr_wlan.attr, -- cgit v0.10.2 From fa465739d4dad4c04715f1e8f1416d86b5b71b64 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Sun, 18 Jan 2015 19:17:12 -0700 Subject: toshiba_acpi: Add a check for TOS_NOT_SUPPORTED in the sci_open function This was "toshiba_acpi: Change sci_open function return value" Some Toshiba laptops have "poorly implemented" SCI calls on their BIOSes and are not checking for sci_{open, close} calls, therefore, the sci_open function is failing and making some of the supported features unavailable (kbd backlight, touchpad, illumination, etc.). This patch checks whether we receive TOS_NOT_SUPPORTED and returns 1, making the supported features work on such laptops. 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. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 446ddc1..48c79b2 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -404,6 +404,19 @@ static int sci_open(struct toshiba_acpi_dev *dev) } 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"); } -- cgit v0.10.2 From b0dcaf4fbb36895175657be029ed64eda2a34707 Mon Sep 17 00:00:00 2001 From: Julijonas Kikutis Date: Thu, 29 Jan 2015 13:04:37 +0000 Subject: samsung-laptop: enable better lid handling Some Samsung laptops with SABI3 delay the sleep for 10 seconds after the lid is closed and do not wake up from sleep after the lid is opened. A SABI command is needed to enable the better behavior. Command = 0x6e, d0 = 0x81 enables this behavior. Returns d0 = 0x01. Command = 0x6e, d0 = 0x80 disables this behavior. Returns d0 = 0x00. Command = 0x6d and any d0 queries the state. This returns: d0 = 0x00000*01, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is enabled. d0 = 0x00000*00, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is disabled. Where * is 0 - laptop has never slept or hibernated after switch on, 1 - laptop has hibernated just before, 2 - laptop has slept just before. Patch addresses bug https://bugzilla.kernel.org/show_bug.cgi?id=75901 . It adds a sysfs attribute lid_handling with a description and also an addition to the quirks structure to enable the mode by default. A user with another laptop in the bug report says that "power button has to be pressed twice to wake the machine" when he or she enabled the mode manually using the SABI command. Therefore, it is enabled by default only for the single laptop that I have tested. Signed-off-by: Julijonas Kikutis Signed-off-by: Darren Hart diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop index 678819a..63c1ad0 100644 --- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop +++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop @@ -35,3 +35,11 @@ Contact: Corentin Chary Description: Use your USB ports to charge devices, even when your laptop is powered off. 1 means enabled, 0 means disabled. + +What: /sys/devices/platform/samsung/lid_handling +Date: December 11, 2014 +KernelVersion: 3.19 +Contact: Julijonas Kikutis +Description: Some Samsung laptops handle lid closing quicker and + only handle lid opening with this mode enabled. + 1 means enabled, 0 means disabled. diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index ce364a4..1743336 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -124,6 +124,10 @@ struct sabi_commands { u16 get_wireless_status; u16 set_wireless_status; + /* 0x80 is off, 0x81 is on */ + u16 get_lid_handling; + u16 set_lid_handling; + /* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */ u16 kbd_backlight; @@ -194,6 +198,9 @@ static const struct sabi_config sabi_configs[] = { .get_wireless_status = 0xFFFF, .set_wireless_status = 0xFFFF, + .get_lid_handling = 0xFFFF, + .set_lid_handling = 0xFFFF, + .kbd_backlight = 0xFFFF, .set_linux = 0x0a, @@ -254,6 +261,9 @@ static const struct sabi_config sabi_configs[] = { .get_wireless_status = 0x69, .set_wireless_status = 0x6a, + .get_lid_handling = 0x6d, + .set_lid_handling = 0x6e, + .kbd_backlight = 0x78, .set_linux = 0xff, @@ -354,6 +364,7 @@ struct samsung_quirks { bool four_kbd_backlight_levels; bool enable_kbd_backlight; bool use_native_backlight; + bool lid_handling; }; static struct samsung_quirks samsung_unknown = {}; @@ -371,6 +382,10 @@ static struct samsung_quirks samsung_np740u3e = { .enable_kbd_backlight = true, }; +static struct samsung_quirks samsung_lid_handling = { + .lid_handling = true, +}; + static bool force; module_param(force, bool, 0); MODULE_PARM_DESC(force, @@ -835,10 +850,76 @@ static ssize_t set_usb_charge(struct device *dev, static DEVICE_ATTR(usb_charge, S_IWUSR | S_IRUGO, get_usb_charge, set_usb_charge); +static int read_lid_handling(struct samsung_laptop *samsung) +{ + const struct sabi_commands *commands = &samsung->config->commands; + struct sabi_data data; + int retval; + + if (commands->get_lid_handling == 0xFFFF) + return -ENODEV; + + memset(&data, 0, sizeof(data)); + retval = sabi_command(samsung, commands->get_lid_handling, + &data, &data); + + if (retval) + return retval; + + return data.data[0] & 0x1; +} + +static int write_lid_handling(struct samsung_laptop *samsung, + int enabled) +{ + const struct sabi_commands *commands = &samsung->config->commands; + struct sabi_data data; + + memset(&data, 0, sizeof(data)); + data.data[0] = 0x80 | enabled; + return sabi_command(samsung, commands->set_lid_handling, + &data, NULL); +} + +static ssize_t get_lid_handling(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct samsung_laptop *samsung = dev_get_drvdata(dev); + int ret; + + ret = read_lid_handling(samsung); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t set_lid_handling(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct samsung_laptop *samsung = dev_get_drvdata(dev); + int ret, value; + + if (!count || kstrtoint(buf, 0, &value) != 0) + return -EINVAL; + + ret = write_lid_handling(samsung, !!value); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(lid_handling, S_IWUSR | S_IRUGO, + get_lid_handling, set_lid_handling); + static struct attribute *platform_attributes[] = { &dev_attr_performance_level.attr, &dev_attr_battery_life_extender.attr, &dev_attr_usb_charge.attr, + &dev_attr_lid_handling.attr, NULL }; @@ -961,6 +1042,22 @@ static int __init samsung_rfkill_init(struct samsung_laptop *samsung) return 0; } +static void samsung_lid_handling_exit(struct samsung_laptop *samsung) +{ + if (samsung->quirks->lid_handling) + write_lid_handling(samsung, 0); +} + +static int __init samsung_lid_handling_init(struct samsung_laptop *samsung) +{ + int retval = 0; + + if (samsung->quirks->lid_handling) + retval = write_lid_handling(samsung, 1); + + return retval; +} + static int kbd_backlight_enable(struct samsung_laptop *samsung) { const struct sabi_commands *commands = &samsung->config->commands; @@ -1116,7 +1213,7 @@ static int __init samsung_backlight_init(struct samsung_laptop *samsung) } static umode_t samsung_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) + struct attribute *attr, int idx) { struct device *dev = container_of(kobj, struct device, kobj); struct platform_device *pdev = to_platform_device(dev); @@ -1129,6 +1226,8 @@ static umode_t samsung_sysfs_is_visible(struct kobject *kobj, ok = !!(read_battery_life_extender(samsung) >= 0); if (attr == &dev_attr_usb_charge.attr) ok = !!(read_usb_charge(samsung) >= 0); + if (attr == &dev_attr_lid_handling.attr) + ok = !!(read_lid_handling(samsung) >= 0); return ok ? attr->mode : 0; } @@ -1441,6 +1540,9 @@ static int samsung_pm_notification(struct notifier_block *nb, samsung->quirks->enable_kbd_backlight) kbd_backlight_enable(samsung); + if (val == PM_POST_HIBERNATION && samsung->quirks->lid_handling) + write_lid_handling(samsung, 1); + return 0; } @@ -1583,6 +1685,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .driver_data = &samsung_np740u3e, }, + { + .callback = samsung_dmi_matched, + .ident = "300V3Z/300V4Z/300V5Z", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "300V3Z/300V4Z/300V5Z"), + }, + .driver_data = &samsung_lid_handling, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); @@ -1662,6 +1773,10 @@ static int __init samsung_init(void) if (ret) goto error_leds; + ret = samsung_lid_handling_init(samsung); + if (ret) + goto error_lid_handling; + ret = samsung_debugfs_init(samsung); if (ret) goto error_debugfs; @@ -1673,6 +1788,8 @@ static int __init samsung_init(void) return ret; error_debugfs: + samsung_lid_handling_exit(samsung); +error_lid_handling: samsung_leds_exit(samsung); error_leds: samsung_rfkill_exit(samsung); @@ -1697,6 +1814,7 @@ static void __exit samsung_exit(void) unregister_pm_notifier(&samsung->pm_nb); samsung_debugfs_exit(samsung); + samsung_lid_handling_exit(samsung); samsung_leds_exit(samsung); samsung_rfkill_exit(samsung); samsung_backlight_exit(samsung); -- cgit v0.10.2 From 4e7f09ad5ea98ae60a435575ae877bd68a5f2d5c Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Thu, 5 Feb 2015 14:40:05 +0000 Subject: samsung-laptop: Fix sparse integer as NULL warning Fix the following sparse warning: samsung-laptop.c:1365:52: warning: Using plain integer as NULL pointer Signed-off-by: Lad, Prabhakar Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index 1743336..3257b02 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -1461,7 +1461,7 @@ static int __init samsung_sabi_init(struct samsung_laptop *samsung) samsung_sabi_diag(samsung); /* Try to find one of the signatures in memory to find the header */ - for (i = 0; sabi_configs[i].test_string != 0; ++i) { + for (i = 0; sabi_configs[i].test_string != NULL; ++i) { samsung->config = &sabi_configs[i]; loca = find_signature(samsung->f0000_segment, samsung->config->test_string); -- cgit v0.10.2 From 802cf2e1e0f202507b6e21b7a12da56d5c86af62 Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Fri, 6 Feb 2015 18:49:23 -0800 Subject: samsung-laptop.c: Prefer kstrtoint over single variable sscanf Replace existing usage of single variable sscanf with kstrtoint for consistency with checkpatch warnings against such usage. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index 3257b02..9e701b2 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -768,7 +768,7 @@ static ssize_t set_battery_life_extender(struct device *dev, struct samsung_laptop *samsung = dev_get_drvdata(dev); int ret, value; - if (!count || sscanf(buf, "%i", &value) != 1) + if (!count || kstrtoint(buf, 0, &value) != 0) return -EINVAL; ret = write_battery_life_extender(samsung, !!value); @@ -837,7 +837,7 @@ static ssize_t set_usb_charge(struct device *dev, struct samsung_laptop *samsung = dev_get_drvdata(dev); int ret, value; - if (!count || sscanf(buf, "%i", &value) != 1) + if (!count || kstrtoint(buf, 0, &value) != 0) return -EINVAL; ret = write_usb_charge(samsung, !!value); -- cgit v0.10.2 From b201a47f3ca6e86d5b3d6d4c4f156a77e6d0cac7 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Thu, 5 Feb 2015 14:45:38 +0000 Subject: thinkpad_acpi.c: Fix sparse warning (make undeclared var static) Fix the following sparse warning: thinkpad_acpi.c:3459:11: warning: symbol 'adaptive_keyboard_modes' was not declared. Should it be static? Signed-off-by: Lad, Prabhakar Acked-by: Henrique de Moraes Holschuh Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c3d11fa..0e9262b 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -3456,7 +3456,7 @@ enum ADAPTIVE_KEY_MODE { LAYFLAT_MODE }; -const int adaptive_keyboard_modes[] = { +static const int adaptive_keyboard_modes[] = { HOME_MODE, /* WEB_BROWSER_MODE = 2, WEB_CONFERENCE_MODE = 3, */ -- cgit v0.10.2 From 76fe63f58b44c7112fbdab4d490fb6848f12122b Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Thu, 5 Feb 2015 14:49:41 +0000 Subject: Sony-laptop: Fix sparse warning (make undeclared var static) Fix the following sparse warning: sony-laptop.c:1035:29: warning: symbol 'sony_bl_props' was not declared. Should it be static? Signed-off-by: Lad, Prabhakar Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 6dd1c0e..e51c1e7 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1032,7 +1032,7 @@ struct sony_backlight_props { u8 offset; u8 maxlvl; }; -struct sony_backlight_props sony_bl_props; +static struct sony_backlight_props sony_bl_props; static int sony_backlight_update_status(struct backlight_device *bd) { -- cgit v0.10.2 From 2a89d7c2e9ed61f5e032e41f9bf1d9e4fe9fd2ea Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Thu, 5 Feb 2015 14:57:44 +0000 Subject: classmate-laptop: Fix sparse warning (0 as NULL) Fix the following sparse warning: classmate-laptop.c:523:61: warning: Using plain integer as NULL pointer Signed-off-by: Lad, Prabhakar Acked-by: Thadeu Lima de Souza Cascardo Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 70d355a..55cf10b 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -520,7 +520,7 @@ static acpi_status cmpc_get_accel(acpi_handle handle, { union acpi_object param[2]; struct acpi_object_list input; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 }; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; unsigned char *locs; acpi_status status; -- cgit v0.10.2 From 98fc4ec64a211a9d301172dec2aed08f47964295 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Mon, 9 Feb 2015 20:55:02 -0700 Subject: toshiba_acpi: Make toshiba_eco_mode_available more robust Some Toshiba laptops do not come with the ECO led installed, however, the driver is registering support for it when it should not. This patch makes the toshiba_eco_mode_available function more robust in detecting ECO led capabilities, not registering the led on laptops that do not support it and registering the led when it really does. The ECO led function now returns 0x8e00 (Not Installed) by querying with in[3] = 0, whenever theres no physical LED installed, and returning 0x8300 (Input Data Error) when it is, however, there are some BIOSes that have stub function calls not returning anything and and the LED device was being registered too, hence the change of the default return value from 1 to 0. Signed-off-by: Azael Avalos Minor comment update, fixed a whitespace error, s/truly/actual/. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 48c79b2..a480fd0 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -108,6 +108,7 @@ MODULE_LICENSE("GPL"); #define TOS_FIFO_EMPTY 0x8c00 #define TOS_DATA_NOT_AVAILABLE 0x8d20 #define TOS_NOT_INITIALIZED 0x8d50 +#define TOS_NOT_INSTALLED 0x8e00 /* registers */ #define HCI_FAN 0x0004 @@ -695,16 +696,32 @@ static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state) static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) { acpi_status status; - u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 }; + u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 }; u32 out[TCI_WORDS]; status = tci_raw(dev, in, out); - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { - pr_info("ACPI call to get ECO led failed\n"); - return 0; + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { + pr_err("ACPI call to get ECO led failed\n"); + } else if (out[0] == TOS_NOT_INSTALLED) { + pr_info("ECO led not installed"); + } else if (out[0] == TOS_INPUT_DATA_ERROR) { + /* If we receive 0x8300 (Input Data Error), it means that the + * 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); + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) + pr_err("ACPI call to get ECO led failed\n"); + else if (out[0] == TOS_SUCCESS) + return 1; } - return 1; + return 0; } static enum led_brightness toshiba_eco_mode_get_status(struct led_classdev *cdev) -- cgit v0.10.2 From 67ab62481cf8d82a6bcbc4a8e6e3fd25e39bcba0 Mon Sep 17 00:00:00 2001 From: Xavier Naveira Date: Tue, 10 Feb 2015 08:45:18 +0100 Subject: thinkpad_acpi: unhandled hkey event Pressing Fn+Esc in a Lenovo Thinkpad x240 to lock the Fn keys generates an unhandled hkey event Signed-off-by: Xavier Naveira Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 0e9262b..bccd449 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -196,6 +196,7 @@ enum tpacpi_hkey_event_t { /* Key-related user-interface events */ TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ + TP_HKEY_EV_KEY_FN_ESC = 0x6060, /* Fn+Esc key pressed X240 */ /* Thermal events */ TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ @@ -3712,6 +3713,7 @@ static bool hotkey_notify_6xxx(const u32 hkey, case TP_HKEY_EV_KEY_NUMLOCK: case TP_HKEY_EV_KEY_FN: + case TP_HKEY_EV_KEY_FN_ESC: /* key press events, we just ignore them as long as the EC * is still reporting them in the normal keyboard stream */ *send_acpi_ev = false; -- cgit v0.10.2 From 1b0eb5bc241354aa854671fdf02132d2d1452bdf Mon Sep 17 00:00:00 2001 From: Adam Lee Date: Wed, 11 Feb 2015 13:43:10 +0800 Subject: thinkpad_acpi: support new BIOS version string pattern Latest ThinkPad models use a new string pattern of BIOS version, thinkpad_acpi won't be loaded automatically without this fix. Signed-off-by: Adam Lee Intentatation cleanup. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index bccd449..3b8ceee 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8885,17 +8885,31 @@ static bool __pure __init tpacpi_is_fw_digit(const char c) return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); } -/* Most models: xxyTkkWW (#.##c); Ancient 570/600 and -SL lacks (#.##c) */ static bool __pure __init tpacpi_is_valid_fw_id(const char * const s, const char t) { - return s && strlen(s) >= 8 && + /* + * Most models: xxyTkkWW (#.##c) + * Ancient 570/600 and -SL lacks (#.##c) + */ + if (s && strlen(s) >= 8 && tpacpi_is_fw_digit(s[0]) && tpacpi_is_fw_digit(s[1]) && s[2] == t && (s[3] == 'T' || s[3] == 'N') && tpacpi_is_fw_digit(s[4]) && - tpacpi_is_fw_digit(s[5]); + tpacpi_is_fw_digit(s[5])) + return true; + + /* New models: xxxyTkkW (#.##c); T550 and some others */ + return s && strlen(s) >= 8 && + tpacpi_is_fw_digit(s[0]) && + tpacpi_is_fw_digit(s[1]) && + tpacpi_is_fw_digit(s[2]) && + s[3] == t && + (s[4] == 'T' || s[4] == 'N') && + tpacpi_is_fw_digit(s[5]) && + tpacpi_is_fw_digit(s[6]); } /* returns 0 - probe ok, or < 0 - probe error. -- cgit v0.10.2 From c6c68ff812ca730a3d6bac95a49d731b832a1460 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:16 -0700 Subject: toshiba_acpi: Add version entry to sysfs This patch adds a new entry to the sysfs, showing the version of the driver. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index a480fd0..fe5987e 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1531,6 +1531,8 @@ static const struct backlight_ops toshiba_backlight_data = { /* * Sysfs files */ +static ssize_t toshiba_version_show(struct device *dev, + struct device_attribute *attr, char *buf); static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); @@ -1583,6 +1585,7 @@ static ssize_t toshiba_usb_sleep_music_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); @@ -1607,6 +1610,7 @@ static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, toshiba_usb_sleep_music_store); static struct attribute *toshiba_attributes[] = { + &dev_attr_version.attr, &dev_attr_kbd_backlight_mode.attr, &dev_attr_kbd_type.attr, &dev_attr_available_kbd_modes.attr, @@ -1628,6 +1632,12 @@ static struct attribute_group toshiba_attr_group = { .attrs = toshiba_attributes, }; +static ssize_t toshiba_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); +} + static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -- cgit v0.10.2 From 94477d4cfe6a579d88811221ee7198fa30f33a99 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:17 -0700 Subject: toshiba_acpi: Add fan entry to sysfs This patch adds a fan entry to sysfs, enabling the user to get and set the fan status. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index fe5987e..47d47b5 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1533,6 +1533,11 @@ static const struct backlight_ops toshiba_backlight_data = { */ static ssize_t toshiba_version_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t toshiba_fan_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static ssize_t toshiba_fan_show(struct device *dev, + struct device_attribute *attr, char *buf); static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); @@ -1586,6 +1591,8 @@ static ssize_t toshiba_usb_sleep_music_store(struct device *dev, const char *buf, size_t count); static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); +static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, + toshiba_fan_show, toshiba_fan_store); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); @@ -1611,6 +1618,7 @@ static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, 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, @@ -1638,6 +1646,45 @@ static ssize_t toshiba_version_show(struct device *dev, return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); } +static ssize_t toshiba_fan_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); + u32 result; + int state; + int ret; + + ret = kstrtoint(buf, 0, &state); + if (ret) + return ret; + + if (state != 0 && state != 1) + return -EINVAL; + + result = hci_write1(toshiba, HCI_FAN, state); + if (result == TOS_FAILURE) + return -EIO; + else if (result == TOS_NOT_SUPPORTED) + return -ENODEV; + + return count; +} + +static ssize_t toshiba_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 ssize_t toshiba_kbd_bl_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -2034,7 +2081,9 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct toshiba_acpi_dev *drv = dev_get_drvdata(dev); bool exists = true; - if (attr == &dev_attr_kbd_backlight_mode.attr) + 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; -- cgit v0.10.2 From bae84195b4cd44767fd127bcd4e61830e426bc7f Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:18 -0700 Subject: toshiba_acpi: Add support for Keyboard functions mode Recent Toshiba laptops that come with the new keyboard layout have the Special Functions (hotkeys) enabled by default, which, in order to access the F{1-12} keys, you need to press the FN-F{1-12} key to access such key. This patch adds support to toggle the Keyboard Functions operation mode by creating the sysfs entry "kbd_functions_keys", accepting only two parameters, 0 to set the "Normal Operation" mode and 1 to set the "Special Functions" mode, however, everytime the mode is toggled, a restart is needed. In the "Normal Operation" mode, the F{1-12} keys are as usual and the hotkeys are accessed via FN-F{1-12}. In the "Special Functions" mode, the F{1-12} keys trigger the hotkey and the F{1-12} keys are accessed via FN-F{1-12}. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 47d47b5..ccf6282 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -127,6 +127,7 @@ MODULE_LICENSE("GPL"); #define SCI_KBD_ILLUM_STATUS 0x015c #define SCI_USB_SLEEP_MUSIC 0x015e #define SCI_TOUCHPAD 0x050e +#define SCI_KBD_FUNCTION_KEYS 0x0522 /* field definitions */ #define HCI_ACCEL_MASK 0x7fff @@ -193,6 +194,7 @@ struct toshiba_acpi_dev { 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 sysfs_created:1; struct mutex mutex; @@ -1005,6 +1007,47 @@ static int toshiba_usb_sleep_music_set(struct toshiba_acpi_dev *dev, u32 state) return 0; } +/* 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 || result == TOS_INPUT_DATA_ERROR) { + pr_err("ACPI call to get KBD function keys failed\n"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("KBD function keys not supported\n"); + return -ENODEV; + } + + return 0; +} + +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 || result == TOS_INPUT_DATA_ERROR) { + pr_err("ACPI call to set KBD function keys failed\n"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("KBD function keys not supported\n"); + return -ENODEV; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1589,6 +1632,12 @@ static ssize_t toshiba_usb_sleep_music_show(struct device *dev, static ssize_t toshiba_usb_sleep_music_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t toshiba_kbd_function_keys_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_kbd_function_keys_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, @@ -1615,6 +1664,9 @@ static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, toshiba_usb_sleep_music_show, toshiba_usb_sleep_music_store); +static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, + toshiba_kbd_function_keys_show, + toshiba_kbd_function_keys_store); static struct attribute *toshiba_attributes[] = { &dev_attr_version.attr, @@ -1629,6 +1681,7 @@ static struct attribute *toshiba_attributes[] = { &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, NULL, }; @@ -2074,6 +2127,48 @@ static ssize_t toshiba_usb_sleep_music_store(struct device *dev, return count; } +static ssize_t toshiba_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 toshiba_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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -2099,6 +2194,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 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; return exists ? attr->mode : 0; } @@ -2517,6 +2614,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) ret = toshiba_usb_sleep_music_get(dev, &dummy); dev->usb_sleep_music_supported = !ret; + ret = toshiba_function_keys_get(dev, &dummy); + dev->kbd_function_keys_supported = !ret; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 35d53ceaf7160fa1950142757420ba96921034bf Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:19 -0700 Subject: toshiba_acpi: Add support for Panel Power ON Toshiba laptops come with a feature called "Panel Open - Power ON", which makes the laptop turn on whenever the LID is opened. This patch adds support for such feature, by creating a sysfs entry named "panel_power_on", accepting only two values, 0 to disable and 1 to enable such feature, however, a reboot is needed on every mode change. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index ccf6282..70370d3 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -122,6 +122,7 @@ MODULE_LICENSE("GPL"); #define HCI_KBD_ILLUMINATION 0x0095 #define HCI_ECO_MODE 0x0097 #define HCI_ACCELEROMETER2 0x00a6 +#define SCI_PANEL_POWER_ON 0x010d #define SCI_ILLUMINATION 0x014e #define SCI_USB_SLEEP_CHARGE 0x0150 #define SCI_KBD_ILLUM_STATUS 0x015c @@ -195,6 +196,7 @@ struct toshiba_acpi_dev { 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 sysfs_created:1; struct mutex mutex; @@ -1048,6 +1050,51 @@ static int toshiba_function_keys_set(struct toshiba_acpi_dev *dev, u32 mode) return 0; } +/* 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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("Panel Power on not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + +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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("Panel Power ON not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1638,6 +1685,12 @@ static ssize_t toshiba_kbd_function_keys_show(struct device *dev, static ssize_t toshiba_kbd_function_keys_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t toshiba_panel_power_on_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_panel_power_on_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, @@ -1667,6 +1720,9 @@ static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, toshiba_kbd_function_keys_show, toshiba_kbd_function_keys_store); +static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, + toshiba_panel_power_on_show, + toshiba_panel_power_on_store); static struct attribute *toshiba_attributes[] = { &dev_attr_version.attr, @@ -1682,6 +1738,7 @@ static struct attribute *toshiba_attributes[] = { &dev_attr_usb_rapid_charge.attr, &dev_attr_usb_sleep_music.attr, &dev_attr_kbd_function_keys.attr, + &dev_attr_panel_power_on.attr, NULL, }; @@ -2169,6 +2226,44 @@ static ssize_t toshiba_kbd_function_keys_store(struct device *dev, return count; } +static ssize_t toshiba_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 toshiba_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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -2196,6 +2291,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 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; return exists ? attr->mode : 0; } @@ -2617,6 +2714,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) ret = toshiba_function_keys_get(dev, &dummy); dev->kbd_function_keys_supported = !ret; + ret = toshiba_panel_power_on_get(dev, &dummy); + dev->panel_power_on_supported = !ret; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 17fe4b3d31e6b1d3afd40a34849fa353d0ca5616 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:20 -0700 Subject: toshiba_acpi: Add support to enable/disable USB 3 Toshiba laptops that come with USB 3 ports have a feature that lets them disable USB 3 functionality and act as a regular USB 2 port, and thus, saving power. This patch adds support to that feature, by creating a sysfs entry named "usb_three", acceptig only two parameters, 0 to disable the USB 3 (acting as a USB 2) and 1 to enable it, however, a reboot is needed everytime this is toggled. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 70370d3..b162a54 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -127,6 +127,7 @@ MODULE_LICENSE("GPL"); #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 @@ -197,6 +198,7 @@ struct toshiba_acpi_dev { 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 sysfs_created:1; struct mutex mutex; @@ -1095,6 +1097,51 @@ static int toshiba_panel_power_on_set(struct toshiba_acpi_dev *dev, u32 state) return 0; } +/* 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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB 3 not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + +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"); + return -EIO; + } else if (result == TOS_NOT_SUPPORTED) { + pr_info("USB 3 not supported\n"); + return -ENODEV; + } else if (result == TOS_INPUT_DATA_ERROR) { + return -EIO; + } + + return 0; +} + /* Bluetooth rfkill handlers */ static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) @@ -1691,6 +1738,12 @@ static ssize_t toshiba_panel_power_on_show(struct device *dev, static ssize_t toshiba_panel_power_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t toshiba_usb_three_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t toshiba_usb_three_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, @@ -1723,6 +1776,8 @@ static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, toshiba_panel_power_on_show, toshiba_panel_power_on_store); +static DEVICE_ATTR(usb_three, S_IRUGO | S_IWUSR, + toshiba_usb_three_show, toshiba_usb_three_store); static struct attribute *toshiba_attributes[] = { &dev_attr_version.attr, @@ -1739,6 +1794,7 @@ static struct attribute *toshiba_attributes[] = { &dev_attr_usb_sleep_music.attr, &dev_attr_kbd_function_keys.attr, &dev_attr_panel_power_on.attr, + &dev_attr_usb_three.attr, NULL, }; @@ -2264,6 +2320,48 @@ static ssize_t toshiba_panel_power_on_store(struct device *dev, return count; } +static ssize_t toshiba_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 toshiba_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 umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -2293,6 +2391,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 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; return exists ? attr->mode : 0; } @@ -2717,6 +2817,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) 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; + /* Determine whether or not BIOS supports fan and video interfaces */ ret = get_video_status(dev, &dummy); -- cgit v0.10.2 From 7216d7021d42e51377a0065c427eed3f01c81fe9 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 21:09:21 -0700 Subject: toshiba_acpi: Bump version number to 0.21 Several new features were added on previous patches, so lets bump up the driver version. And also, update the copyright year. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index b162a54..d6e97aa 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -5,7 +5,7 @@ * Copyright (C) 2002-2004 John Belmonte * Copyright (C) 2008 Philip Langdale * Copyright (C) 2010 Pierre Ducroquet - * Copyright (C) 2014 Azael Avalos + * Copyright (C) 2014-2015 Azael Avalos * * 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 @@ -38,7 +38,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define TOSHIBA_ACPI_VERSION "0.20" +#define TOSHIBA_ACPI_VERSION "0.21" #define PROC_INTERFACE_VERSION 1 #include -- cgit v0.10.2 From b51639927283169c25b873e318e3a18ebd1086df Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 23:43:56 -0700 Subject: toshiba_acpi: Clean file according to coding style This patch simply cleans the the driver out of 2 errors and 17 warnings according to "checkpatch -f", no functionality was changed, simply a cleanup. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index d6e97aa..734c98f9 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include MODULE_AUTHOR("John Belmonte"); MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); @@ -289,7 +289,7 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { /* utility */ -static __inline__ void _set_bit(u32 * word, u32 mask, int value) +static inline void _set_bit(u32 *word, u32 mask, int value) { *word = (*word & ~mask) | (mask * value); } @@ -332,9 +332,8 @@ static acpi_status tci_raw(struct toshiba_acpi_dev *dev, (char *)dev->method_hci, ¶ms, &results); if ((status == AE_OK) && (out_objs->package.count <= TCI_WORDS)) { - for (i = 0; i < out_objs->package.count; ++i) { + for (i = 0; i < out_objs->package.count; ++i) out[i] = out_objs->package.elements[i].integer.value; - } } return status; @@ -360,6 +359,7 @@ static u32 hci_read1(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; @@ -377,11 +377,13 @@ static u32 hci_write2(struct toshiba_acpi_dev *dev, u32 reg, u32 in1, u32 in2) return ACPI_SUCCESS(status) ? out[0] : TOS_FAILURE; } -static u32 hci_read2(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1, u32 *out2) +static u32 hci_read2(struct toshiba_acpi_dev *dev, + u32 reg, u32 *out1, u32 *out2) { u32 in[TCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 }; u32 out[TCI_WORDS]; acpi_status status = tci_raw(dev, in, out); + if (ACPI_FAILURE(status)) return TOS_FAILURE; @@ -456,6 +458,7 @@ 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; @@ -730,7 +733,8 @@ static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) return 0; } -static enum led_brightness toshiba_eco_mode_get_status(struct led_classdev *cdev) +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); @@ -1252,7 +1256,7 @@ static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable) return hci_result == TOS_SUCCESS ? 0 : -EIO; } -static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; +static struct proc_dir_entry *toshiba_proc_dir /*= 0*/; static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) { @@ -1263,6 +1267,7 @@ static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) if (dev->tr_backlight_supported) { bool enabled; int ret = get_tr_backlight_status(dev, &enabled); + if (ret) return ret; if (enabled) @@ -1280,6 +1285,7 @@ static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) static int get_lcd_brightness(struct backlight_device *bd) { struct toshiba_acpi_dev *dev = bl_get_data(bd); + return __get_lcd_brightness(dev); } @@ -1316,6 +1322,7 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) if (dev->tr_backlight_supported) { bool enable = !value; int ret = set_tr_backlight_status(dev, enable); + if (ret) return ret; if (value) @@ -1330,6 +1337,7 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) 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); } @@ -1387,6 +1395,7 @@ static int video_proc_show(struct seq_file *m, void *v) int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; int 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); @@ -1439,8 +1448,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, do { ++buffer; --remain; - } - while (remain && *(buffer - 1) != ';'); + } while (remain && *(buffer - 1) != ';'); } kfree(cmd); @@ -1448,6 +1456,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, 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) @@ -1517,10 +1526,10 @@ static ssize_t fan_proc_write(struct file *file, const char __user *buf, if (sscanf(cmd, " force_on : %i", &value) == 1 && value >= 0 && value <= 1) { hci_result = hci_write1(dev, HCI_FAN, value); - if (hci_result != TOS_SUCCESS) - return -EIO; - else + if (hci_result == TOS_SUCCESS) dev->force_fan = value; + else + return -EIO; } else { return -EINVAL; } @@ -1585,11 +1594,10 @@ static ssize_t keys_proc_write(struct file *file, const char __user *buf, return -EFAULT; cmd[len] = '\0'; - if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { + if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) dev->key_event_valid = 0; - } else { + else return -EINVAL; - } return count; } -- cgit v0.10.2 From 15667b2c1d0dcd554c515ebcf04e7f1733891cc9 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 23:43:57 -0700 Subject: Documentation/ABI: Add file describing the sysfs entries for toshiba_acpi This patch adds a new file describing the sysfs entries for the toshiba_acpi driver. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/Documentation/ABI/testing/sysfs-driver-toshiba_acpi b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi new file mode 100644 index 0000000..ca9c71a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi @@ -0,0 +1,114 @@ +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_backlight_mode +Date: June 8, 2014 +KernelVersion: 3.15 +Contact: Azael Avalos +Description: This file controls the keyboard backlight operation mode, valid + values are: + * 0x1 -> FN-Z + * 0x2 -> AUTO (also called TIMER) + * 0x8 -> ON + * 0x10 -> OFF + Note that the kernel 3.16 onwards this file accepts all listed + parameters, kernel 3.15 only accepts the first two (FN-Z and + AUTO). +Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_backlight_timeout +Date: June 8, 2014 +KernelVersion: 3.15 +Contact: Azael Avalos +Description: This file controls the timeout of the keyboard backlight + whenever the operation mode is set to AUTO (or TIMER), + valid values range from 0-60. + Note that the kernel 3.15 only had support for the first + keyboard type, the kernel 3.16 added support for the second + type and the range accepted for type 2 is 1-60. + See the entry named "kbd_type" +Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/position +Date: June 8, 2014 +KernelVersion: 3.15 +Contact: Azael Avalos +Description: This file shows the absolute position of the built-in + accelereometer. + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/touchpad +Date: June 8, 2014 +KernelVersion: 3.15 +Contact: Azael Avalos +Description: This files controls the status of the touchpad and pointing + stick (if available), valid values are: + * 0 -> OFF + * 1 -> ON +Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/available_kbd_modes +Date: August 3, 2014 +KernelVersion: 3.16 +Contact: Azael Avalos +Description: This file shows the supported keyboard backlight modes + the system supports, which can be: + * 0x1 -> FN-Z + * 0x2 -> AUTO (also called TIMER) + * 0x8 -> ON + * 0x10 -> OFF + Note that not all keyboard types support the listed modes. + See the entry named "available_kbd_modes" +Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_type +Date: August 3, 2014 +KernelVersion: 3.16 +Contact: Azael Avalos +Description: This file shows the current keyboard backlight type, + which can be: + * 1 -> Type 1, supporting modes FN-Z and AUTO + * 2 -> Type 2, supporting modes TIMER, ON and OFF +Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/version +Date: February, 2015 +KernelVersion: 3.20 +Contact: Azael Avalos +Description: This file shows the current version of the driver + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/fan +Date: February, 2015 +KernelVersion: 3.20 +Contact: Azael Avalos +Description: This file controls the state of the internal fan, valid + values are: + * 0 -> OFF + * 1 -> ON + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_function_keys +Date: February, 2015 +KernelVersion: 3.20 +Contact: Azael Avalos +Description: This file controls the Special Functions (hotkeys) operation + mode, valid values are: + * 0 -> Normal Operation + * 1 -> Special Functions + In the "Normal Operation" mode, the F{1-12} keys are as usual + and the hotkeys are accessed via FN-F{1-12}. + In the "Special Functions" mode, the F{1-12} keys trigger the + hotkey and the F{1-12} keys are accessed via FN-F{1-12}. + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/panel_power_on +Date: February, 2015 +KernelVersion: 3.20 +Contact: Azael Avalos +Description: This file controls whether the laptop should turn ON whenever + the LID is opened, valid values are: + * 0 -> Disabled + * 1 -> Enabled + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_three +Date: February, 2015 +KernelVersion: 3.20 +Contact: Azael Avalos +Description: This file controls whether the USB 3 functionality, valid + values are: + * 0 -> Disabled (Acts as a regular USB 2) + * 1 -> Enabled (Full USB 3 functionality) -- cgit v0.10.2 From 9bd1213b12debacd7db26108bd8b7bb0a5d772a9 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 23:43:58 -0700 Subject: toshiba_acpi: Move sysfs function and struct declarations further down Commit 93f8c16d635e ("toshiba_acpi: Support new keyboard backlight type") moved all the sysfs structs and function declarations further up in order to make use of sysfs_update_group, however, commit 805469053ba9 ("toshiba_acpi: Add keyboard backlight mode change event") made use of that function unnecesary. This patch moves all the sysfs structs and function declarations further down, making the file shorther in lines and more readable. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 734c98f9..c4f9d81 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1677,144 +1677,6 @@ static const struct backlight_ops toshiba_backlight_data = { * Sysfs files */ static ssize_t toshiba_version_show(struct device *dev, - struct device_attribute *attr, char *buf); -static ssize_t toshiba_fan_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_fan_show(struct device *dev, - struct device_attribute *attr, char *buf); -static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_kbd_type_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_available_kbd_modes_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_touchpad_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_touchpad_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_position_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_usb_sleep_charge_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_usb_sleep_charge_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t sleep_functions_on_battery_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t sleep_functions_on_battery_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_usb_rapid_charge_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_usb_sleep_music_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_usb_sleep_music_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_kbd_function_keys_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_kbd_function_keys_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_panel_power_on_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_panel_power_on_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); -static ssize_t toshiba_usb_three_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t toshiba_usb_three_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count); - -static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); -static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, - toshiba_fan_show, toshiba_fan_store); -static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, - toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); -static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); -static DEVICE_ATTR(available_kbd_modes, S_IRUGO, - toshiba_available_kbd_modes_show, NULL); -static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, - toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store); -static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, - toshiba_touchpad_show, toshiba_touchpad_store); -static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); -static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, - toshiba_usb_sleep_charge_show, - toshiba_usb_sleep_charge_store); -static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, - sleep_functions_on_battery_show, - sleep_functions_on_battery_store); -static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, - toshiba_usb_rapid_charge_show, - toshiba_usb_rapid_charge_store); -static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, - toshiba_usb_sleep_music_show, - toshiba_usb_sleep_music_store); -static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, - toshiba_kbd_function_keys_show, - toshiba_kbd_function_keys_store); -static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, - toshiba_panel_power_on_show, - toshiba_panel_power_on_store); -static DEVICE_ATTR(usb_three, S_IRUGO | S_IWUSR, - toshiba_usb_three_show, toshiba_usb_three_store); - -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, -}; - -static umode_t toshiba_sysfs_is_visible(struct kobject *, - struct attribute *, int); - -static struct attribute_group toshiba_attr_group = { - .is_visible = toshiba_sysfs_is_visible, - .attrs = toshiba_attributes, -}; - -static ssize_t toshiba_version_show(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); @@ -2370,6 +2232,59 @@ static ssize_t toshiba_usb_three_store(struct device *dev, return count; } +static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); +static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, + toshiba_fan_show, toshiba_fan_store); +static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, + toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); +static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); +static DEVICE_ATTR(available_kbd_modes, S_IRUGO, + toshiba_available_kbd_modes_show, NULL); +static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, + toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store); +static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, + toshiba_touchpad_show, toshiba_touchpad_store); +static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); +static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, + toshiba_usb_sleep_charge_show, + toshiba_usb_sleep_charge_store); +static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, + sleep_functions_on_battery_show, + sleep_functions_on_battery_store); +static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, + toshiba_usb_rapid_charge_show, + toshiba_usb_rapid_charge_store); +static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, + toshiba_usb_sleep_music_show, + toshiba_usb_sleep_music_store); +static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, + toshiba_kbd_function_keys_show, + toshiba_kbd_function_keys_store); +static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, + toshiba_panel_power_on_show, + toshiba_panel_power_on_store); +static DEVICE_ATTR(usb_three, S_IRUGO | S_IWUSR, + toshiba_usb_three_show, toshiba_usb_three_store); + +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, +}; + static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { @@ -2405,6 +2320,11 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, return exists ? attr->mode : 0; } +static struct attribute_group toshiba_attr_group = { + .is_visible = toshiba_sysfs_is_visible, + .attrs = toshiba_attributes, +}; + /* * Hotkeys */ -- cgit v0.10.2 From 9d3098481934a421ce8b1ce230d22e49f38a2a0b Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 23:43:59 -0700 Subject: toshiba_acpi: Drop the toshiba_ prefix from sysfs function names This patch removes the toshiba_ prefix from all the sysfs function names and adapted the code according to coding style. Also a few functions were renamed to match the sysfs entry, as this patch is a preparation for the next patch to switch to DEVICE_ATTR_{RO, RW, WO} macros. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c4f9d81..f66e0aa 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1676,15 +1676,15 @@ static const struct backlight_ops toshiba_backlight_data = { /* * Sysfs files */ -static ssize_t toshiba_version_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t version_show(struct device *dev, + struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); } -static ssize_t toshiba_fan_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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); u32 result; @@ -1707,8 +1707,8 @@ static ssize_t toshiba_fan_store(struct device *dev, return count; } -static ssize_t toshiba_fan_show(struct device *dev, - struct device_attribute *attr, char *buf) +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; @@ -1721,9 +1721,9 @@ static ssize_t toshiba_fan_show(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -1778,9 +1778,9 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, return count; } -static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -1791,18 +1791,17 @@ static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, return sprintf(buf, "%i\n", time & SCI_KBD_MODE_MASK); } -static ssize_t toshiba_kbd_type_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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 ssize_t toshiba_available_kbd_modes_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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); @@ -1814,9 +1813,9 @@ static ssize_t toshiba_available_kbd_modes_show(struct device *dev, SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF); } -static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -1857,9 +1856,9 @@ static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, return count; } -static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -1870,9 +1869,9 @@ static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, return sprintf(buf, "%i\n", time >> HCI_MISC_SHIFT); } -static ssize_t toshiba_touchpad_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -1892,8 +1891,8 @@ static ssize_t toshiba_touchpad_store(struct device *dev, return count; } -static ssize_t toshiba_touchpad_show(struct device *dev, - struct device_attribute *attr, char *buf) +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; @@ -1906,8 +1905,8 @@ static ssize_t toshiba_touchpad_show(struct device *dev, return sprintf(buf, "%i\n", state); } -static ssize_t toshiba_position_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t position_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); u32 xyval, zval, tmp; @@ -1927,9 +1926,8 @@ static ssize_t toshiba_position_show(struct device *dev, return sprintf(buf, "%d %d %d\n", x, y, z); } -static ssize_t toshiba_usb_sleep_charge_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -1942,9 +1940,9 @@ static ssize_t toshiba_usb_sleep_charge_show(struct device *dev, return sprintf(buf, "%x\n", mode & SCI_USB_CHARGE_MODE_MASK); } -static ssize_t toshiba_usb_sleep_charge_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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); u32 mode; @@ -2038,9 +2036,8 @@ static ssize_t sleep_functions_on_battery_store(struct device *dev, return count; } -static ssize_t toshiba_usb_rapid_charge_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -2053,9 +2050,9 @@ static ssize_t toshiba_usb_rapid_charge_show(struct device *dev, return sprintf(buf, "%d\n", state); } -static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -2074,9 +2071,8 @@ static ssize_t toshiba_usb_rapid_charge_store(struct device *dev, return count; } -static ssize_t toshiba_usb_sleep_music_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -2089,9 +2085,9 @@ static ssize_t toshiba_usb_sleep_music_show(struct device *dev, return sprintf(buf, "%d\n", state); } -static ssize_t toshiba_usb_sleep_music_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -2110,9 +2106,8 @@ static ssize_t toshiba_usb_sleep_music_store(struct device *dev, return count; } -static ssize_t toshiba_kbd_function_keys_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -2125,9 +2120,9 @@ static ssize_t toshiba_kbd_function_keys_show(struct device *dev, return sprintf(buf, "%d\n", mode); } -static ssize_t toshiba_kbd_function_keys_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -2152,9 +2147,8 @@ static ssize_t toshiba_kbd_function_keys_store(struct device *dev, return count; } -static ssize_t toshiba_panel_power_on_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -2167,9 +2161,9 @@ static ssize_t toshiba_panel_power_on_show(struct device *dev, return sprintf(buf, "%d\n", state); } -static ssize_t toshiba_panel_power_on_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -2190,9 +2184,8 @@ static ssize_t toshiba_panel_power_on_store(struct device *dev, return count; } -static ssize_t toshiba_usb_three_show(struct device *dev, - struct device_attribute *attr, - char *buf) +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; @@ -2205,9 +2198,9 @@ static ssize_t toshiba_usb_three_show(struct device *dev, return sprintf(buf, "%d\n", state); } -static ssize_t toshiba_usb_three_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +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; @@ -2232,39 +2225,32 @@ static ssize_t toshiba_usb_three_store(struct device *dev, return count; } -static DEVICE_ATTR(version, S_IRUGO, toshiba_version_show, NULL); -static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, - toshiba_fan_show, toshiba_fan_store); +static DEVICE_ATTR(version, S_IRUGO, version_show, NULL); +static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, fan_show, fan_store); static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, - toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); -static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); + kbd_backlight_mode_show, kbd_backlight_mode_store); +static DEVICE_ATTR(kbd_type, S_IRUGO, kbd_type_show, NULL); static DEVICE_ATTR(available_kbd_modes, S_IRUGO, - toshiba_available_kbd_modes_show, NULL); + available_kbd_modes_show, NULL); static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, - toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store); -static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, - toshiba_touchpad_show, toshiba_touchpad_store); -static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); + kbd_backlight_timeout_show, kbd_backlight_timeout_store); +static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, touchpad_show, touchpad_store); +static DEVICE_ATTR(position, S_IRUGO, position_show, NULL); static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, - toshiba_usb_sleep_charge_show, - toshiba_usb_sleep_charge_store); + usb_sleep_charge_show, usb_sleep_charge_store); static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, sleep_functions_on_battery_show, sleep_functions_on_battery_store); static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, - toshiba_usb_rapid_charge_show, - toshiba_usb_rapid_charge_store); + usb_rapid_charge_show, usb_rapid_charge_store); static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, - toshiba_usb_sleep_music_show, - toshiba_usb_sleep_music_store); + usb_sleep_music_show, usb_sleep_music_store); static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, - toshiba_kbd_function_keys_show, - toshiba_kbd_function_keys_store); + kbd_function_keys_show, kbd_function_keys_store); static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, - toshiba_panel_power_on_show, - toshiba_panel_power_on_store); + panel_power_on_show, panel_power_on_store); static DEVICE_ATTR(usb_three, S_IRUGO | S_IWUSR, - toshiba_usb_three_show, toshiba_usb_three_store); + usb_three_show, usb_three_store); static struct attribute *toshiba_attributes[] = { &dev_attr_version.attr, -- cgit v0.10.2 From 0c3c0f10d4396a3d3dc9d7432102d5437b181487 Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Tue, 10 Feb 2015 23:44:00 -0700 Subject: toshiba_acpi: Make use of DEVICE_ATTR_{RO, RW} macros This patch makes use of the DEVICE_ATTR_{RO, RW} macros to simplify sysfs attributes declarations. Signed-off-by: Azael Avalos Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index f66e0aa..1cfc443 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1681,6 +1681,7 @@ static ssize_t version_show(struct device *dev, { return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); } +static DEVICE_ATTR_RO(version); static ssize_t fan_store(struct device *dev, struct device_attribute *attr, @@ -1720,6 +1721,7 @@ static ssize_t fan_show(struct device *dev, 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, @@ -1790,6 +1792,7 @@ static ssize_t kbd_backlight_mode_show(struct device *dev, 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) @@ -1798,6 +1801,7 @@ static ssize_t kbd_type_show(struct device *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, @@ -1812,6 +1816,7 @@ static ssize_t available_kbd_modes_show(struct device *dev, return sprintf(buf, "%x %x %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, @@ -1868,6 +1873,7 @@ static ssize_t kbd_backlight_timeout_show(struct device *dev, 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, @@ -1904,6 +1910,7 @@ static ssize_t touchpad_show(struct device *dev, return sprintf(buf, "%i\n", state); } +static DEVICE_ATTR_RW(touchpad); static ssize_t position_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1925,6 +1932,7 @@ static ssize_t position_show(struct device *dev, return sprintf(buf, "%d %d %d\n", x, y, z); } +static DEVICE_ATTR_RO(position); static ssize_t usb_sleep_charge_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1974,6 +1982,7 @@ static ssize_t usb_sleep_charge_store(struct device *dev, return count; } +static DEVICE_ATTR_RW(usb_sleep_charge); static ssize_t sleep_functions_on_battery_show(struct device *dev, struct device_attribute *attr, @@ -2035,6 +2044,7 @@ static ssize_t sleep_functions_on_battery_store(struct device *dev, 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) @@ -2070,6 +2080,7 @@ static ssize_t usb_rapid_charge_store(struct device *dev, 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) @@ -2105,6 +2116,7 @@ static ssize_t usb_sleep_music_store(struct device *dev, 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) @@ -2146,6 +2158,7 @@ static ssize_t kbd_function_keys_store(struct device *dev, 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) @@ -2183,6 +2196,7 @@ static ssize_t panel_power_on_store(struct device *dev, return count; } +static DEVICE_ATTR_RW(panel_power_on); static ssize_t usb_three_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -2224,33 +2238,7 @@ static ssize_t usb_three_store(struct device *dev, return count; } - -static DEVICE_ATTR(version, S_IRUGO, version_show, NULL); -static DEVICE_ATTR(fan, S_IRUGO | S_IWUSR, fan_show, fan_store); -static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, - kbd_backlight_mode_show, kbd_backlight_mode_store); -static DEVICE_ATTR(kbd_type, S_IRUGO, kbd_type_show, NULL); -static DEVICE_ATTR(available_kbd_modes, S_IRUGO, - available_kbd_modes_show, NULL); -static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, - kbd_backlight_timeout_show, kbd_backlight_timeout_store); -static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, touchpad_show, touchpad_store); -static DEVICE_ATTR(position, S_IRUGO, position_show, NULL); -static DEVICE_ATTR(usb_sleep_charge, S_IRUGO | S_IWUSR, - usb_sleep_charge_show, usb_sleep_charge_store); -static DEVICE_ATTR(sleep_functions_on_battery, S_IRUGO | S_IWUSR, - sleep_functions_on_battery_show, - sleep_functions_on_battery_store); -static DEVICE_ATTR(usb_rapid_charge, S_IRUGO | S_IWUSR, - usb_rapid_charge_show, usb_rapid_charge_store); -static DEVICE_ATTR(usb_sleep_music, S_IRUGO | S_IWUSR, - usb_sleep_music_show, usb_sleep_music_store); -static DEVICE_ATTR(kbd_function_keys, S_IRUGO | S_IWUSR, - kbd_function_keys_show, kbd_function_keys_store); -static DEVICE_ATTR(panel_power_on, S_IRUGO | S_IWUSR, - panel_power_on_show, panel_power_on_store); -static DEVICE_ATTR(usb_three, S_IRUGO | S_IWUSR, - usb_three_show, usb_three_store); +static DEVICE_ATTR_RW(usb_three); static struct attribute *toshiba_attributes[] = { &dev_attr_version.attr, -- cgit v0.10.2 From e0769fe6f28b500868c2b1059f74ab1177ff41db Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Wed, 11 Feb 2015 20:50:08 -0800 Subject: toshiba_acpi: Cleanup comment blocks and capitalization Ensure multiline comments start with /* and */ each on its own line. Capitalize the first word of comments. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 1cfc443..07be889 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -71,7 +71,8 @@ MODULE_LICENSE("GPL"); /* Toshiba ACPI method paths */ #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" -/* The Toshiba configuration interface is composed of the HCI and the SCI, +/* + * 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 @@ -286,7 +287,8 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { { KE_END, 0 }, }; -/* utility +/* + * Utility */ static inline void _set_bit(u32 *word, u32 mask, int value) @@ -294,7 +296,8 @@ static inline void _set_bit(u32 *word, u32 mask, int value) *word = (*word & ~mask) | (mask * value); } -/* acpi interface wrappers +/* + * ACPI interface wrappers */ static int write_acpi_int(const char *methodName, int val) @@ -305,7 +308,8 @@ static int write_acpi_int(const char *methodName, int val) return (status == AE_OK) ? 0 : -EIO; } -/* Perform a raw configuration call. Here we don't care about input or output +/* + * 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, @@ -339,7 +343,8 @@ static acpi_status tci_raw(struct toshiba_acpi_dev *dev, return status; } -/* common hci tasks (get or set one or two value) +/* + * Common hci tasks (get or set one or two value) * * In addition to the ACPI status, the HCI system returns a result which * may be useful (such as "not supported"). @@ -393,7 +398,8 @@ static u32 hci_read2(struct toshiba_acpi_dev *dev, return out[0]; } -/* common sci tasks +/* + * Common sci tasks */ static int sci_open(struct toshiba_acpi_dev *dev) @@ -414,7 +420,8 @@ static int sci_open(struct toshiba_acpi_dev *dev) 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 + /* + * Some BIOSes do not have the SCI open/close functions * implemented and return 0x8000 (Not Supported), failing to * register some supported features. * @@ -567,10 +574,11 @@ static int toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) return 0; } - /* Check for keyboard backlight timeout max value, + /* + * 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 + * to 0x3c001a, use this to distinguish between them. */ if (out[3] == SCI_KBD_TIME_MAX) dev->kbd_type = 2; @@ -714,7 +722,8 @@ static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) } else if (out[0] == TOS_NOT_INSTALLED) { pr_info("ECO led not installed"); } else if (out[0] == TOS_INPUT_DATA_ERROR) { - /* If we receive 0x8300 (Input Data Error), it means that the + /* + * If we receive 0x8300 (Input Data Error), it means that the * LED device is present, but that we just screwed the input * parameters. * @@ -776,7 +785,8 @@ static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev) u32 out[TCI_WORDS]; acpi_status status; - /* Check if the accelerometer call exists, + /* + * Check if the accelerometer call exists, * this call also serves as initialization */ status = tci_raw(dev, in, out); @@ -1433,9 +1443,9 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, buffer = cmd; - /* scan expression. Multiple expressions may be delimited with ; - * - * NOTE: to keep scanning simple, invalid fields are ignored + /* + * 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) @@ -1444,7 +1454,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, crt_out = value & 1; else if (sscanf(buffer, " tv_out : %i", &value) == 1) tv_out = value & 1; - /* advance to one character past the next ; */ + /* Advance to one character past the next ; */ do { ++buffer; --remain; @@ -1463,7 +1473,8 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, _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 + /* + * 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); @@ -1558,11 +1569,13 @@ static int keys_proc_show(struct seq_file *m, void *v) dev->key_event_valid = 1; dev->last_key_event = value; } else if (hci_result == TOS_FIFO_EMPTY) { - /* better luck next time */ + /* Better luck next time */ } else if (hci_result == TOS_NOT_SUPPORTED) { - /* This is a workaround for an unresolved issue on + /* + * This is a workaround for an unresolved issue on * some machines where system events sporadically - * become disabled. */ + * become disabled. + */ hci_result = hci_write1(dev, HCI_SYSTEM_EVENT, 1); pr_notice("Re-enabled hotkeys\n"); } else { @@ -1631,7 +1644,8 @@ static const struct file_operations version_proc_fops = { .release = single_release, }; -/* proc and module init +/* + * Proc and module init */ #define PROC_TOSHIBA "toshiba" @@ -1749,7 +1763,8 @@ static ssize_t kbd_backlight_mode_store(struct device *dev, return -EINVAL; } - /* Set the Keyboard Backlight Mode where: + /* + * 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 @@ -1960,7 +1975,8 @@ static ssize_t usb_sleep_charge_store(struct device *dev, ret = kstrtoint(buf, 0, &state); if (ret) return ret; - /* Check for supported values, where: + /* + * Check for supported values, where: * 0 - Disabled * 1 - Alternate (Non USB conformant devices that require more power) * 2 - Auto (USB conformant devices) @@ -2022,7 +2038,8 @@ static ssize_t sleep_functions_on_battery_store(struct device *dev, if (ret) return ret; - /* Set the status of the function: + /* + * Set the status of the function: * 0 - Disabled * 1-100 - Enabled */ @@ -2143,7 +2160,8 @@ static ssize_t kbd_function_keys_store(struct device *dev, ret = kstrtoint(buf, 0, &mode); if (ret) return ret; - /* Check for the function keys mode where: + /* + * 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) */ @@ -2223,7 +2241,8 @@ static ssize_t usb_three_store(struct device *dev, ret = kstrtoint(buf, 0, &state); if (ret) return ret; - /* Check for USB 3 mode where: + /* + * Check for USB 3 mode where: * 0 - Disabled (Acts like a USB 2 port, saving power) * 1 - Enabled */ @@ -2375,7 +2394,7 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, if (scancode == 0x100) return; - /* act on key press; ignore key release */ + /* Act on key press; ignore key release */ if (scancode & 0x80) return; @@ -2411,7 +2430,7 @@ static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) hci_result = hci_write1(dev, HCI_SYSTEM_EVENT, 1); pr_notice("Re-enabled hotkeys\n"); - /* fall through */ + /* Fall through */ default: retries--; break; @@ -2533,7 +2552,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) props.type = BACKLIGHT_PLATFORM; props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; - /* adding an extra level and having 0 change to transflective mode */ + /* Adding an extra level and having 0 change to transflective mode */ if (dev->tr_backlight_supported) props.max_brightness++; -- cgit v0.10.2 From c57c0fa4bc9c2ad023674ef478c25719abaace7d Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Wed, 11 Feb 2015 21:25:22 -0800 Subject: toshiba_acpi: Cleanup GPL header Remove the Free Software Foundation street address paragraph and reference COPYING. Remove an empty TODO block. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 07be889..dbcb7a8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1,7 +1,6 @@ /* * toshiba_acpi.c - Toshiba Laptop ACPI Extras * - * * Copyright (C) 2002-2004 John Belmonte * Copyright (C) 2008 Philip Langdale * Copyright (C) 2010 Pierre Ducroquet @@ -17,10 +16,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". * * The devolpment page for this driver is located at * http://memebeam.org/toys/ToshibaAcpiDriver. @@ -30,10 +27,6 @@ * engineering the Windows drivers * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 * Rob Miller - TV out and hotkeys help - * - * - * TODO - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- cgit v0.10.2