brintos

brintos / linux-shallow public Read only

0
0
Text · 65.8 KiB · 5671bd0 Raw
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