2605 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for Dell laptop extras4 *5 * Copyright (c) Red Hat <mjg@redhat.com>6 * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com>7 * Copyright (c) 2014 Pali Rohár <pali@kernel.org>8 *9 * Based on documentation in the libsmbios package:10 * Copyright (C) 2005-2014 Dell Inc.11 */12 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt14 15#include <linux/module.h>16#include <linux/kernel.h>17#include <linux/init.h>18#include <linux/platform_device.h>19#include <linux/backlight.h>20#include <linux/err.h>21#include <linux/dmi.h>22#include <linux/io.h>23#include <linux/rfkill.h>24#include <linux/power_supply.h>25#include <linux/sysfs.h>26#include <linux/acpi.h>27#include <linux/mm.h>28#include <linux/i8042.h>29#include <linux/debugfs.h>30#include <linux/seq_file.h>31#include <acpi/battery.h>32#include <acpi/video.h>33#include "dell-rbtn.h"34#include "dell-smbios.h"35 36#include "dell-wmi-privacy.h"37 38struct quirk_entry {39 bool touchpad_led;40 bool kbd_led_not_present;41 bool kbd_led_levels_off_1;42 bool kbd_missing_ac_tag;43 44 bool needs_kbd_timeouts;45 /*46 * Ordered list of timeouts expressed in seconds.47 * The list must end with -148 */49 int kbd_timeouts[];50};51 52static struct quirk_entry *quirks;53 54static struct quirk_entry quirk_dell_vostro_v130 = {55 .touchpad_led = true,56};57 58static int __init dmi_matched(const struct dmi_system_id *dmi)59{60 quirks = dmi->driver_data;61 return 1;62}63 64/*65 * These values come from Windows utility provided by Dell. If any other value66 * is used then BIOS silently set timeout to 0 without any error message.67 */68static struct quirk_entry quirk_dell_xps13_9333 = {69 .needs_kbd_timeouts = true,70 .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },71};72 73static struct quirk_entry quirk_dell_xps13_9370 = {74 .kbd_missing_ac_tag = true,75};76 77static struct quirk_entry quirk_dell_latitude_e6410 = {78 .kbd_led_levels_off_1 = true,79};80 81static struct quirk_entry quirk_dell_inspiron_1012 = {82 .kbd_led_not_present = true,83};84 85static struct quirk_entry quirk_dell_latitude_7520 = {86 .kbd_missing_ac_tag = true,87};88 89static struct platform_driver platform_driver = {90 .driver = {91 .name = "dell-laptop",92 }93};94 95static struct platform_device *platform_device;96static struct backlight_device *dell_backlight_device;97static struct rfkill *wifi_rfkill;98static struct rfkill *bluetooth_rfkill;99static struct rfkill *wwan_rfkill;100static bool force_rfkill;101static bool micmute_led_registered;102static bool mute_led_registered;103 104struct battery_mode_info {105 int token;106 const char *label;107};108 109static const struct battery_mode_info battery_modes[] = {110 { BAT_PRI_AC_MODE_TOKEN, "Trickle" },111 { BAT_EXPRESS_MODE_TOKEN, "Fast" },112 { BAT_STANDARD_MODE_TOKEN, "Standard" },113 { BAT_ADAPTIVE_MODE_TOKEN, "Adaptive" },114 { BAT_CUSTOM_MODE_TOKEN, "Custom" },115};116static u32 battery_supported_modes;117 118module_param(force_rfkill, bool, 0444);119MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");120 121static const struct dmi_system_id dell_device_table[] __initconst = {122 {123 .ident = "Dell laptop",124 .matches = {125 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),126 DMI_MATCH(DMI_CHASSIS_TYPE, "8"),127 },128 },129 {130 .matches = {131 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),132 DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /*Laptop*/133 },134 },135 {136 .matches = {137 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),138 DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /*Notebook*/139 },140 },141 {142 .matches = {143 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),144 DMI_MATCH(DMI_CHASSIS_TYPE, "30"), /*Tablet*/145 },146 },147 {148 .matches = {149 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),150 DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /*Convertible*/151 },152 },153 {154 .matches = {155 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),156 DMI_MATCH(DMI_CHASSIS_TYPE, "32"), /*Detachable*/157 },158 },159 {160 .ident = "Dell Computer Corporation",161 .matches = {162 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),163 DMI_MATCH(DMI_CHASSIS_TYPE, "8"),164 },165 },166 { }167};168MODULE_DEVICE_TABLE(dmi, dell_device_table);169 170static const struct dmi_system_id dell_quirks[] __initconst = {171 {172 .callback = dmi_matched,173 .ident = "Dell Vostro V130",174 .matches = {175 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),176 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V130"),177 },178 .driver_data = &quirk_dell_vostro_v130,179 },180 {181 .callback = dmi_matched,182 .ident = "Dell Vostro V131",183 .matches = {184 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),185 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),186 },187 .driver_data = &quirk_dell_vostro_v130,188 },189 {190 .callback = dmi_matched,191 .ident = "Dell Vostro 3350",192 .matches = {193 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),194 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"),195 },196 .driver_data = &quirk_dell_vostro_v130,197 },198 {199 .callback = dmi_matched,200 .ident = "Dell Vostro 3555",201 .matches = {202 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),203 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3555"),204 },205 .driver_data = &quirk_dell_vostro_v130,206 },207 {208 .callback = dmi_matched,209 .ident = "Dell Inspiron N311z",210 .matches = {211 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),212 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N311z"),213 },214 .driver_data = &quirk_dell_vostro_v130,215 },216 {217 .callback = dmi_matched,218 .ident = "Dell Inspiron M5110",219 .matches = {220 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),221 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron M5110"),222 },223 .driver_data = &quirk_dell_vostro_v130,224 },225 {226 .callback = dmi_matched,227 .ident = "Dell Vostro 3360",228 .matches = {229 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),230 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),231 },232 .driver_data = &quirk_dell_vostro_v130,233 },234 {235 .callback = dmi_matched,236 .ident = "Dell Vostro 3460",237 .matches = {238 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),239 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3460"),240 },241 .driver_data = &quirk_dell_vostro_v130,242 },243 {244 .callback = dmi_matched,245 .ident = "Dell Vostro 3560",246 .matches = {247 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),248 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3560"),249 },250 .driver_data = &quirk_dell_vostro_v130,251 },252 {253 .callback = dmi_matched,254 .ident = "Dell Vostro 3450",255 .matches = {256 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),257 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System Vostro 3450"),258 },259 .driver_data = &quirk_dell_vostro_v130,260 },261 {262 .callback = dmi_matched,263 .ident = "Dell Inspiron 5420",264 .matches = {265 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),266 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"),267 },268 .driver_data = &quirk_dell_vostro_v130,269 },270 {271 .callback = dmi_matched,272 .ident = "Dell Inspiron 5520",273 .matches = {274 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),275 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"),276 },277 .driver_data = &quirk_dell_vostro_v130,278 },279 {280 .callback = dmi_matched,281 .ident = "Dell Inspiron 5720",282 .matches = {283 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),284 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"),285 },286 .driver_data = &quirk_dell_vostro_v130,287 },288 {289 .callback = dmi_matched,290 .ident = "Dell Inspiron 7420",291 .matches = {292 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),293 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"),294 },295 .driver_data = &quirk_dell_vostro_v130,296 },297 {298 .callback = dmi_matched,299 .ident = "Dell Inspiron 7520",300 .matches = {301 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),302 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),303 },304 .driver_data = &quirk_dell_vostro_v130,305 },306 {307 .callback = dmi_matched,308 .ident = "Dell Inspiron 7720",309 .matches = {310 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),311 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),312 },313 .driver_data = &quirk_dell_vostro_v130,314 },315 {316 .callback = dmi_matched,317 .ident = "Dell XPS13 9333",318 .matches = {319 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),320 DMI_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"),321 },322 .driver_data = &quirk_dell_xps13_9333,323 },324 {325 .callback = dmi_matched,326 .ident = "Dell XPS 13 9370",327 .matches = {328 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),329 DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9370"),330 },331 .driver_data = &quirk_dell_xps13_9370,332 },333 {334 .callback = dmi_matched,335 .ident = "Dell Latitude E6410",336 .matches = {337 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),338 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6410"),339 },340 .driver_data = &quirk_dell_latitude_e6410,341 },342 {343 .callback = dmi_matched,344 .ident = "Dell Inspiron 1012",345 .matches = {346 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),347 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),348 },349 .driver_data = &quirk_dell_inspiron_1012,350 },351 {352 .callback = dmi_matched,353 .ident = "Dell Inspiron 1018",354 .matches = {355 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),356 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1018"),357 },358 .driver_data = &quirk_dell_inspiron_1012,359 },360 {361 .callback = dmi_matched,362 .ident = "Dell Latitude 7520",363 .matches = {364 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),365 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 7520"),366 },367 .driver_data = &quirk_dell_latitude_7520,368 },369 { }370};371 372/* -1 is a sentinel value, telling us to use token->value */373#define USE_TVAL ((u32) -1)374static int dell_send_request_for_tokenid(struct calling_interface_buffer *buffer,375 u16 class, u16 select, u16 tokenid,376 u32 val)377{378 struct calling_interface_token *token;379 380 token = dell_smbios_find_token(tokenid);381 if (!token)382 return -ENODEV;383 384 if (val == USE_TVAL)385 val = token->value;386 387 dell_fill_request(buffer, token->location, val, 0, 0);388 return dell_send_request(buffer, class, select);389}390 391static inline int dell_set_std_token_value(struct calling_interface_buffer *buffer,392 u16 tokenid, u32 value)393{394 return dell_send_request_for_tokenid(buffer, CLASS_TOKEN_WRITE,395 SELECT_TOKEN_STD, tokenid, value);396}397 398/*399 * Derived from information in smbios-wireless-ctl:400 *401 * cbSelect 17, Value 11402 *403 * Return Wireless Info404 * cbArg1, byte0 = 0x00405 *406 * cbRes1 Standard return codes (0, -1, -2)407 * cbRes2 Info bit flags:408 *409 * 0 Hardware switch supported (1)410 * 1 WiFi locator supported (1)411 * 2 WLAN supported (1)412 * 3 Bluetooth (BT) supported (1)413 * 4 WWAN supported (1)414 * 5 Wireless KBD supported (1)415 * 6 Uw b supported (1)416 * 7 WiGig supported (1)417 * 8 WLAN installed (1)418 * 9 BT installed (1)419 * 10 WWAN installed (1)420 * 11 Uw b installed (1)421 * 12 WiGig installed (1)422 * 13-15 Reserved (0)423 * 16 Hardware (HW) switch is On (1)424 * 17 WLAN disabled (1)425 * 18 BT disabled (1)426 * 19 WWAN disabled (1)427 * 20 Uw b disabled (1)428 * 21 WiGig disabled (1)429 * 20-31 Reserved (0)430 *431 * cbRes3 NVRAM size in bytes432 * cbRes4, byte 0 NVRAM format version number433 *434 *435 * Set QuickSet Radio Disable Flag436 * cbArg1, byte0 = 0x01437 * cbArg1, byte1438 * Radio ID value:439 * 0 Radio Status440 * 1 WLAN ID441 * 2 BT ID442 * 3 WWAN ID443 * 4 UWB ID444 * 5 WIGIG ID445 * cbArg1, byte2 Flag bits:446 * 0 QuickSet disables radio (1)447 * 1-7 Reserved (0)448 *449 * cbRes1 Standard return codes (0, -1, -2)450 * cbRes2 QuickSet (QS) radio disable bit map:451 * 0 QS disables WLAN452 * 1 QS disables BT453 * 2 QS disables WWAN454 * 3 QS disables UWB455 * 4 QS disables WIGIG456 * 5-31 Reserved (0)457 *458 * Wireless Switch Configuration459 * cbArg1, byte0 = 0x02460 *461 * cbArg1, byte1462 * Subcommand:463 * 0 Get config464 * 1 Set config465 * 2 Set WiFi locator enable/disable466 * cbArg1,byte2467 * Switch settings (if byte 1==1):468 * 0 WLAN sw itch control (1)469 * 1 BT sw itch control (1)470 * 2 WWAN sw itch control (1)471 * 3 UWB sw itch control (1)472 * 4 WiGig sw itch control (1)473 * 5-7 Reserved (0)474 * cbArg1, byte2 Enable bits (if byte 1==2):475 * 0 Enable WiFi locator (1)476 *477 * cbRes1 Standard return codes (0, -1, -2)478 * cbRes2 QuickSet radio disable bit map:479 * 0 WLAN controlled by sw itch (1)480 * 1 BT controlled by sw itch (1)481 * 2 WWAN controlled by sw itch (1)482 * 3 UWB controlled by sw itch (1)483 * 4 WiGig controlled by sw itch (1)484 * 5-6 Reserved (0)485 * 7 Wireless sw itch config locked (1)486 * 8 WiFi locator enabled (1)487 * 9-14 Reserved (0)488 * 15 WiFi locator setting locked (1)489 * 16-31 Reserved (0)490 *491 * Read Local Config Data (LCD)492 * cbArg1, byte0 = 0x10493 * cbArg1, byte1 NVRAM index low byte494 * cbArg1, byte2 NVRAM index high byte495 * cbRes1 Standard return codes (0, -1, -2)496 * cbRes2 4 bytes read from LCD[index]497 * cbRes3 4 bytes read from LCD[index+4]498 * cbRes4 4 bytes read from LCD[index+8]499 *500 * Write Local Config Data (LCD)501 * cbArg1, byte0 = 0x11502 * cbArg1, byte1 NVRAM index low byte503 * cbArg1, byte2 NVRAM index high byte504 * cbArg2 4 bytes to w rite at LCD[index]505 * cbArg3 4 bytes to w rite at LCD[index+4]506 * cbArg4 4 bytes to w rite at LCD[index+8]507 * cbRes1 Standard return codes (0, -1, -2)508 *509 * Populate Local Config Data from NVRAM510 * cbArg1, byte0 = 0x12511 * cbRes1 Standard return codes (0, -1, -2)512 *513 * Commit Local Config Data to NVRAM514 * cbArg1, byte0 = 0x13515 * cbRes1 Standard return codes (0, -1, -2)516 */517 518static int dell_rfkill_set(void *data, bool blocked)519{520 int disable = blocked ? 1 : 0;521 unsigned long radio = (unsigned long)data;522 int hwswitch_bit = (unsigned long)data - 1;523 struct calling_interface_buffer buffer;524 int hwswitch;525 int status;526 int ret;527 528 dell_fill_request(&buffer, 0, 0, 0, 0);529 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);530 if (ret)531 return ret;532 status = buffer.output[1];533 534 dell_fill_request(&buffer, 0x2, 0, 0, 0);535 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);536 if (ret)537 return ret;538 hwswitch = buffer.output[1];539 540 /* If the hardware switch controls this radio, and the hardware541 switch is disabled, always disable the radio */542 if (ret == 0 && (hwswitch & BIT(hwswitch_bit)) &&543 (status & BIT(0)) && !(status & BIT(16)))544 disable = 1;545 546 dell_fill_request(&buffer, 1 | (radio<<8) | (disable << 16), 0, 0, 0);547 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);548 return ret;549}550 551static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,552 int status)553{554 if (status & BIT(0)) {555 /* Has hw-switch, sync sw_state to BIOS */556 struct calling_interface_buffer buffer;557 int block = rfkill_blocked(rfkill);558 dell_fill_request(&buffer,559 1 | (radio << 8) | (block << 16), 0, 0, 0);560 dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);561 } else {562 /* No hw-switch, sync BIOS state to sw_state */563 rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));564 }565}566 567static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,568 int status, int hwswitch)569{570 if (hwswitch & (BIT(radio - 1)))571 rfkill_set_hw_state(rfkill, !(status & BIT(16)));572}573 574static void dell_rfkill_query(struct rfkill *rfkill, void *data)575{576 int radio = ((unsigned long)data & 0xF);577 struct calling_interface_buffer buffer;578 int hwswitch;579 int status;580 int ret;581 582 dell_fill_request(&buffer, 0, 0, 0, 0);583 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);584 status = buffer.output[1];585 586 if (ret != 0 || !(status & BIT(0))) {587 return;588 }589 590 dell_fill_request(&buffer, 0x2, 0, 0, 0);591 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);592 hwswitch = buffer.output[1];593 594 if (ret != 0)595 return;596 597 dell_rfkill_update_hw_state(rfkill, radio, status, hwswitch);598}599 600static const struct rfkill_ops dell_rfkill_ops = {601 .set_block = dell_rfkill_set,602 .query = dell_rfkill_query,603};604 605static struct dentry *dell_laptop_dir;606 607static int dell_debugfs_show(struct seq_file *s, void *data)608{609 struct calling_interface_buffer buffer;610 int hwswitch_state;611 int hwswitch_ret;612 int status;613 int ret;614 615 dell_fill_request(&buffer, 0, 0, 0, 0);616 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);617 if (ret)618 return ret;619 status = buffer.output[1];620 621 dell_fill_request(&buffer, 0x2, 0, 0, 0);622 hwswitch_ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);623 if (hwswitch_ret)624 return hwswitch_ret;625 hwswitch_state = buffer.output[1];626 627 seq_printf(s, "return:\t%d\n", ret);628 seq_printf(s, "status:\t0x%X\n", status);629 seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n",630 status & BIT(0));631 seq_printf(s, "Bit 1 : Wifi locator supported: %lu\n",632 (status & BIT(1)) >> 1);633 seq_printf(s, "Bit 2 : Wifi is supported: %lu\n",634 (status & BIT(2)) >> 2);635 seq_printf(s, "Bit 3 : Bluetooth is supported: %lu\n",636 (status & BIT(3)) >> 3);637 seq_printf(s, "Bit 4 : WWAN is supported: %lu\n",638 (status & BIT(4)) >> 4);639 seq_printf(s, "Bit 5 : Wireless keyboard supported: %lu\n",640 (status & BIT(5)) >> 5);641 seq_printf(s, "Bit 6 : UWB supported: %lu\n",642 (status & BIT(6)) >> 6);643 seq_printf(s, "Bit 7 : WiGig supported: %lu\n",644 (status & BIT(7)) >> 7);645 seq_printf(s, "Bit 8 : Wifi is installed: %lu\n",646 (status & BIT(8)) >> 8);647 seq_printf(s, "Bit 9 : Bluetooth is installed: %lu\n",648 (status & BIT(9)) >> 9);649 seq_printf(s, "Bit 10: WWAN is installed: %lu\n",650 (status & BIT(10)) >> 10);651 seq_printf(s, "Bit 11: UWB installed: %lu\n",652 (status & BIT(11)) >> 11);653 seq_printf(s, "Bit 12: WiGig installed: %lu\n",654 (status & BIT(12)) >> 12);655 656 seq_printf(s, "Bit 16: Hardware switch is on: %lu\n",657 (status & BIT(16)) >> 16);658 seq_printf(s, "Bit 17: Wifi is blocked: %lu\n",659 (status & BIT(17)) >> 17);660 seq_printf(s, "Bit 18: Bluetooth is blocked: %lu\n",661 (status & BIT(18)) >> 18);662 seq_printf(s, "Bit 19: WWAN is blocked: %lu\n",663 (status & BIT(19)) >> 19);664 seq_printf(s, "Bit 20: UWB is blocked: %lu\n",665 (status & BIT(20)) >> 20);666 seq_printf(s, "Bit 21: WiGig is blocked: %lu\n",667 (status & BIT(21)) >> 21);668 669 seq_printf(s, "\nhwswitch_return:\t%d\n", hwswitch_ret);670 seq_printf(s, "hwswitch_state:\t0x%X\n", hwswitch_state);671 seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n",672 hwswitch_state & BIT(0));673 seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n",674 (hwswitch_state & BIT(1)) >> 1);675 seq_printf(s, "Bit 2 : WWAN controlled by switch: %lu\n",676 (hwswitch_state & BIT(2)) >> 2);677 seq_printf(s, "Bit 3 : UWB controlled by switch: %lu\n",678 (hwswitch_state & BIT(3)) >> 3);679 seq_printf(s, "Bit 4 : WiGig controlled by switch: %lu\n",680 (hwswitch_state & BIT(4)) >> 4);681 seq_printf(s, "Bit 7 : Wireless switch config locked: %lu\n",682 (hwswitch_state & BIT(7)) >> 7);683 seq_printf(s, "Bit 8 : Wifi locator enabled: %lu\n",684 (hwswitch_state & BIT(8)) >> 8);685 seq_printf(s, "Bit 15: Wifi locator setting locked: %lu\n",686 (hwswitch_state & BIT(15)) >> 15);687 688 return 0;689}690DEFINE_SHOW_ATTRIBUTE(dell_debugfs);691 692static void dell_update_rfkill(struct work_struct *ignored)693{694 struct calling_interface_buffer buffer;695 int hwswitch = 0;696 int status;697 int ret;698 699 dell_fill_request(&buffer, 0, 0, 0, 0);700 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);701 status = buffer.output[1];702 703 if (ret != 0)704 return;705 706 dell_fill_request(&buffer, 0x2, 0, 0, 0);707 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);708 709 if (ret == 0 && (status & BIT(0)))710 hwswitch = buffer.output[1];711 712 if (wifi_rfkill) {713 dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch);714 dell_rfkill_update_sw_state(wifi_rfkill, 1, status);715 }716 if (bluetooth_rfkill) {717 dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status,718 hwswitch);719 dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status);720 }721 if (wwan_rfkill) {722 dell_rfkill_update_hw_state(wwan_rfkill, 3, status, hwswitch);723 dell_rfkill_update_sw_state(wwan_rfkill, 3, status);724 }725}726static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);727 728static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,729 struct serio *port)730{731 static bool extended;732 733 if (str & I8042_STR_AUXDATA)734 return false;735 736 if (unlikely(data == 0xe0)) {737 extended = true;738 return false;739 } else if (unlikely(extended)) {740 switch (data) {741 case 0x8:742 schedule_delayed_work(&dell_rfkill_work,743 round_jiffies_relative(HZ / 4));744 break;745 }746 extended = false;747 }748 749 return false;750}751 752static int (*dell_rbtn_notifier_register_func)(struct notifier_block *);753static int (*dell_rbtn_notifier_unregister_func)(struct notifier_block *);754 755static int dell_laptop_rbtn_notifier_call(struct notifier_block *nb,756 unsigned long action, void *data)757{758 schedule_delayed_work(&dell_rfkill_work, 0);759 return NOTIFY_OK;760}761 762static struct notifier_block dell_laptop_rbtn_notifier = {763 .notifier_call = dell_laptop_rbtn_notifier_call,764};765 766static int __init dell_setup_rfkill(void)767{768 struct calling_interface_buffer buffer;769 int status, ret, whitelisted;770 const char *product;771 772 /*773 * rfkill support causes trouble on various models, mostly Inspirons.774 * So we whitelist certain series, and don't support rfkill on others.775 */776 whitelisted = 0;777 product = dmi_get_system_info(DMI_PRODUCT_NAME);778 if (product && (strncmp(product, "Latitude", 8) == 0 ||779 strncmp(product, "Precision", 9) == 0))780 whitelisted = 1;781 if (!force_rfkill && !whitelisted)782 return 0;783 784 dell_fill_request(&buffer, 0, 0, 0, 0);785 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);786 status = buffer.output[1];787 788 /* dell wireless info smbios call is not supported */789 if (ret != 0)790 return 0;791 792 /* rfkill is only tested on laptops with a hwswitch */793 if (!(status & BIT(0)) && !force_rfkill)794 return 0;795 796 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {797 wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,798 RFKILL_TYPE_WLAN,799 &dell_rfkill_ops, (void *) 1);800 if (!wifi_rfkill) {801 ret = -ENOMEM;802 goto err_wifi;803 }804 ret = rfkill_register(wifi_rfkill);805 if (ret)806 goto err_wifi;807 }808 809 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {810 bluetooth_rfkill = rfkill_alloc("dell-bluetooth",811 &platform_device->dev,812 RFKILL_TYPE_BLUETOOTH,813 &dell_rfkill_ops, (void *) 2);814 if (!bluetooth_rfkill) {815 ret = -ENOMEM;816 goto err_bluetooth;817 }818 ret = rfkill_register(bluetooth_rfkill);819 if (ret)820 goto err_bluetooth;821 }822 823 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {824 wwan_rfkill = rfkill_alloc("dell-wwan",825 &platform_device->dev,826 RFKILL_TYPE_WWAN,827 &dell_rfkill_ops, (void *) 3);828 if (!wwan_rfkill) {829 ret = -ENOMEM;830 goto err_wwan;831 }832 ret = rfkill_register(wwan_rfkill);833 if (ret)834 goto err_wwan;835 }836 837 /*838 * Dell Airplane Mode Switch driver (dell-rbtn) supports ACPI devices839 * which can receive events from HW slider switch.840 *841 * Dell SMBIOS on whitelisted models supports controlling radio devices842 * but does not support receiving HW button switch events. We can use843 * i8042 filter hook function to receive keyboard data and handle844 * keycode for HW button.845 *846 * So if it is possible we will use Dell Airplane Mode Switch ACPI847 * driver for receiving HW events and Dell SMBIOS for setting rfkill848 * states. If ACPI driver or device is not available we will fallback to849 * i8042 filter hook function.850 *851 * To prevent duplicate rfkill devices which control and do same thing,852 * dell-rbtn driver will automatically remove its own rfkill devices853 * once function dell_rbtn_notifier_register() is called.854 */855 856 dell_rbtn_notifier_register_func =857 symbol_request(dell_rbtn_notifier_register);858 if (dell_rbtn_notifier_register_func) {859 dell_rbtn_notifier_unregister_func =860 symbol_request(dell_rbtn_notifier_unregister);861 if (!dell_rbtn_notifier_unregister_func) {862 symbol_put(dell_rbtn_notifier_register);863 dell_rbtn_notifier_register_func = NULL;864 }865 }866 867 if (dell_rbtn_notifier_register_func) {868 ret = dell_rbtn_notifier_register_func(869 &dell_laptop_rbtn_notifier);870 symbol_put(dell_rbtn_notifier_register);871 dell_rbtn_notifier_register_func = NULL;872 if (ret != 0) {873 symbol_put(dell_rbtn_notifier_unregister);874 dell_rbtn_notifier_unregister_func = NULL;875 }876 } else {877 pr_info("Symbols from dell-rbtn acpi driver are not available\n");878 ret = -ENODEV;879 }880 881 if (ret == 0) {882 pr_info("Using dell-rbtn acpi driver for receiving events\n");883 } else if (ret != -ENODEV) {884 pr_warn("Unable to register dell rbtn notifier\n");885 goto err_filter;886 } else {887 ret = i8042_install_filter(dell_laptop_i8042_filter);888 if (ret) {889 pr_warn("Unable to install key filter\n");890 goto err_filter;891 }892 pr_info("Using i8042 filter function for receiving events\n");893 }894 895 return 0;896err_filter:897 if (wwan_rfkill)898 rfkill_unregister(wwan_rfkill);899err_wwan:900 rfkill_destroy(wwan_rfkill);901 if (bluetooth_rfkill)902 rfkill_unregister(bluetooth_rfkill);903err_bluetooth:904 rfkill_destroy(bluetooth_rfkill);905 if (wifi_rfkill)906 rfkill_unregister(wifi_rfkill);907err_wifi:908 rfkill_destroy(wifi_rfkill);909 910 return ret;911}912 913static void dell_cleanup_rfkill(void)914{915 if (dell_rbtn_notifier_unregister_func) {916 dell_rbtn_notifier_unregister_func(&dell_laptop_rbtn_notifier);917 symbol_put(dell_rbtn_notifier_unregister);918 dell_rbtn_notifier_unregister_func = NULL;919 } else {920 i8042_remove_filter(dell_laptop_i8042_filter);921 }922 cancel_delayed_work_sync(&dell_rfkill_work);923 if (wifi_rfkill) {924 rfkill_unregister(wifi_rfkill);925 rfkill_destroy(wifi_rfkill);926 }927 if (bluetooth_rfkill) {928 rfkill_unregister(bluetooth_rfkill);929 rfkill_destroy(bluetooth_rfkill);930 }931 if (wwan_rfkill) {932 rfkill_unregister(wwan_rfkill);933 rfkill_destroy(wwan_rfkill);934 }935}936 937static int dell_send_intensity(struct backlight_device *bd)938{939 struct calling_interface_buffer buffer;940 u16 select;941 942 select = power_supply_is_system_supplied() > 0 ?943 SELECT_TOKEN_AC : SELECT_TOKEN_BAT;944 return dell_send_request_for_tokenid(&buffer, CLASS_TOKEN_WRITE,945 select, BRIGHTNESS_TOKEN, bd->props.brightness);946}947 948static int dell_get_intensity(struct backlight_device *bd)949{950 struct calling_interface_buffer buffer;951 int ret;952 u16 select;953 954 select = power_supply_is_system_supplied() > 0 ?955 SELECT_TOKEN_AC : SELECT_TOKEN_BAT;956 ret = dell_send_request_for_tokenid(&buffer, CLASS_TOKEN_READ,957 select, BRIGHTNESS_TOKEN, 0);958 if (ret == 0)959 ret = buffer.output[1];960 961 return ret;962}963 964static const struct backlight_ops dell_ops = {965 .get_brightness = dell_get_intensity,966 .update_status = dell_send_intensity,967};968 969static void touchpad_led_on(void)970{971 int command = 0x97;972 char data = 1;973 i8042_command(&data, command | 1 << 12);974}975 976static void touchpad_led_off(void)977{978 int command = 0x97;979 char data = 2;980 i8042_command(&data, command | 1 << 12);981}982 983static void touchpad_led_set(struct led_classdev *led_cdev,984 enum led_brightness value)985{986 if (value > 0)987 touchpad_led_on();988 else989 touchpad_led_off();990}991 992static struct led_classdev touchpad_led = {993 .name = "dell-laptop::touchpad",994 .brightness_set = touchpad_led_set,995 .flags = LED_CORE_SUSPENDRESUME,996};997 998static int __init touchpad_led_init(struct device *dev)999{1000 return led_classdev_register(dev, &touchpad_led);1001}1002 1003static void touchpad_led_exit(void)1004{1005 led_classdev_unregister(&touchpad_led);1006}1007 1008/*1009 * Derived from information in smbios-keyboard-ctl:1010 *1011 * cbClass 41012 * cbSelect 111013 * Keyboard illumination1014 * cbArg1 determines the function to be performed1015 *1016 * cbArg1 0x0 = Get Feature Information1017 * cbRES1 Standard return codes (0, -1, -2)1018 * cbRES2, word0 Bitmap of user-selectable modes1019 * bit 0 Always off (All systems)1020 * bit 1 Always on (Travis ATG, Siberia)1021 * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG)1022 * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off1023 * bit 4 Auto: Input-activity-based On; input-activity based Off1024 * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off1025 * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off1026 * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off1027 * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off1028 * bits 9-15 Reserved for future use1029 * cbRES2, byte2 Reserved for future use1030 * cbRES2, byte3 Keyboard illumination type1031 * 0 Reserved1032 * 1 Tasklight1033 * 2 Backlight1034 * 3-255 Reserved for future use1035 * cbRES3, byte0 Supported auto keyboard illumination trigger bitmap.1036 * bit 0 Any keystroke1037 * bit 1 Touchpad activity1038 * bit 2 Pointing stick1039 * bit 3 Any mouse1040 * bits 4-7 Reserved for future use1041 * cbRES3, byte1 Supported timeout unit bitmap1042 * bit 0 Seconds1043 * bit 1 Minutes1044 * bit 2 Hours1045 * bit 3 Days1046 * bits 4-7 Reserved for future use1047 * cbRES3, byte2 Number of keyboard light brightness levels1048 * cbRES4, byte0 Maximum acceptable seconds value (0 if seconds not supported).1049 * cbRES4, byte1 Maximum acceptable minutes value (0 if minutes not supported).1050 * cbRES4, byte2 Maximum acceptable hours value (0 if hours not supported).1051 * cbRES4, byte3 Maximum acceptable days value (0 if days not supported)1052 *1053 * cbArg1 0x1 = Get Current State1054 * cbRES1 Standard return codes (0, -1, -2)1055 * cbRES2, word0 Bitmap of current mode state1056 * bit 0 Always off (All systems)1057 * bit 1 Always on (Travis ATG, Siberia)1058 * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG)1059 * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off1060 * bit 4 Auto: Input-activity-based On; input-activity based Off1061 * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off1062 * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off1063 * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off1064 * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off1065 * bits 9-15 Reserved for future use1066 * Note: Only One bit can be set1067 * cbRES2, byte2 Currently active auto keyboard illumination triggers.1068 * bit 0 Any keystroke1069 * bit 1 Touchpad activity1070 * bit 2 Pointing stick1071 * bit 3 Any mouse1072 * bits 4-7 Reserved for future use1073 * cbRES2, byte3 Current Timeout on battery1074 * bits 7:6 Timeout units indicator:1075 * 00b Seconds1076 * 01b Minutes1077 * 10b Hours1078 * 11b Days1079 * bits 5:0 Timeout value (0-63) in sec/min/hr/day1080 * NOTE: A value of 0 means always on (no timeout) if any bits of RES3 byte1081 * are set upon return from the [Get feature information] call.1082 * cbRES3, byte0 Current setting of ALS value that turns the light on or off.1083 * cbRES3, byte1 Current ALS reading1084 * cbRES3, byte2 Current keyboard light level.1085 * cbRES3, byte3 Current timeout on AC Power1086 * bits 7:6 Timeout units indicator:1087 * 00b Seconds1088 * 01b Minutes1089 * 10b Hours1090 * 11b Days1091 * Bits 5:0 Timeout value (0-63) in sec/min/hr/day1092 * NOTE: A value of 0 means always on (no timeout) if any bits of RES3 byte21093 * are set upon return from the upon return from the [Get Feature information] call.1094 *1095 * cbArg1 0x2 = Set New State1096 * cbRES1 Standard return codes (0, -1, -2)1097 * cbArg2, word0 Bitmap of current mode state1098 * bit 0 Always off (All systems)1099 * bit 1 Always on (Travis ATG, Siberia)1100 * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG)1101 * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off1102 * bit 4 Auto: Input-activity-based On; input-activity based Off1103 * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off1104 * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off1105 * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off1106 * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off1107 * bits 9-15 Reserved for future use1108 * Note: Only One bit can be set1109 * cbArg2, byte2 Desired auto keyboard illumination triggers. Must remain inactive to allow1110 * keyboard to turn off automatically.1111 * bit 0 Any keystroke1112 * bit 1 Touchpad activity1113 * bit 2 Pointing stick1114 * bit 3 Any mouse1115 * bits 4-7 Reserved for future use1116 * cbArg2, byte3 Desired Timeout on battery1117 * bits 7:6 Timeout units indicator:1118 * 00b Seconds1119 * 01b Minutes1120 * 10b Hours1121 * 11b Days1122 * bits 5:0 Timeout value (0-63) in sec/min/hr/day1123 * cbArg3, byte0 Desired setting of ALS value that turns the light on or off.1124 * cbArg3, byte2 Desired keyboard light level.1125 * cbArg3, byte3 Desired Timeout on AC power1126 * bits 7:6 Timeout units indicator:1127 * 00b Seconds1128 * 01b Minutes1129 * 10b Hours1130 * 11b Days1131 * bits 5:0 Timeout value (0-63) in sec/min/hr/day1132 */1133 1134 1135enum kbd_timeout_unit {1136 KBD_TIMEOUT_SECONDS = 0,1137 KBD_TIMEOUT_MINUTES,1138 KBD_TIMEOUT_HOURS,1139 KBD_TIMEOUT_DAYS,1140};1141 1142enum kbd_mode_bit {1143 KBD_MODE_BIT_OFF = 0,1144 KBD_MODE_BIT_ON,1145 KBD_MODE_BIT_ALS,1146 KBD_MODE_BIT_TRIGGER_ALS,1147 KBD_MODE_BIT_TRIGGER,1148 KBD_MODE_BIT_TRIGGER_25,1149 KBD_MODE_BIT_TRIGGER_50,1150 KBD_MODE_BIT_TRIGGER_75,1151 KBD_MODE_BIT_TRIGGER_100,1152};1153 1154#define kbd_is_als_mode_bit(bit) \1155 ((bit) == KBD_MODE_BIT_ALS || (bit) == KBD_MODE_BIT_TRIGGER_ALS)1156#define kbd_is_trigger_mode_bit(bit) \1157 ((bit) >= KBD_MODE_BIT_TRIGGER_ALS && (bit) <= KBD_MODE_BIT_TRIGGER_100)1158#define kbd_is_level_mode_bit(bit) \1159 ((bit) >= KBD_MODE_BIT_TRIGGER_25 && (bit) <= KBD_MODE_BIT_TRIGGER_100)1160 1161struct kbd_info {1162 u16 modes;1163 u8 type;1164 u8 triggers;1165 u8 levels;1166 u8 seconds;1167 u8 minutes;1168 u8 hours;1169 u8 days;1170};1171 1172struct kbd_state {1173 u8 mode_bit;1174 u8 triggers;1175 u8 timeout_value;1176 u8 timeout_unit;1177 u8 timeout_value_ac;1178 u8 timeout_unit_ac;1179 u8 als_setting;1180 u8 als_value;1181 u8 level;1182};1183 1184static const int kbd_tokens[] = {1185 KBD_LED_OFF_TOKEN,1186 KBD_LED_AUTO_25_TOKEN,1187 KBD_LED_AUTO_50_TOKEN,1188 KBD_LED_AUTO_75_TOKEN,1189 KBD_LED_AUTO_100_TOKEN,1190 KBD_LED_ON_TOKEN,1191};1192 1193static u16 kbd_token_bits;1194 1195static struct kbd_info kbd_info;1196static bool kbd_als_supported;1197static bool kbd_triggers_supported;1198static bool kbd_timeout_ac_supported;1199 1200static u8 kbd_mode_levels[16];1201static int kbd_mode_levels_count;1202 1203static u8 kbd_previous_level;1204static u8 kbd_previous_mode_bit;1205 1206static bool kbd_led_present;1207static DEFINE_MUTEX(kbd_led_mutex);1208static enum led_brightness kbd_led_level;1209 1210/*1211 * NOTE: there are three ways to set the keyboard backlight level.1212 * First, via kbd_state.mode_bit (assigning KBD_MODE_BIT_TRIGGER_* value).1213 * Second, via kbd_state.level (assigning numerical value <= kbd_info.levels).1214 * Third, via SMBIOS tokens (KBD_LED_* in kbd_tokens)1215 *1216 * There are laptops which support only one of these methods. If we want to1217 * support as many machines as possible we need to implement all three methods.1218 * The first two methods use the kbd_state structure. The third uses SMBIOS1219 * tokens. If kbd_info.levels == 0, the machine does not support setting the1220 * keyboard backlight level via kbd_state.level.1221 */1222 1223static int kbd_get_info(struct kbd_info *info)1224{1225 struct calling_interface_buffer buffer;1226 u8 units;1227 int ret;1228 1229 dell_fill_request(&buffer, 0, 0, 0, 0);1230 ret = dell_send_request(&buffer,1231 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);1232 if (ret)1233 return ret;1234 1235 info->modes = buffer.output[1] & 0xFFFF;1236 info->type = (buffer.output[1] >> 24) & 0xFF;1237 info->triggers = buffer.output[2] & 0xFF;1238 units = (buffer.output[2] >> 8) & 0xFF;1239 info->levels = (buffer.output[2] >> 16) & 0xFF;1240 1241 if (quirks && quirks->kbd_led_levels_off_1 && info->levels)1242 info->levels--;1243 1244 if (units & BIT(0))1245 info->seconds = (buffer.output[3] >> 0) & 0xFF;1246 if (units & BIT(1))1247 info->minutes = (buffer.output[3] >> 8) & 0xFF;1248 if (units & BIT(2))1249 info->hours = (buffer.output[3] >> 16) & 0xFF;1250 if (units & BIT(3))1251 info->days = (buffer.output[3] >> 24) & 0xFF;1252 1253 return ret;1254}1255 1256static unsigned int kbd_get_max_level(void)1257{1258 if (kbd_info.levels != 0)1259 return kbd_info.levels;1260 if (kbd_mode_levels_count > 0)1261 return kbd_mode_levels_count - 1;1262 return 0;1263}1264 1265static int kbd_get_level(struct kbd_state *state)1266{1267 int i;1268 1269 if (kbd_info.levels != 0)1270 return state->level;1271 1272 if (kbd_mode_levels_count > 0) {1273 for (i = 0; i < kbd_mode_levels_count; ++i)1274 if (kbd_mode_levels[i] == state->mode_bit)1275 return i;1276 return 0;1277 }1278 1279 return -EINVAL;1280}1281 1282static int kbd_set_level(struct kbd_state *state, u8 level)1283{1284 if (kbd_info.levels != 0) {1285 if (level != 0)1286 kbd_previous_level = level;1287 if (state->level == level)1288 return 0;1289 state->level = level;1290 if (level != 0 && state->mode_bit == KBD_MODE_BIT_OFF)1291 state->mode_bit = kbd_previous_mode_bit;1292 else if (level == 0 && state->mode_bit != KBD_MODE_BIT_OFF) {1293 kbd_previous_mode_bit = state->mode_bit;1294 state->mode_bit = KBD_MODE_BIT_OFF;1295 }1296 return 0;1297 }1298 1299 if (kbd_mode_levels_count > 0 && level < kbd_mode_levels_count) {1300 if (level != 0)1301 kbd_previous_level = level;1302 state->mode_bit = kbd_mode_levels[level];1303 return 0;1304 }1305 1306 return -EINVAL;1307}1308 1309static int kbd_get_state(struct kbd_state *state)1310{1311 struct calling_interface_buffer buffer;1312 int ret;1313 1314 dell_fill_request(&buffer, 0x1, 0, 0, 0);1315 ret = dell_send_request(&buffer,1316 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);1317 if (ret)1318 return ret;1319 1320 state->mode_bit = ffs(buffer.output[1] & 0xFFFF);1321 if (state->mode_bit != 0)1322 state->mode_bit--;1323 1324 state->triggers = (buffer.output[1] >> 16) & 0xFF;1325 state->timeout_value = (buffer.output[1] >> 24) & 0x3F;1326 state->timeout_unit = (buffer.output[1] >> 30) & 0x3;1327 state->als_setting = buffer.output[2] & 0xFF;1328 state->als_value = (buffer.output[2] >> 8) & 0xFF;1329 state->level = (buffer.output[2] >> 16) & 0xFF;1330 state->timeout_value_ac = (buffer.output[2] >> 24) & 0x3F;1331 state->timeout_unit_ac = (buffer.output[2] >> 30) & 0x3;1332 1333 return ret;1334}1335 1336static int kbd_set_state(struct kbd_state *state)1337{1338 struct calling_interface_buffer buffer;1339 int ret;1340 u32 input1;1341 u32 input2;1342 1343 input1 = BIT(state->mode_bit) & 0xFFFF;1344 input1 |= (state->triggers & 0xFF) << 16;1345 input1 |= (state->timeout_value & 0x3F) << 24;1346 input1 |= (state->timeout_unit & 0x3) << 30;1347 input2 = state->als_setting & 0xFF;1348 input2 |= (state->level & 0xFF) << 16;1349 input2 |= (state->timeout_value_ac & 0x3F) << 24;1350 input2 |= (state->timeout_unit_ac & 0x3) << 30;1351 dell_fill_request(&buffer, 0x2, input1, input2, 0);1352 ret = dell_send_request(&buffer,1353 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);1354 1355 return ret;1356}1357 1358static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old)1359{1360 int ret;1361 1362 ret = kbd_set_state(state);1363 if (ret == 0)1364 return 0;1365 1366 /*1367 * When setting the new state fails,try to restore the previous one.1368 * This is needed on some machines where BIOS sets a default state when1369 * setting a new state fails. This default state could be all off.1370 */1371 1372 if (kbd_set_state(old))1373 pr_err("Setting old previous keyboard state failed\n");1374 1375 return ret;1376}1377 1378static int kbd_set_token_bit(u8 bit)1379{1380 struct calling_interface_buffer buffer;1381 1382 if (bit >= ARRAY_SIZE(kbd_tokens))1383 return -EINVAL;1384 1385 return dell_set_std_token_value(&buffer, kbd_tokens[bit], USE_TVAL);1386}1387 1388static int kbd_get_token_bit(u8 bit)1389{1390 struct calling_interface_buffer buffer;1391 struct calling_interface_token *token;1392 int ret;1393 int val;1394 1395 if (bit >= ARRAY_SIZE(kbd_tokens))1396 return -EINVAL;1397 1398 token = dell_smbios_find_token(kbd_tokens[bit]);1399 if (!token)1400 return -EINVAL;1401 1402 dell_fill_request(&buffer, token->location, 0, 0, 0);1403 ret = dell_send_request(&buffer, CLASS_TOKEN_READ, SELECT_TOKEN_STD);1404 if (ret)1405 return ret;1406 1407 val = buffer.output[1];1408 return (val == token->value);1409}1410 1411static int kbd_get_first_active_token_bit(void)1412{1413 int i;1414 int ret;1415 1416 for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) {1417 ret = kbd_get_token_bit(i);1418 if (ret == 1)1419 return i;1420 }1421 1422 return ret;1423}1424 1425static int kbd_get_valid_token_counts(void)1426{1427 return hweight16(kbd_token_bits);1428}1429 1430static inline int kbd_init_info(void)1431{1432 struct kbd_state state;1433 int ret;1434 int i;1435 1436 ret = kbd_get_info(&kbd_info);1437 if (ret)1438 return ret;1439 1440 /* NOTE: Old models without KBD_LED_AC_TOKEN token supports only one1441 * timeout value which is shared for both battery and AC power1442 * settings. So do not try to set AC values on old models.1443 */1444 if ((quirks && quirks->kbd_missing_ac_tag) ||1445 dell_smbios_find_token(KBD_LED_AC_TOKEN))1446 kbd_timeout_ac_supported = true;1447 1448 kbd_get_state(&state);1449 1450 /* NOTE: timeout value is stored in 6 bits so max value is 63 */1451 if (kbd_info.seconds > 63)1452 kbd_info.seconds = 63;1453 if (kbd_info.minutes > 63)1454 kbd_info.minutes = 63;1455 if (kbd_info.hours > 63)1456 kbd_info.hours = 63;1457 if (kbd_info.days > 63)1458 kbd_info.days = 63;1459 1460 /* NOTE: On tested machines ON mode did not work and caused1461 * problems (turned backlight off) so do not use it1462 */1463 kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON);1464 1465 kbd_previous_level = kbd_get_level(&state);1466 kbd_previous_mode_bit = state.mode_bit;1467 1468 if (kbd_previous_level == 0 && kbd_get_max_level() != 0)1469 kbd_previous_level = 1;1470 1471 if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) {1472 kbd_previous_mode_bit =1473 ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF));1474 if (kbd_previous_mode_bit != 0)1475 kbd_previous_mode_bit--;1476 }1477 1478 if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) |1479 BIT(KBD_MODE_BIT_TRIGGER_ALS)))1480 kbd_als_supported = true;1481 1482 if (kbd_info.modes & (1483 BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) |1484 BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) |1485 BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100)1486 ))1487 kbd_triggers_supported = true;1488 1489 /* kbd_mode_levels[0] is reserved, see below */1490 for (i = 0; i < 16; ++i)1491 if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes))1492 kbd_mode_levels[1 + kbd_mode_levels_count++] = i;1493 1494 /*1495 * Find the first supported mode and assign to kbd_mode_levels[0].1496 * This should be 0 (off), but we cannot depend on the BIOS to1497 * support 0.1498 */1499 if (kbd_mode_levels_count > 0) {1500 for (i = 0; i < 16; ++i) {1501 if (BIT(i) & kbd_info.modes) {1502 kbd_mode_levels[0] = i;1503 break;1504 }1505 }1506 kbd_mode_levels_count++;1507 }1508 1509 return 0;1510 1511}1512 1513static inline void __init kbd_init_tokens(void)1514{1515 int i;1516 1517 for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i)1518 if (dell_smbios_find_token(kbd_tokens[i]))1519 kbd_token_bits |= BIT(i);1520}1521 1522static void __init kbd_init(void)1523{1524 int ret;1525 1526 if (quirks && quirks->kbd_led_not_present)1527 return;1528 1529 ret = kbd_init_info();1530 kbd_init_tokens();1531 1532 /*1533 * Only supports keyboard backlight when it has at least two modes.1534 */1535 if ((ret == 0 && (kbd_info.levels != 0 || kbd_mode_levels_count >= 2))1536 || kbd_get_valid_token_counts() >= 2)1537 kbd_led_present = true;1538}1539 1540static ssize_t kbd_led_timeout_store(struct device *dev,1541 struct device_attribute *attr,1542 const char *buf, size_t count)1543{1544 struct kbd_state new_state;1545 struct kbd_state state;1546 bool convert;1547 int value;1548 int ret;1549 char ch;1550 u8 unit;1551 int i;1552 1553 ret = sscanf(buf, "%d %c", &value, &ch);1554 if (ret < 1)1555 return -EINVAL;1556 else if (ret == 1)1557 ch = 's';1558 1559 if (value < 0)1560 return -EINVAL;1561 1562 convert = false;1563 1564 switch (ch) {1565 case 's':1566 if (value > kbd_info.seconds)1567 convert = true;1568 unit = KBD_TIMEOUT_SECONDS;1569 break;1570 case 'm':1571 if (value > kbd_info.minutes)1572 convert = true;1573 unit = KBD_TIMEOUT_MINUTES;1574 break;1575 case 'h':1576 if (value > kbd_info.hours)1577 convert = true;1578 unit = KBD_TIMEOUT_HOURS;1579 break;1580 case 'd':1581 if (value > kbd_info.days)1582 convert = true;1583 unit = KBD_TIMEOUT_DAYS;1584 break;1585 default:1586 return -EINVAL;1587 }1588 1589 if (quirks && quirks->needs_kbd_timeouts)1590 convert = true;1591 1592 if (convert) {1593 /* Convert value from current units to seconds */1594 switch (unit) {1595 case KBD_TIMEOUT_DAYS:1596 value *= 24;1597 fallthrough;1598 case KBD_TIMEOUT_HOURS:1599 value *= 60;1600 fallthrough;1601 case KBD_TIMEOUT_MINUTES:1602 value *= 60;1603 unit = KBD_TIMEOUT_SECONDS;1604 }1605 1606 if (quirks && quirks->needs_kbd_timeouts) {1607 for (i = 0; quirks->kbd_timeouts[i] != -1; i++) {1608 if (value <= quirks->kbd_timeouts[i]) {1609 value = quirks->kbd_timeouts[i];1610 break;1611 }1612 }1613 }1614 1615 if (value <= kbd_info.seconds && kbd_info.seconds) {1616 unit = KBD_TIMEOUT_SECONDS;1617 } else if (value / 60 <= kbd_info.minutes && kbd_info.minutes) {1618 value /= 60;1619 unit = KBD_TIMEOUT_MINUTES;1620 } else if (value / (60 * 60) <= kbd_info.hours && kbd_info.hours) {1621 value /= (60 * 60);1622 unit = KBD_TIMEOUT_HOURS;1623 } else if (value / (60 * 60 * 24) <= kbd_info.days && kbd_info.days) {1624 value /= (60 * 60 * 24);1625 unit = KBD_TIMEOUT_DAYS;1626 } else {1627 return -EINVAL;1628 }1629 }1630 1631 mutex_lock(&kbd_led_mutex);1632 1633 ret = kbd_get_state(&state);1634 if (ret)1635 goto out;1636 1637 new_state = state;1638 1639 if (kbd_timeout_ac_supported && power_supply_is_system_supplied() > 0) {1640 new_state.timeout_value_ac = value;1641 new_state.timeout_unit_ac = unit;1642 } else {1643 new_state.timeout_value = value;1644 new_state.timeout_unit = unit;1645 }1646 1647 ret = kbd_set_state_safe(&new_state, &state);1648 if (ret)1649 goto out;1650 1651 ret = count;1652out:1653 mutex_unlock(&kbd_led_mutex);1654 return ret;1655}1656 1657static ssize_t kbd_led_timeout_show(struct device *dev,1658 struct device_attribute *attr, char *buf)1659{1660 struct kbd_state state;1661 int value;1662 int ret;1663 int len;1664 u8 unit;1665 1666 ret = kbd_get_state(&state);1667 if (ret)1668 return ret;1669 1670 if (kbd_timeout_ac_supported && power_supply_is_system_supplied() > 0) {1671 value = state.timeout_value_ac;1672 unit = state.timeout_unit_ac;1673 } else {1674 value = state.timeout_value;1675 unit = state.timeout_unit;1676 }1677 1678 len = sprintf(buf, "%d", value);1679 1680 switch (unit) {1681 case KBD_TIMEOUT_SECONDS:1682 return len + sprintf(buf+len, "s\n");1683 case KBD_TIMEOUT_MINUTES:1684 return len + sprintf(buf+len, "m\n");1685 case KBD_TIMEOUT_HOURS:1686 return len + sprintf(buf+len, "h\n");1687 case KBD_TIMEOUT_DAYS:1688 return len + sprintf(buf+len, "d\n");1689 default:1690 return -EINVAL;1691 }1692 1693 return len;1694}1695 1696static DEVICE_ATTR(stop_timeout, S_IRUGO | S_IWUSR,1697 kbd_led_timeout_show, kbd_led_timeout_store);1698 1699static const char * const kbd_led_triggers[] = {1700 "keyboard",1701 "touchpad",1702 /*"trackstick"*/ NULL, /* NOTE: trackstick is just alias for touchpad */1703 "mouse",1704};1705 1706static ssize_t kbd_led_triggers_store(struct device *dev,1707 struct device_attribute *attr,1708 const char *buf, size_t count)1709{1710 struct kbd_state new_state;1711 struct kbd_state state;1712 bool triggers_enabled = false;1713 int trigger_bit = -1;1714 char trigger[21];1715 int i, ret;1716 1717 ret = sscanf(buf, "%20s", trigger);1718 if (ret != 1)1719 return -EINVAL;1720 1721 if (trigger[0] != '+' && trigger[0] != '-')1722 return -EINVAL;1723 1724 mutex_lock(&kbd_led_mutex);1725 1726 ret = kbd_get_state(&state);1727 if (ret)1728 goto out;1729 1730 if (kbd_triggers_supported)1731 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);1732 1733 if (kbd_triggers_supported) {1734 for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) {1735 if (!(kbd_info.triggers & BIT(i)))1736 continue;1737 if (!kbd_led_triggers[i])1738 continue;1739 if (strcmp(trigger+1, kbd_led_triggers[i]) != 0)1740 continue;1741 if (trigger[0] == '+' &&1742 triggers_enabled && (state.triggers & BIT(i))) {1743 ret = count;1744 goto out;1745 }1746 if (trigger[0] == '-' &&1747 (!triggers_enabled || !(state.triggers & BIT(i)))) {1748 ret = count;1749 goto out;1750 }1751 trigger_bit = i;1752 break;1753 }1754 }1755 1756 if (trigger_bit == -1) {1757 ret = -EINVAL;1758 goto out;1759 }1760 1761 new_state = state;1762 if (trigger[0] == '+')1763 new_state.triggers |= BIT(trigger_bit);1764 else {1765 new_state.triggers &= ~BIT(trigger_bit);1766 /*1767 * NOTE: trackstick bit (2) must be disabled when1768 * disabling touchpad bit (1), otherwise touchpad1769 * bit (1) will not be disabled1770 */1771 if (trigger_bit == 1)1772 new_state.triggers &= ~BIT(2);1773 }1774 if ((kbd_info.triggers & new_state.triggers) !=1775 new_state.triggers) {1776 ret = -EINVAL;1777 goto out;1778 }1779 if (new_state.triggers && !triggers_enabled) {1780 new_state.mode_bit = KBD_MODE_BIT_TRIGGER;1781 kbd_set_level(&new_state, kbd_previous_level);1782 } else if (new_state.triggers == 0) {1783 kbd_set_level(&new_state, 0);1784 }1785 if (!(kbd_info.modes & BIT(new_state.mode_bit))) {1786 ret = -EINVAL;1787 goto out;1788 }1789 ret = kbd_set_state_safe(&new_state, &state);1790 if (ret)1791 goto out;1792 if (new_state.mode_bit != KBD_MODE_BIT_OFF)1793 kbd_previous_mode_bit = new_state.mode_bit;1794 ret = count;1795out:1796 mutex_unlock(&kbd_led_mutex);1797 return ret;1798}1799 1800static ssize_t kbd_led_triggers_show(struct device *dev,1801 struct device_attribute *attr, char *buf)1802{1803 struct kbd_state state;1804 bool triggers_enabled;1805 int level, i, ret;1806 int len = 0;1807 1808 ret = kbd_get_state(&state);1809 if (ret)1810 return ret;1811 1812 len = 0;1813 1814 if (kbd_triggers_supported) {1815 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);1816 level = kbd_get_level(&state);1817 for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) {1818 if (!(kbd_info.triggers & BIT(i)))1819 continue;1820 if (!kbd_led_triggers[i])1821 continue;1822 if ((triggers_enabled || level <= 0) &&1823 (state.triggers & BIT(i)))1824 buf[len++] = '+';1825 else1826 buf[len++] = '-';1827 len += sprintf(buf+len, "%s ", kbd_led_triggers[i]);1828 }1829 }1830 1831 if (len)1832 buf[len - 1] = '\n';1833 1834 return len;1835}1836 1837static DEVICE_ATTR(start_triggers, S_IRUGO | S_IWUSR,1838 kbd_led_triggers_show, kbd_led_triggers_store);1839 1840static ssize_t kbd_led_als_enabled_store(struct device *dev,1841 struct device_attribute *attr,1842 const char *buf, size_t count)1843{1844 struct kbd_state new_state;1845 struct kbd_state state;1846 bool triggers_enabled = false;1847 int enable;1848 int ret;1849 1850 ret = kstrtoint(buf, 0, &enable);1851 if (ret)1852 return ret;1853 1854 mutex_lock(&kbd_led_mutex);1855 1856 ret = kbd_get_state(&state);1857 if (ret)1858 goto out;1859 1860 if (enable == kbd_is_als_mode_bit(state.mode_bit)) {1861 ret = count;1862 goto out;1863 }1864 1865 new_state = state;1866 1867 if (kbd_triggers_supported)1868 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);1869 1870 if (enable) {1871 if (triggers_enabled)1872 new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS;1873 else1874 new_state.mode_bit = KBD_MODE_BIT_ALS;1875 } else {1876 if (triggers_enabled) {1877 new_state.mode_bit = KBD_MODE_BIT_TRIGGER;1878 kbd_set_level(&new_state, kbd_previous_level);1879 } else {1880 new_state.mode_bit = KBD_MODE_BIT_ON;1881 }1882 }1883 if (!(kbd_info.modes & BIT(new_state.mode_bit))) {1884 ret = -EINVAL;1885 goto out;1886 }1887 1888 ret = kbd_set_state_safe(&new_state, &state);1889 if (ret)1890 goto out;1891 kbd_previous_mode_bit = new_state.mode_bit;1892 1893 ret = count;1894out:1895 mutex_unlock(&kbd_led_mutex);1896 return ret;1897}1898 1899static ssize_t kbd_led_als_enabled_show(struct device *dev,1900 struct device_attribute *attr,1901 char *buf)1902{1903 struct kbd_state state;1904 bool enabled = false;1905 int ret;1906 1907 ret = kbd_get_state(&state);1908 if (ret)1909 return ret;1910 enabled = kbd_is_als_mode_bit(state.mode_bit);1911 1912 return sprintf(buf, "%d\n", enabled ? 1 : 0);1913}1914 1915static DEVICE_ATTR(als_enabled, S_IRUGO | S_IWUSR,1916 kbd_led_als_enabled_show, kbd_led_als_enabled_store);1917 1918static ssize_t kbd_led_als_setting_store(struct device *dev,1919 struct device_attribute *attr,1920 const char *buf, size_t count)1921{1922 struct kbd_state state;1923 struct kbd_state new_state;1924 u8 setting;1925 int ret;1926 1927 ret = kstrtou8(buf, 10, &setting);1928 if (ret)1929 return ret;1930 1931 mutex_lock(&kbd_led_mutex);1932 1933 ret = kbd_get_state(&state);1934 if (ret)1935 goto out;1936 1937 new_state = state;1938 new_state.als_setting = setting;1939 1940 ret = kbd_set_state_safe(&new_state, &state);1941 if (ret)1942 goto out;1943 1944 ret = count;1945out:1946 mutex_unlock(&kbd_led_mutex);1947 return ret;1948}1949 1950static ssize_t kbd_led_als_setting_show(struct device *dev,1951 struct device_attribute *attr,1952 char *buf)1953{1954 struct kbd_state state;1955 int ret;1956 1957 ret = kbd_get_state(&state);1958 if (ret)1959 return ret;1960 1961 return sprintf(buf, "%d\n", state.als_setting);1962}1963 1964static DEVICE_ATTR(als_setting, S_IRUGO | S_IWUSR,1965 kbd_led_als_setting_show, kbd_led_als_setting_store);1966 1967static struct attribute *kbd_led_attrs[] = {1968 &dev_attr_stop_timeout.attr,1969 &dev_attr_start_triggers.attr,1970 NULL,1971};1972 1973static const struct attribute_group kbd_led_group = {1974 .attrs = kbd_led_attrs,1975};1976 1977static struct attribute *kbd_led_als_attrs[] = {1978 &dev_attr_als_enabled.attr,1979 &dev_attr_als_setting.attr,1980 NULL,1981};1982 1983static const struct attribute_group kbd_led_als_group = {1984 .attrs = kbd_led_als_attrs,1985};1986 1987static const struct attribute_group *kbd_led_groups[] = {1988 &kbd_led_group,1989 &kbd_led_als_group,1990 NULL,1991};1992 1993static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)1994{1995 int ret;1996 u16 num;1997 struct kbd_state state;1998 1999 if (kbd_get_max_level()) {2000 ret = kbd_get_state(&state);2001 if (ret)2002 return 0;2003 ret = kbd_get_level(&state);2004 if (ret < 0)2005 return 0;2006 return ret;2007 }2008 2009 if (kbd_get_valid_token_counts()) {2010 ret = kbd_get_first_active_token_bit();2011 if (ret < 0)2012 return 0;2013 for (num = kbd_token_bits; num != 0 && ret > 0; --ret)2014 num &= num - 1; /* clear the first bit set */2015 if (num == 0)2016 return 0;2017 return ffs(num) - 1;2018 }2019 2020 pr_warn("Keyboard brightness level control not supported\n");2021 return 0;2022}2023 2024static int kbd_led_level_set(struct led_classdev *led_cdev,2025 enum led_brightness value)2026{2027 enum led_brightness new_value = value;2028 struct kbd_state state;2029 struct kbd_state new_state;2030 u16 num;2031 int ret;2032 2033 mutex_lock(&kbd_led_mutex);2034 2035 if (kbd_get_max_level()) {2036 ret = kbd_get_state(&state);2037 if (ret)2038 goto out;2039 new_state = state;2040 ret = kbd_set_level(&new_state, value);2041 if (ret)2042 goto out;2043 ret = kbd_set_state_safe(&new_state, &state);2044 } else if (kbd_get_valid_token_counts()) {2045 for (num = kbd_token_bits; num != 0 && value > 0; --value)2046 num &= num - 1; /* clear the first bit set */2047 if (num == 0)2048 ret = 0;2049 else2050 ret = kbd_set_token_bit(ffs(num) - 1);2051 } else {2052 pr_warn("Keyboard brightness level control not supported\n");2053 ret = -ENXIO;2054 }2055 2056out:2057 if (ret == 0)2058 kbd_led_level = new_value;2059 2060 mutex_unlock(&kbd_led_mutex);2061 return ret;2062}2063 2064static struct led_classdev kbd_led = {2065 .name = "dell::kbd_backlight",2066 .flags = LED_BRIGHT_HW_CHANGED,2067 .brightness_set_blocking = kbd_led_level_set,2068 .brightness_get = kbd_led_level_get,2069 .groups = kbd_led_groups,2070};2071 2072static int __init kbd_led_init(struct device *dev)2073{2074 int ret;2075 2076 kbd_init();2077 if (!kbd_led_present)2078 return -ENODEV;2079 if (!kbd_als_supported)2080 kbd_led_groups[1] = NULL;2081 kbd_led.max_brightness = kbd_get_max_level();2082 if (!kbd_led.max_brightness) {2083 kbd_led.max_brightness = kbd_get_valid_token_counts();2084 if (kbd_led.max_brightness)2085 kbd_led.max_brightness--;2086 }2087 2088 kbd_led_level = kbd_led_level_get(NULL);2089 2090 ret = led_classdev_register(dev, &kbd_led);2091 if (ret)2092 kbd_led_present = false;2093 2094 return ret;2095}2096 2097static void brightness_set_exit(struct led_classdev *led_cdev,2098 enum led_brightness value)2099{2100 /* Don't change backlight level on exit */2101};2102 2103static void kbd_led_exit(void)2104{2105 if (!kbd_led_present)2106 return;2107 kbd_led.brightness_set = brightness_set_exit;2108 led_classdev_unregister(&kbd_led);2109}2110 2111static int dell_laptop_notifier_call(struct notifier_block *nb,2112 unsigned long action, void *data)2113{2114 bool changed = false;2115 enum led_brightness new_kbd_led_level;2116 2117 switch (action) {2118 case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:2119 if (!kbd_led_present)2120 break;2121 2122 mutex_lock(&kbd_led_mutex);2123 new_kbd_led_level = kbd_led_level_get(&kbd_led);2124 if (kbd_led_level != new_kbd_led_level) {2125 kbd_led_level = new_kbd_led_level;2126 changed = true;2127 }2128 mutex_unlock(&kbd_led_mutex);2129 2130 if (changed)2131 led_classdev_notify_brightness_hw_changed(&kbd_led,2132 kbd_led_level);2133 break;2134 }2135 2136 return NOTIFY_OK;2137}2138 2139static struct notifier_block dell_laptop_notifier = {2140 .notifier_call = dell_laptop_notifier_call,2141};2142 2143static int micmute_led_set(struct led_classdev *led_cdev,2144 enum led_brightness brightness)2145{2146 struct calling_interface_buffer buffer;2147 u32 tokenid;2148 2149 tokenid = brightness == LED_OFF ?2150 GLOBAL_MIC_MUTE_DISABLE : GLOBAL_MIC_MUTE_ENABLE;2151 return dell_set_std_token_value(&buffer, tokenid, USE_TVAL);2152}2153 2154static struct led_classdev micmute_led_cdev = {2155 .name = "platform::micmute",2156 .max_brightness = 1,2157 .brightness_set_blocking = micmute_led_set,2158 .default_trigger = "audio-micmute",2159};2160 2161static int mute_led_set(struct led_classdev *led_cdev,2162 enum led_brightness brightness)2163{2164 struct calling_interface_buffer buffer;2165 u32 tokenid;2166 2167 tokenid = brightness == LED_OFF ?2168 GLOBAL_MUTE_DISABLE : GLOBAL_MUTE_ENABLE;2169 return dell_set_std_token_value(&buffer, tokenid, USE_TVAL);2170}2171 2172static struct led_classdev mute_led_cdev = {2173 .name = "platform::mute",2174 .max_brightness = 1,2175 .brightness_set_blocking = mute_led_set,2176 .default_trigger = "audio-mute",2177};2178 2179static int dell_battery_set_mode(const u16 tokenid)2180{2181 struct calling_interface_buffer buffer;2182 2183 return dell_set_std_token_value(&buffer, tokenid, USE_TVAL);2184}2185 2186static int dell_battery_read(const u16 tokenid)2187{2188 struct calling_interface_buffer buffer;2189 int err;2190 2191 err = dell_send_request_for_tokenid(&buffer, CLASS_TOKEN_READ,2192 SELECT_TOKEN_STD, tokenid, 0);2193 if (err)2194 return err;2195 2196 if (buffer.output[1] > INT_MAX)2197 return -EIO;2198 2199 return buffer.output[1];2200}2201 2202static bool dell_battery_mode_is_active(const u16 tokenid)2203{2204 struct calling_interface_token *token;2205 int ret;2206 2207 ret = dell_battery_read(tokenid);2208 if (ret < 0)2209 return false;2210 2211 token = dell_smbios_find_token(tokenid);2212 /* token's already verified by dell_battery_read() */2213 2214 return token->value == (u16) ret;2215}2216 2217/*2218 * The rules: the minimum start charging value is 50%. The maximum2219 * start charging value is 95%. The minimum end charging value is2220 * 55%. The maximum end charging value is 100%. And finally, there2221 * has to be at least a 5% difference between start & end values.2222 */2223#define CHARGE_START_MIN 502224#define CHARGE_START_MAX 952225#define CHARGE_END_MIN 552226#define CHARGE_END_MAX 1002227#define CHARGE_MIN_DIFF 52228 2229static int dell_battery_set_custom_charge_start(int start)2230{2231 struct calling_interface_buffer buffer;2232 int end;2233 2234 start = clamp(start, CHARGE_START_MIN, CHARGE_START_MAX);2235 end = dell_battery_read(BAT_CUSTOM_CHARGE_END);2236 if (end < 0)2237 return end;2238 if ((end - start) < CHARGE_MIN_DIFF)2239 start = end - CHARGE_MIN_DIFF;2240 2241 return dell_set_std_token_value(&buffer, BAT_CUSTOM_CHARGE_START,2242 start);2243}2244 2245static int dell_battery_set_custom_charge_end(int end)2246{2247 struct calling_interface_buffer buffer;2248 int start;2249 2250 end = clamp(end, CHARGE_END_MIN, CHARGE_END_MAX);2251 start = dell_battery_read(BAT_CUSTOM_CHARGE_START);2252 if (start < 0)2253 return start;2254 if ((end - start) < CHARGE_MIN_DIFF)2255 end = start + CHARGE_MIN_DIFF;2256 2257 return dell_set_std_token_value(&buffer, BAT_CUSTOM_CHARGE_END, end);2258}2259 2260static ssize_t charge_types_show(struct device *dev,2261 struct device_attribute *attr,2262 char *buf)2263{2264 ssize_t count = 0;2265 int i;2266 2267 for (i = 0; i < ARRAY_SIZE(battery_modes); i++) {2268 bool active;2269 2270 if (!(battery_supported_modes & BIT(i)))2271 continue;2272 2273 active = dell_battery_mode_is_active(battery_modes[i].token);2274 count += sysfs_emit_at(buf, count, active ? "[%s] " : "%s ",2275 battery_modes[i].label);2276 }2277 2278 /* convert the last space to a newline */2279 if (count > 0)2280 count--;2281 count += sysfs_emit_at(buf, count, "\n");2282 2283 return count;2284}2285 2286static ssize_t charge_types_store(struct device *dev,2287 struct device_attribute *attr,2288 const char *buf, size_t size)2289{2290 bool matched = false;2291 int err, i;2292 2293 for (i = 0; i < ARRAY_SIZE(battery_modes); i++) {2294 if (!(battery_supported_modes & BIT(i)))2295 continue;2296 2297 if (sysfs_streq(battery_modes[i].label, buf)) {2298 matched = true;2299 break;2300 }2301 }2302 if (!matched)2303 return -EINVAL;2304 2305 err = dell_battery_set_mode(battery_modes[i].token);2306 if (err)2307 return err;2308 2309 return size;2310}2311 2312static ssize_t charge_control_start_threshold_show(struct device *dev,2313 struct device_attribute *attr,2314 char *buf)2315{2316 int start;2317 2318 start = dell_battery_read(BAT_CUSTOM_CHARGE_START);2319 if (start < 0)2320 return start;2321 2322 if (start > CHARGE_START_MAX)2323 return -EIO;2324 2325 return sysfs_emit(buf, "%d\n", start);2326}2327 2328static ssize_t charge_control_start_threshold_store(struct device *dev,2329 struct device_attribute *attr,2330 const char *buf, size_t size)2331{2332 int ret, start;2333 2334 ret = kstrtoint(buf, 10, &start);2335 if (ret)2336 return ret;2337 if (start < 0 || start > 100)2338 return -EINVAL;2339 2340 ret = dell_battery_set_custom_charge_start(start);2341 if (ret)2342 return ret;2343 2344 return size;2345}2346 2347static ssize_t charge_control_end_threshold_show(struct device *dev,2348 struct device_attribute *attr,2349 char *buf)2350{2351 int end;2352 2353 end = dell_battery_read(BAT_CUSTOM_CHARGE_END);2354 if (end < 0)2355 return end;2356 2357 if (end > CHARGE_END_MAX)2358 return -EIO;2359 2360 return sysfs_emit(buf, "%d\n", end);2361}2362 2363static ssize_t charge_control_end_threshold_store(struct device *dev,2364 struct device_attribute *attr,2365 const char *buf, size_t size)2366{2367 int ret, end;2368 2369 ret = kstrtouint(buf, 10, &end);2370 if (ret)2371 return ret;2372 if (end < 0 || end > 100)2373 return -EINVAL;2374 2375 ret = dell_battery_set_custom_charge_end(end);2376 if (ret)2377 return ret;2378 2379 return size;2380}2381 2382static DEVICE_ATTR_RW(charge_control_start_threshold);2383static DEVICE_ATTR_RW(charge_control_end_threshold);2384static DEVICE_ATTR_RW(charge_types);2385 2386static struct attribute *dell_battery_attrs[] = {2387 &dev_attr_charge_control_start_threshold.attr,2388 &dev_attr_charge_control_end_threshold.attr,2389 &dev_attr_charge_types.attr,2390 NULL,2391};2392ATTRIBUTE_GROUPS(dell_battery);2393 2394static bool dell_battery_supported(struct power_supply *battery)2395{2396 /* We currently only support the primary battery */2397 return strcmp(battery->desc->name, "BAT0") == 0;2398}2399 2400static int dell_battery_add(struct power_supply *battery,2401 struct acpi_battery_hook *hook)2402{2403 /* Return 0 instead of an error to avoid being unloaded */2404 if (!dell_battery_supported(battery))2405 return 0;2406 2407 return device_add_groups(&battery->dev, dell_battery_groups);2408}2409 2410static int dell_battery_remove(struct power_supply *battery,2411 struct acpi_battery_hook *hook)2412{2413 if (!dell_battery_supported(battery))2414 return 0;2415 2416 device_remove_groups(&battery->dev, dell_battery_groups);2417 return 0;2418}2419 2420static struct acpi_battery_hook dell_battery_hook = {2421 .add_battery = dell_battery_add,2422 .remove_battery = dell_battery_remove,2423 .name = "Dell Primary Battery Extension",2424};2425 2426static u32 __init battery_get_supported_modes(void)2427{2428 u32 modes = 0;2429 int i;2430 2431 for (i = 0; i < ARRAY_SIZE(battery_modes); i++) {2432 if (dell_smbios_find_token(battery_modes[i].token))2433 modes |= BIT(i);2434 }2435 2436 return modes;2437}2438 2439static void __init dell_battery_init(struct device *dev)2440{2441 battery_supported_modes = battery_get_supported_modes();2442 2443 if (battery_supported_modes != 0)2444 battery_hook_register(&dell_battery_hook);2445}2446 2447static void dell_battery_exit(void)2448{2449 if (battery_supported_modes != 0)2450 battery_hook_unregister(&dell_battery_hook);2451}2452 2453static int __init dell_init(void)2454{2455 struct calling_interface_buffer buffer;2456 int max_intensity = 0;2457 int ret;2458 2459 if (!dmi_check_system(dell_device_table))2460 return -ENODEV;2461 2462 quirks = NULL;2463 /* find if this machine support other functions */2464 dmi_check_system(dell_quirks);2465 2466 ret = platform_driver_register(&platform_driver);2467 if (ret)2468 goto fail_platform_driver;2469 platform_device = platform_device_alloc("dell-laptop", PLATFORM_DEVID_NONE);2470 if (!platform_device) {2471 ret = -ENOMEM;2472 goto fail_platform_device1;2473 }2474 ret = platform_device_add(platform_device);2475 if (ret)2476 goto fail_platform_device2;2477 2478 ret = dell_setup_rfkill();2479 2480 if (ret) {2481 pr_warn("Unable to setup rfkill\n");2482 goto fail_rfkill;2483 }2484 2485 if (quirks && quirks->touchpad_led)2486 touchpad_led_init(&platform_device->dev);2487 2488 kbd_led_init(&platform_device->dev);2489 dell_battery_init(&platform_device->dev);2490 2491 dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);2492 debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,2493 &dell_debugfs_fops);2494 2495 dell_laptop_register_notifier(&dell_laptop_notifier);2496 2497 if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) &&2498 dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE) &&2499 !dell_privacy_has_mic_mute()) {2500 ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev);2501 if (ret < 0)2502 goto fail_led;2503 micmute_led_registered = true;2504 }2505 2506 if (dell_smbios_find_token(GLOBAL_MUTE_DISABLE) &&2507 dell_smbios_find_token(GLOBAL_MUTE_ENABLE)) {2508 ret = led_classdev_register(&platform_device->dev, &mute_led_cdev);2509 if (ret < 0)2510 goto fail_backlight;2511 mute_led_registered = true;2512 }2513 2514 if (acpi_video_get_backlight_type() != acpi_backlight_vendor)2515 return 0;2516 2517 ret = dell_send_request_for_tokenid(&buffer, CLASS_TOKEN_READ,2518 SELECT_TOKEN_AC, BRIGHTNESS_TOKEN, 0);2519 if (ret == 0)2520 max_intensity = buffer.output[3];2521 2522 if (max_intensity) {2523 struct backlight_properties props;2524 memset(&props, 0, sizeof(struct backlight_properties));2525 props.type = BACKLIGHT_PLATFORM;2526 props.max_brightness = max_intensity;2527 dell_backlight_device = backlight_device_register("dell_backlight",2528 &platform_device->dev,2529 NULL,2530 &dell_ops,2531 &props);2532 2533 if (IS_ERR(dell_backlight_device)) {2534 ret = PTR_ERR(dell_backlight_device);2535 dell_backlight_device = NULL;2536 goto fail_backlight;2537 }2538 2539 dell_backlight_device->props.brightness =2540 dell_get_intensity(dell_backlight_device);2541 if (dell_backlight_device->props.brightness < 0) {2542 ret = dell_backlight_device->props.brightness;2543 goto fail_get_brightness;2544 }2545 backlight_update_status(dell_backlight_device);2546 }2547 2548 return 0;2549 2550fail_get_brightness:2551 backlight_device_unregister(dell_backlight_device);2552fail_backlight:2553 if (micmute_led_registered)2554 led_classdev_unregister(&micmute_led_cdev);2555 if (mute_led_registered)2556 led_classdev_unregister(&mute_led_cdev);2557fail_led:2558 dell_battery_exit();2559 dell_cleanup_rfkill();2560fail_rfkill:2561 platform_device_del(platform_device);2562fail_platform_device2:2563 platform_device_put(platform_device);2564fail_platform_device1:2565 platform_driver_unregister(&platform_driver);2566fail_platform_driver:2567 return ret;2568}2569 2570static void __exit dell_exit(void)2571{2572 dell_laptop_unregister_notifier(&dell_laptop_notifier);2573 debugfs_remove_recursive(dell_laptop_dir);2574 if (quirks && quirks->touchpad_led)2575 touchpad_led_exit();2576 kbd_led_exit();2577 dell_battery_exit();2578 backlight_device_unregister(dell_backlight_device);2579 if (micmute_led_registered)2580 led_classdev_unregister(&micmute_led_cdev);2581 if (mute_led_registered)2582 led_classdev_unregister(&mute_led_cdev);2583 dell_cleanup_rfkill();2584 if (platform_device) {2585 platform_device_unregister(platform_device);2586 platform_driver_unregister(&platform_driver);2587 }2588}2589 2590/* dell-rbtn.c driver export functions which will not work correctly (and could2591 * cause kernel crash) if they are called before dell-rbtn.c init code. This is2592 * not problem when dell-rbtn.c is compiled as external module. When both files2593 * (dell-rbtn.c and dell-laptop.c) are compiled statically into kernel, then we2594 * need to ensure that dell_init() will be called after initializing dell-rbtn.2595 * This can be achieved by late_initcall() instead module_init().2596 */2597late_initcall(dell_init);2598module_exit(dell_exit);2599 2600MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");2601MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");2602MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");2603MODULE_DESCRIPTION("Dell laptop driver");2604MODULE_LICENSE("GPL");2605