linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions
@ 2015-01-14 21:40 Azael Avalos
  2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Azael Avalos @ 2015-01-14 21:40 UTC (permalink / raw)
  To: Darren Hart, platform-driver-x86, linux-kernel; +Cc: Azael Avalos

The following patches add support to several USB Sleep functions
found on newer Toshiba laptops, allowing to use th USB ports while
the laptop is asleep or turned off.

Azael Avalos (4):
  toshiba_acpi: Add support for USB Sleep and Charge function
  toshiba_acpi: Add support for USB Sleep functions under battery
  toshiba_acpi: Add support for USB Rapid Charge
  toshiba_acpi: Add support for USB Sleep and Music

 drivers/platform/x86/toshiba_acpi.c | 449 ++++++++++++++++++++++++++++++++++++
 1 file changed, 449 insertions(+)

-- 
2.2.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function
  2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
@ 2015-01-14 21:40 ` Azael Avalos
  2015-01-18 18:46   ` Darren Hart
  2015-01-18 18:55   ` Darren Hart
  2015-01-14 21:40 ` [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery Azael Avalos
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: Azael Avalos @ 2015-01-14 21:40 UTC (permalink / raw)
  To: Darren Hart, platform-driver-x86, linux-kernel; +Cc: Azael Avalos

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, 0x0, 0x9 and 0x21, beign
disabled, alternate and auto respectively.

Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
---
 drivers/platform/x86/toshiba_acpi.c | 112 ++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 71ac7c12..b03129d 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;
@@ -761,6 +767,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)
@@ -1314,6 +1367,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);
@@ -1325,6 +1384,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,
@@ -1333,6 +1395,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,
 };
 
@@ -1550,6 +1613,50 @@ 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 state;
+	int ret;
+
+	ret = toshiba_usb_sleep_charge_get(toshiba, &state);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%x\n", state & 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);
+	int state;
+	int ret;
+
+	ret = kstrtoint(buf, 0, &state);
+	if (ret)
+		return ret;
+
+	/* Set the USB charging mode where:
+	 * 0x30000 - Disable
+	 * 0x30009 - Alternate
+	 * 0x30021 - Auto
+	 */
+	state |= 0x30000;
+	if (state != SCI_USB_CHARGE_DISABLED && state != SCI_USB_CHARGE_AUTO &&
+	    state != SCI_USB_CHARGE_ALTERNATE)
+		return -EINVAL;
+
+	ret = toshiba_usb_sleep_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)
 {
@@ -1565,6 +1672,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;
 }
@@ -1974,6 +2083,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);
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery
  2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
  2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
@ 2015-01-14 21:40 ` Azael Avalos
  2015-01-18 18:54   ` Darren Hart
  2015-01-14 21:40 ` [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge Azael Avalos
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Azael Avalos @ 2015-01-14 21:40 UTC (permalink / raw)
  To: Darren Hart, platform-driver-x86, linux-kernel; +Cc: Azael Avalos

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 <coproscefalo@gmail.com>
---
 drivers/platform/x86/toshiba_acpi.c | 133 ++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index b03129d..9e054c5 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;
@@ -814,6 +819,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)
@@ -1373,6 +1433,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);
@@ -1387,6 +1453,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,
@@ -1396,6 +1465,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,
 };
 
@@ -1657,6 +1727,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 ret;
+	int tmp;
+	int status;
+	int bat_lvl;
+
+	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)
 {
@@ -1674,6 +1805,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;
 }
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge
  2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
  2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
  2015-01-14 21:40 ` [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery Azael Avalos
@ 2015-01-14 21:40 ` Azael Avalos
  2015-01-18 19:00   ` Darren Hart
  2015-01-14 21:40 ` [PATCH 4/4] toshiba_acpi: Add support for USB Sleep and Music Azael Avalos
  2015-01-18 19:07 ` [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Darren Hart
  4 siblings, 1 reply; 10+ messages in thread
From: Azael Avalos @ 2015-01-14 21:40 UTC (permalink / raw)
  To: Darren Hart, platform-driver-x86, linux-kernel; +Cc: Azael Avalos

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
one to enable, however, the machine needs a restart everytime the
function is toggled.

Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
---
 drivers/platform/x86/toshiba_acpi.c | 107 ++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 9e054c5..eba5f9e 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;
@@ -874,6 +876,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)
@@ -1439,6 +1495,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);
@@ -1456,6 +1518,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,
@@ -1466,6 +1531,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,
 };
 
