|
@@ -97,6 +97,8 @@ MODULE_LICENSE("GPL");
|
|
#define HCI_FAILURE 0x1000
|
|
#define HCI_FAILURE 0x1000
|
|
#define HCI_NOT_SUPPORTED 0x8000
|
|
#define HCI_NOT_SUPPORTED 0x8000
|
|
#define HCI_EMPTY 0x8c00
|
|
#define HCI_EMPTY 0x8c00
|
|
|
|
+#define HCI_DATA_NOT_AVAILABLE 0x8d20
|
|
|
|
+#define HCI_NOT_INITIALIZED 0x8d50
|
|
#define SCI_OPEN_CLOSE_OK 0x0044
|
|
#define SCI_OPEN_CLOSE_OK 0x0044
|
|
#define SCI_ALREADY_OPEN 0x8100
|
|
#define SCI_ALREADY_OPEN 0x8100
|
|
#define SCI_NOT_OPENED 0x8200
|
|
#define SCI_NOT_OPENED 0x8200
|
|
@@ -111,13 +113,16 @@ MODULE_LICENSE("GPL");
|
|
#define HCI_HOTKEY_EVENT 0x001e
|
|
#define HCI_HOTKEY_EVENT 0x001e
|
|
#define HCI_LCD_BRIGHTNESS 0x002a
|
|
#define HCI_LCD_BRIGHTNESS 0x002a
|
|
#define HCI_WIRELESS 0x0056
|
|
#define HCI_WIRELESS 0x0056
|
|
|
|
+#define HCI_ACCELEROMETER 0x006d
|
|
#define HCI_KBD_ILLUMINATION 0x0095
|
|
#define HCI_KBD_ILLUMINATION 0x0095
|
|
#define HCI_ECO_MODE 0x0097
|
|
#define HCI_ECO_MODE 0x0097
|
|
|
|
+#define HCI_ACCELEROMETER2 0x00a6
|
|
#define SCI_ILLUMINATION 0x014e
|
|
#define SCI_ILLUMINATION 0x014e
|
|
#define SCI_KBD_ILLUM_STATUS 0x015c
|
|
#define SCI_KBD_ILLUM_STATUS 0x015c
|
|
#define SCI_TOUCHPAD 0x050e
|
|
#define SCI_TOUCHPAD 0x050e
|
|
|
|
|
|
/* field definitions */
|
|
/* field definitions */
|
|
|
|
+#define HCI_ACCEL_MASK 0x7fff
|
|
#define HCI_HOTKEY_DISABLE 0x0b
|
|
#define HCI_HOTKEY_DISABLE 0x0b
|
|
#define HCI_HOTKEY_ENABLE 0x09
|
|
#define HCI_HOTKEY_ENABLE 0x09
|
|
#define HCI_LCD_BRIGHTNESS_BITS 3
|
|
#define HCI_LCD_BRIGHTNESS_BITS 3
|
|
@@ -162,6 +167,7 @@ struct toshiba_acpi_dev {
|
|
unsigned int kbd_led_registered:1;
|
|
unsigned int kbd_led_registered:1;
|
|
unsigned int touchpad_supported:1;
|
|
unsigned int touchpad_supported:1;
|
|
unsigned int eco_supported:1;
|
|
unsigned int eco_supported:1;
|
|
|
|
+ unsigned int accelerometer_supported:1;
|
|
unsigned int sysfs_created:1;
|
|
unsigned int sysfs_created:1;
|
|
|
|
|
|
struct mutex mutex;
|
|
struct mutex mutex;
|
|
@@ -624,6 +630,52 @@ static void toshiba_eco_mode_set_status(struct led_classdev *cdev,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/* Accelerometer support */
|
|
|
|
+static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev)
|
|
|
|
+{
|
|
|
|
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 };
|
|
|
|
+ u32 out[HCI_WORDS];
|
|
|
|
+ acpi_status status;
|
|
|
|
+
|
|
|
|
+ /* Check if the accelerometer call exists,
|
|
|
|
+ * this call also serves as initialization
|
|
|
|
+ */
|
|
|
|
+ status = hci_raw(dev, in, out);
|
|
|
|
+ if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
|
|
|
|
+ pr_err("ACPI call to query the accelerometer failed\n");
|
|
|
|
+ return -EIO;
|
|
|
|
+ } else if (out[0] == HCI_DATA_NOT_AVAILABLE ||
|
|
|
|
+ out[0] == HCI_NOT_INITIALIZED) {
|
|
|
|
+ pr_err("Accelerometer not initialized\n");
|
|
|
|
+ return -EIO;
|
|
|
|
+ } else if (out[0] == HCI_NOT_SUPPORTED) {
|
|
|
|
+ pr_info("Accelerometer not supported\n");
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev,
|
|
|
|
+ u32 *xy, u32 *z)
|
|
|
|
+{
|
|
|
|
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER, 0, 1, 0, 0 };
|
|
|
|
+ u32 out[HCI_WORDS];
|
|
|
|
+ acpi_status status;
|
|
|
|
+
|
|
|
|
+ /* Check the Accelerometer status */
|
|
|
|
+ status = hci_raw(dev, in, out);
|
|
|
|
+ if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
|
|
|
|
+ pr_err("ACPI call to query the accelerometer failed\n");
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *xy = out[2];
|
|
|
|
+ *z = out[4];
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
|
|
/* Bluetooth rfkill handlers */
|
|
/* Bluetooth rfkill handlers */
|
|
|
|
|
|
@@ -1257,6 +1309,27 @@ static ssize_t toshiba_touchpad_show(struct device *dev,
|
|
|
|
|
|
return sprintf(buf, "%i\n", state);
|
|
return sprintf(buf, "%i\n", state);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+static ssize_t toshiba_position_show(struct device *dev,
|
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
|
+{
|
|
|
|
+ struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
|
|
|
|
+ u32 xyval, zval, tmp;
|
|
|
|
+ u16 x, y, z;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ xyval = zval = 0;
|
|
|
|
+ ret = toshiba_accelerometer_get(toshiba, &xyval, &zval);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ x = xyval & HCI_ACCEL_MASK;
|
|
|
|
+ tmp = xyval >> HCI_MISC_SHIFT;
|
|
|
|
+ y = tmp & HCI_ACCEL_MASK;
|
|
|
|
+ z = zval & HCI_ACCEL_MASK;
|
|
|
|
+
|
|
|
|
+ return sprintf(buf, "%d %d %d\n", x, y, z);
|
|
|
|
+}
|
|
|
|
|
|
static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR,
|
|
static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR,
|
|
toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store);
|
|
toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store);
|
|
@@ -1264,11 +1337,13 @@ static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR,
|
|
toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store);
|
|
toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store);
|
|
static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR,
|
|
static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR,
|
|
toshiba_touchpad_show, toshiba_touchpad_store);
|
|
toshiba_touchpad_show, toshiba_touchpad_store);
|
|
|
|
+static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL);
|
|
|
|
|
|
static struct attribute *toshiba_attributes[] = {
|
|
static struct attribute *toshiba_attributes[] = {
|
|
&dev_attr_kbd_backlight_mode.attr,
|
|
&dev_attr_kbd_backlight_mode.attr,
|
|
&dev_attr_kbd_backlight_timeout.attr,
|
|
&dev_attr_kbd_backlight_timeout.attr,
|
|
&dev_attr_touchpad.attr,
|
|
&dev_attr_touchpad.attr,
|
|
|
|
+ &dev_attr_position.attr,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -1285,6 +1360,8 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
|
|
exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false;
|
|
exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false;
|
|
else if (attr == &dev_attr_touchpad.attr)
|
|
else if (attr == &dev_attr_touchpad.attr)
|
|
exists = (drv->touchpad_supported) ? true : false;
|
|
exists = (drv->touchpad_supported) ? true : false;
|
|
|
|
+ else if (attr == &dev_attr_position.attr)
|
|
|
|
+ exists = (drv->accelerometer_supported) ? true : false;
|
|
|
|
|
|
return exists ? attr->mode : 0;
|
|
return exists ? attr->mode : 0;
|
|
}
|
|
}
|
|
@@ -1643,6 +1720,9 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
|
|
|
|
|
|
ret = toshiba_touchpad_get(dev, &dummy);
|
|
ret = toshiba_touchpad_get(dev, &dummy);
|
|
dev->touchpad_supported = !ret;
|
|
dev->touchpad_supported = !ret;
|
|
|
|
+
|
|
|
|
+ ret = toshiba_accelerometer_supported(dev);
|
|
|
|
+ dev->accelerometer_supported = !ret;
|
|
|
|
|
|
/* Determine whether or not BIOS supports fan and video interfaces */
|
|
/* Determine whether or not BIOS supports fan and video interfaces */
|
|
|
|
|