aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorAzael Avalos <coproscefalo@gmail.com>2014-09-12 20:50:36 -0400
committerDarren Hart <dvhart@linux.intel.com>2014-09-17 16:55:52 -0400
commit93f8c16d635e6b1e3ea978e38e110391ce28b26f (patch)
tree033cb4f74ed000b218690ef6f17dbc82c636b47c /drivers/platform
parentc8a41669a76381f655f5567d3ccd8449a53f9a7f (diff)
toshiba_acpi: Support new keyboard backlight type
Newer Toshiba models now come with a new (and different) keyboard backlight implementation with three modes of operation: TIMER, ON and OFF, and the LED is now controlled internally by the firmware. This patch adds support for that type of backlight, changing the existing code to accomodate the new implementation. The timeout value range is now 1-60 seconds, and the accepted modes are now: 1 (FN-Z), 2 (AUTO or TIMER), 8 (ON) and 10 (OFF), this adds two new entries kbd_type and available_kbd_modes, the first shows the keyboard type and the latter shows the supported modes depending on the keyboard type. Signed-off-by: Azael Avalos <coproscefalo@gmail.com> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/toshiba_acpi.c188
1 files changed, 156 insertions, 32 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 2a84652a4f0e..edd8f3dad6b4 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -138,8 +138,12 @@ MODULE_LICENSE("GPL");
138#define HCI_WIRELESS_BT_PRESENT 0x0f 138#define HCI_WIRELESS_BT_PRESENT 0x0f
139#define HCI_WIRELESS_BT_ATTACH 0x40 139#define HCI_WIRELESS_BT_ATTACH 0x40
140#define HCI_WIRELESS_BT_POWER 0x80 140#define HCI_WIRELESS_BT_POWER 0x80
141#define SCI_KBD_MODE_MASK 0x1f
141#define SCI_KBD_MODE_FNZ 0x1 142#define SCI_KBD_MODE_FNZ 0x1
142#define SCI_KBD_MODE_AUTO 0x2 143#define SCI_KBD_MODE_AUTO 0x2
144#define SCI_KBD_MODE_ON 0x8
145#define SCI_KBD_MODE_OFF 0x10
146#define SCI_KBD_TIME_MAX 0x3c001a
143 147
144struct toshiba_acpi_dev { 148struct toshiba_acpi_dev {
145 struct acpi_device *acpi_dev; 149 struct acpi_device *acpi_dev;
@@ -155,6 +159,7 @@ struct toshiba_acpi_dev {
155 int force_fan; 159 int force_fan;
156 int last_key_event; 160 int last_key_event;
157 int key_event_valid; 161 int key_event_valid;
162 int kbd_type;
158 int kbd_mode; 163 int kbd_mode;
159 int kbd_time; 164 int kbd_time;
160 165
@@ -495,6 +500,42 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
495} 500}
496 501
497/* KBD Illumination */ 502/* KBD Illumination */
503static int toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev)
504{
505 u32 in[HCI_WORDS] = { SCI_GET, SCI_KBD_ILLUM_STATUS, 0, 0, 0, 0 };
506 u32 out[HCI_WORDS];
507 acpi_status status;
508
509 if (!sci_open(dev))
510 return 0;
511
512 status = hci_raw(dev, in, out);
513 sci_close(dev);
514 if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) {
515 pr_err("ACPI call to query kbd illumination support failed\n");
516 return 0;
517 } else if (out[0] == HCI_NOT_SUPPORTED) {
518 pr_info("Keyboard illumination not available\n");
519 return 0;
520 }
521
522 /* Check for keyboard backlight timeout max value,
523 * previous kbd backlight implementation set this to
524 * 0x3c0003, and now the new implementation set this
525 * to 0x3c001a, use this to distinguish between them
526 */
527 if (out[3] == SCI_KBD_TIME_MAX)
528 dev->kbd_type = 2;
529 else
530 dev->kbd_type = 1;
531 /* Get the current keyboard backlight mode */
532 dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK;
533 /* Get the current time (1-60 seconds) */
534 dev->kbd_time = out[2] >> HCI_MISC_SHIFT;
535
536 return 1;
537}
538
498static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time) 539static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time)
499{ 540{
500 u32 result; 541 u32 result;
@@ -1254,6 +1295,62 @@ static const struct backlight_ops toshiba_backlight_data = {
1254/* 1295/*
1255 * Sysfs files 1296 * Sysfs files
1256 */ 1297 */
1298static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
1299 struct device_attribute *attr,
1300 const char *buf, size_t count);
1301static ssize_t toshiba_kbd_bl_mode_show(struct device *dev,
1302 struct device_attribute *attr,
1303 char *buf);
1304static ssize_t toshiba_kbd_type_show(struct device *dev,
1305 struct device_attribute *attr,
1306 char *buf);
1307static ssize_t toshiba_available_kbd_modes_show(struct device *dev,
1308 struct device_attribute *attr,
1309 char *buf);
1310static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev,
1311 struct device_attribute *attr,
1312 const char *buf, size_t count);
1313static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev,
1314 struct device_attribute *attr,
1315 char *buf);
1316static ssize_t toshiba_touchpad_store(struct device *dev,
1317 struct device_attribute *attr,
1318 const char *buf, size_t count);
1319static ssize_t toshiba_touchpad_show(struct device *dev,
1320 struct device_attribute *attr,
1321 char *buf);
1322static ssize_t toshiba_position_show(struct device *dev,
1323 struct device_attribute *attr,
1324 char *buf);
1325
1326static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR,
1327 toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store);
1328static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL);
1329static DEVICE_ATTR(available_kbd_modes, S_IRUGO,
1330 toshiba_available_kbd_modes_show, NULL);
1331static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR,
1332 toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store);
1333static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR,
1334 toshiba_touchpad_show, toshiba_touchpad_store);
1335static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL);
1336
1337static struct attribute *toshiba_attributes[] = {
1338 &dev_attr_kbd_backlight_mode.attr,
1339 &dev_attr_kbd_type.attr,
1340 &dev_attr_available_kbd_modes.attr,
1341 &dev_attr_kbd_backlight_timeout.attr,
1342 &dev_attr_touchpad.attr,
1343 &dev_attr_position.attr,
1344 NULL,
1345};
1346
1347static umode_t toshiba_sysfs_is_visible(struct kobject *,
1348 struct attribute *, int);
1349
1350static struct attribute_group toshiba_attr_group = {
1351 .is_visible = toshiba_sysfs_is_visible,
1352 .attrs = toshiba_attributes,
1353};
1257 1354
1258static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, 1355static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
1259 struct device_attribute *attr, 1356 struct device_attribute *attr,
@@ -1268,20 +1365,50 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
1268 ret = kstrtoint(buf, 0, &mode); 1365 ret = kstrtoint(buf, 0, &mode);
1269 if (ret) 1366 if (ret)
1270 return ret; 1367 return ret;
1271 if (mode != SCI_KBD_MODE_FNZ && mode != SCI_KBD_MODE_AUTO) 1368
1272 return -EINVAL; 1369 /* Check for supported modes depending on keyboard backlight type */
1370 if (toshiba->kbd_type == 1) {
1371 /* Type 1 supports SCI_KBD_MODE_FNZ and SCI_KBD_MODE_AUTO */
1372 if (mode != SCI_KBD_MODE_FNZ && mode != SCI_KBD_MODE_AUTO)
1373 return -EINVAL;
1374 } else if (toshiba->kbd_type == 2) {
1375 /* Type 2 doesn't support SCI_KBD_MODE_FNZ */
1376 if (mode != SCI_KBD_MODE_AUTO && mode != SCI_KBD_MODE_ON &&
1377 mode != SCI_KBD_MODE_OFF)
1378 return -EINVAL;
1379 }
1273 1380
1274 /* Set the Keyboard Backlight Mode where: 1381 /* Set the Keyboard Backlight Mode where:
1275 * Mode - Auto (2) | FN-Z (1)
1276 * Auto - KBD backlight turns off automatically in given time 1382 * Auto - KBD backlight turns off automatically in given time
1277 * FN-Z - KBD backlight "toggles" when hotkey pressed 1383 * FN-Z - KBD backlight "toggles" when hotkey pressed
1384 * ON - KBD backlight is always on
1385 * OFF - KBD backlight is always off
1278 */ 1386 */
1387
1388 /* Only make a change if the actual mode has changed */
1279 if (toshiba->kbd_mode != mode) { 1389 if (toshiba->kbd_mode != mode) {
1390 /* Shift the time to "base time" (0x3c0000 == 60 seconds) */
1280 time = toshiba->kbd_time << HCI_MISC_SHIFT; 1391 time = toshiba->kbd_time << HCI_MISC_SHIFT;
1281 time = time + toshiba->kbd_mode; 1392
1393 /* OR the "base time" to the actual method format */
1394 if (toshiba->kbd_type == 1) {
1395 /* Type 1 requires the current mode */
1396 time |= toshiba->kbd_mode;
1397 } else if (toshiba->kbd_type == 2) {
1398 /* Type 2 requires the desired mode */
1399 time |= mode;
1400 }
1401
1282 ret = toshiba_kbd_illum_status_set(toshiba, time); 1402 ret = toshiba_kbd_illum_status_set(toshiba, time);
1283 if (ret) 1403 if (ret)
1284 return ret; 1404 return ret;
1405
1406 /* Update sysfs entries on successful mode change*/
1407 ret = sysfs_update_group(&toshiba->acpi_dev->dev.kobj,
1408 &toshiba_attr_group);
1409 if (ret)
1410 return ret;
1411
1285 toshiba->kbd_mode = mode; 1412 toshiba->kbd_mode = mode;
1286 } 1413 }
1287 1414
@@ -1298,7 +1425,30 @@ static ssize_t toshiba_kbd_bl_mode_show(struct device *dev,
1298 if (toshiba_kbd_illum_status_get(toshiba, &time) < 0) 1425 if (toshiba_kbd_illum_status_get(toshiba, &time) < 0)
1299 return -EIO; 1426 return -EIO;
1300 1427
1301 return sprintf(buf, "%i\n", time & 0x07); 1428 return sprintf(buf, "%i\n", time & SCI_KBD_MODE_MASK);
1429}
1430
1431static ssize_t toshiba_kbd_type_show(struct device *dev,
1432 struct device_attribute *attr,
1433 char *buf)
1434{
1435 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1436
1437 return sprintf(buf, "%d\n", toshiba->kbd_type);
1438}
1439
1440static ssize_t toshiba_available_kbd_modes_show(struct device *dev,
1441 struct device_attribute *attr,
1442 char *buf)
1443{
1444 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1445
1446 if (toshiba->kbd_type == 1)
1447 return sprintf(buf, "%x %x\n",
1448 SCI_KBD_MODE_FNZ, SCI_KBD_MODE_AUTO);
1449
1450 return sprintf(buf, "%x %x %x\n",
1451 SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF);
1302} 1452}
1303 1453
1304static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, 1454static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev,
@@ -1394,22 +1544,6 @@ static ssize_t toshiba_position_show(struct device *dev,
1394 return sprintf(buf, "%d %d %d\n", x, y, z); 1544 return sprintf(buf, "%d %d %d\n", x, y, z);
1395} 1545}
1396 1546
1397static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR,
1398 toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store);
1399static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR,
1400 toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store);
1401static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR,
1402 toshiba_touchpad_show, toshiba_touchpad_store);
1403static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL);
1404
1405static struct attribute *toshiba_attributes[] = {
1406 &dev_attr_kbd_backlight_mode.attr,
1407 &dev_attr_kbd_backlight_timeout.attr,
1408 &dev_attr_touchpad.attr,
1409 &dev_attr_position.attr,
1410 NULL,
1411};
1412
1413static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, 1547static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
1414 struct attribute *attr, int idx) 1548 struct attribute *attr, int idx)
1415{ 1549{
@@ -1429,11 +1563,6 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj,
1429 return exists ? attr->mode : 0; 1563 return exists ? attr->mode : 0;
1430} 1564}
1431 1565
1432static struct attribute_group toshiba_attr_group = {
1433 .is_visible = toshiba_sysfs_is_visible,
1434 .attrs = toshiba_attributes,
1435};
1436
1437static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, 1566static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
1438 struct serio *port) 1567 struct serio *port)
1439{ 1568{
@@ -1765,12 +1894,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
1765 dev->eco_supported = 1; 1894 dev->eco_supported = 1;
1766 } 1895 }
1767 1896
1768 ret = toshiba_kbd_illum_status_get(dev, &dummy); 1897 dev->kbd_illum_supported = toshiba_kbd_illum_available(dev);
1769 if (!ret) {
1770 dev->kbd_time = dummy >> HCI_MISC_SHIFT;
1771 dev->kbd_mode = dummy & 0x07;
1772 }
1773 dev->kbd_illum_supported = !ret;
1774 /* 1898 /*
1775 * Only register the LED if KBD illumination is supported 1899 * Only register the LED if KBD illumination is supported
1776 * and the keyboard backlight operation mode is set to FN-Z 1900 * and the keyboard backlight operation mode is set to FN-Z