@@ -1788,6 +1854,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)
 {
@@ -1807,6 +1909,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;
 }
@@ -2219,6 +2323,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);
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] toshiba_acpi: Add support for USB Sleep and Music
  2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
                   ` (2 preceding siblings ...)
  2015-01-14 21:40 ` [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge Azael Avalos
@ 2015-01-14 21:40 ` Azael Avalos
  2015-01-18 19:07 ` [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Darren Hart
  4 siblings, 0 replies; 10+ messages in thread
From: Azael Avalos @ 2015-01-14 21:40 UTC (permalink / raw)
  To: Darren Hart, platform-driver-x86, linux-kernel; +Cc: Azael Avalos

Newer Toshiba laptops now come with a feature called USB Sleep and
Charge, where the laptop speakers remain powered and the line-in jack
is used to connect an external device to use the laptop speakers.

This patchs adds support to such feature, by creating a sysfs entry
named "usb_sleep_music", accepting parameters zero and one, where
zero disables the feature and one enables it respectively.

Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
---
 drivers/platform/x86/toshiba_acpi.c | 97 +++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index eba5f9e..d107f38 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;
@@ -930,6 +932,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)
@@ -1501,6 +1547,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);
@@ -1521,6 +1573,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,
@@ -1532,6 +1587,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,
 };
 
@@ -1890,6 +1946,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)
 {
@@ -1911,6 +2003,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;
 }
@@ -2326,6 +2420,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);
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function
  2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
@ 2015-01-18 18:46   ` Darren Hart
  2015-01-18 18:55   ` Darren Hart
  1 sibling, 0 replies; 10+ messages in thread
From: Darren Hart @ 2015-01-18 18:46 UTC (permalink / raw)
  To: Azael Avalos; +Cc: platform-driver-x86, linux-kernel

On Wed, Jan 14, 2015 at 02:40:18PM -0700, Azael Avalos wrote:
> 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, 0x0, 0x9 and 0x21, beign
> disabled, alternate and auto respectively.
> 
> Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
> ---
>  drivers/platform/x86/toshiba_acpi.c | 112 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 112 insertions(+)
> 
> diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
> index 71ac7c12..b03129d 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;
> @@ -761,6 +767,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;

Personally I would feel more comfortable relying on our own data input
validation than that of the AML.

We can also present the user with an abstracted interface, we don't need to have
them send in register values that match the underlying hardware. In fact, should
the firmware in future machines change, you will be faced with having to remap
values should they mean different things. I would suggest defining a user
visible namespace for these, consider:

0: Disabled
1: Auto
2: Alternate (what does this mean anyway?)

Also, per Documentation/sysfs-rules.txt, which I believe I added based on
previous review with you?, -EIO is typically returned by sysfs itself from some
sort of general failure, like a NULL read or store pointer.

When the read or store operation fails as above, -ENXIO is the preferred error
code.

-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery
  2015-01-14 21:40 ` [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery Azael Avalos
@ 2015-01-18 18:54   ` Darren Hart
  0 siblings, 0 replies; 10+ messages in thread
From: Darren Hart @ 2015-01-18 18:54 UTC (permalink / raw)
  To: Azael Avalos; +Cc: platform-driver-x86, linux-kernel

On Wed, Jan 14, 2015 at 02:40:19PM -0700, Azael Avalos wrote:
> 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 <coproscefalo@gmail.com>
> ---
>  drivers/platform/x86/toshiba_acpi.c | 133 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 133 insertions(+)
> 
> diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
> index b03129d..9e054c5 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;
> @@ -814,6 +819,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;
> +	}
> +

See comments to 1/4 regarding error codes and input validation.

> +	return 0;
> +}
> +
>  /* Bluetooth rfkill handlers */
>  
>  static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present)
> @@ -1373,6 +1433,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);
> @@ -1387,6 +1453,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,
> @@ -1396,6 +1465,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,
>  };
>  
> @@ -1657,6 +1727,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 ret;
> +	int tmp;
> +	int status;
> +	int bat_lvl;

Order declarations in decreasing line length please.

int bat_lvl;
int status;
int state;
int tmp;
int ret;

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

Yeah, like that ;-)

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

Ah, oops, you catch the input here. Good.

-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function
  2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
  2015-01-18 18:46   ` Darren Hart
@ 2015-01-18 18:55   ` Darren Hart
  1 sibling, 0 replies; 10+ messages in thread
From: Darren Hart @ 2015-01-18 18:55 UTC (permalink / raw)
  To: Azael Avalos; +Cc: platform-driver-x86, linux-kernel

On Wed, Jan 14, 2015 at 02:40:18PM -0700, Azael Avalos wrote:
> 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, 0x0, 0x9 and 0x21, beign
> disabled, alternate and auto respectively.
> 
> Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
> ---
>  drivers/platform/x86/toshiba_acpi.c | 112 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 112 insertions(+)
...

> +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);
> +	int state;
> +	int ret;
> +
> +	ret = kstrtoint(buf, 0, &state);
> +	if (ret)
> +		return ret;
> +
> +	/* Set the USB charging mode where:
> +	 * 0x30000 - Disable
> +	 * 0x30009 - Alternate
> +	 * 0x30021 - Auto
> +	 */
> +	state |= 0x30000;
> +	if (state != SCI_USB_CHARGE_DISABLED && state != SCI_USB_CHARGE_AUTO &&
> +	    state != SCI_USB_CHARGE_ALTERNATE)
> +		return -EINVAL;

Sorry, I missed this as the input validation on my first pass. Looks good.

-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge
  2015-01-14 21:40 ` [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge Azael Avalos
@ 2015-01-18 19:00   ` Darren Hart
  0 siblings, 0 replies; 10+ messages in thread
From: Darren Hart @ 2015-01-18 19:00 UTC (permalink / raw)
  To: Azael Avalos; +Cc: platform-driver-x86, linux-kernel

On Wed, Jan 14, 2015 at 02:40:20PM -0700, Azael Avalos wrote:
> 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
> one to enable, however, the machine needs a restart everytime the

s/one/1//

> function is toggled.
> 
> Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
> ---
>  drivers/platform/x86/toshiba_acpi.c | 107 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
> 
> diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
> index 9e054c5..eba5f9e 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;
> @@ -874,6 +876,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;
> +	}
> +

Same comment on return codes.

Although, on looking through the existing driver, I only see EIO, and internally
consistency is important.... we can stick with EIO for this driver.
-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions
  2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
                   ` (3 preceding siblings ...)
  2015-01-14 21:40 ` [PATCH 4/4] toshiba_acpi: Add support for USB Sleep and Music Azael Avalos
@ 2015-01-18 19:07 ` Darren Hart
  4 siblings, 0 replies; 10+ messages in thread
From: Darren Hart @ 2015-01-18 19:07 UTC (permalink / raw)
  To: Azael Avalos; +Cc: platform-driver-x86, linux-kernel

On Wed, Jan 14, 2015 at 02:40:17PM -0700, Azael Avalos wrote:
> The following patches add support to several USB Sleep functions
> found on newer Toshiba laptops, allowing to use th USB ports while
> the laptop is asleep or turned off.
> 
> Azael Avalos (4):
>   toshiba_acpi: Add support for USB Sleep and Charge function
>   toshiba_acpi: Add support for USB Sleep functions under battery
>   toshiba_acpi: Add support for USB Rapid Charge
>   toshiba_acpi: Add support for USB Sleep and Music
> 
>  drivers/platform/x86/toshiba_acpi.c | 449 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 449 insertions(+)

Hi Azael,

Ignore my comments on input validation and error codes, you cover the former,
and the latter keeps the driver internally consistent. That only leaves the
Disable/Auto/Alternate values and a couple trivial formatting and typos to
address.

Thanks,

-- 
Darren Hart
Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-01-18 19:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-14 21:40 [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Azael Avalos
2015-01-14 21:40 ` [PATCH 1/4] toshiba_acpi: Add support for USB Sleep and Charge function Azael Avalos
2015-01-18 18:46   ` Darren Hart
2015-01-18 18:55   ` Darren Hart
2015-01-14 21:40 ` [PATCH 2/4] toshiba_acpi: Add support for USB Sleep functions under battery Azael Avalos
2015-01-18 18:54   ` Darren Hart
2015-01-14 21:40 ` [PATCH 3/4] toshiba_acpi: Add support for USB Rapid Charge Azael Avalos
2015-01-18 19:00   ` Darren Hart
2015-01-14 21:40 ` [PATCH 4/4] toshiba_acpi: Add support for USB Sleep and Music Azael Avalos
2015-01-18 19:07 ` [PATCH 0/4] toshiba_acpi: Add support for USB Sleep functions Darren Hart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).