0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0014
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 #include <linux/init.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/backlight.h>
0020 #include <linux/err.h>
0021 #include <linux/dmi.h>
0022 #include <linux/io.h>
0023 #include <linux/rfkill.h>
0024 #include <linux/power_supply.h>
0025 #include <linux/acpi.h>
0026 #include <linux/mm.h>
0027 #include <linux/i8042.h>
0028 #include <linux/debugfs.h>
0029 #include <linux/seq_file.h>
0030 #include <acpi/video.h>
0031 #include "dell-rbtn.h"
0032 #include "dell-smbios.h"
0033
0034 #include "dell-wmi-privacy.h"
0035
0036 struct quirk_entry {
0037 bool touchpad_led;
0038 bool kbd_led_not_present;
0039 bool kbd_led_levels_off_1;
0040 bool kbd_missing_ac_tag;
0041
0042 bool needs_kbd_timeouts;
0043
0044
0045
0046
0047 int kbd_timeouts[];
0048 };
0049
0050 static struct quirk_entry *quirks;
0051
0052 static struct quirk_entry quirk_dell_vostro_v130 = {
0053 .touchpad_led = true,
0054 };
0055
0056 static int __init dmi_matched(const struct dmi_system_id *dmi)
0057 {
0058 quirks = dmi->driver_data;
0059 return 1;
0060 }
0061
0062
0063
0064
0065
0066 static struct quirk_entry quirk_dell_xps13_9333 = {
0067 .needs_kbd_timeouts = true,
0068 .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
0069 };
0070
0071 static struct quirk_entry quirk_dell_xps13_9370 = {
0072 .kbd_missing_ac_tag = true,
0073 };
0074
0075 static struct quirk_entry quirk_dell_latitude_e6410 = {
0076 .kbd_led_levels_off_1 = true,
0077 };
0078
0079 static struct quirk_entry quirk_dell_inspiron_1012 = {
0080 .kbd_led_not_present = true,
0081 };
0082
0083 static struct quirk_entry quirk_dell_latitude_7520 = {
0084 .kbd_missing_ac_tag = true,
0085 };
0086
0087 static struct platform_driver platform_driver = {
0088 .driver = {
0089 .name = "dell-laptop",
0090 }
0091 };
0092
0093 static struct platform_device *platform_device;
0094 static struct backlight_device *dell_backlight_device;
0095 static struct rfkill *wifi_rfkill;
0096 static struct rfkill *bluetooth_rfkill;
0097 static struct rfkill *wwan_rfkill;
0098 static bool force_rfkill;
0099 static bool micmute_led_registered;
0100
0101 module_param(force_rfkill, bool, 0444);
0102 MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
0103
0104 static const struct dmi_system_id dell_device_table[] __initconst = {
0105 {
0106 .ident = "Dell laptop",
0107 .matches = {
0108 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0109 DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
0110 },
0111 },
0112 {
0113 .matches = {
0114 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0115 DMI_MATCH(DMI_CHASSIS_TYPE, "9"),
0116 },
0117 },
0118 {
0119 .matches = {
0120 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0121 DMI_MATCH(DMI_CHASSIS_TYPE, "10"),
0122 },
0123 },
0124 {
0125 .matches = {
0126 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0127 DMI_MATCH(DMI_CHASSIS_TYPE, "30"),
0128 },
0129 },
0130 {
0131 .matches = {
0132 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0133 DMI_MATCH(DMI_CHASSIS_TYPE, "31"),
0134 },
0135 },
0136 {
0137 .matches = {
0138 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0139 DMI_MATCH(DMI_CHASSIS_TYPE, "32"),
0140 },
0141 },
0142 {
0143 .ident = "Dell Computer Corporation",
0144 .matches = {
0145 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
0146 DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
0147 },
0148 },
0149 { }
0150 };
0151 MODULE_DEVICE_TABLE(dmi, dell_device_table);
0152
0153 static const struct dmi_system_id dell_quirks[] __initconst = {
0154 {
0155 .callback = dmi_matched,
0156 .ident = "Dell Vostro V130",
0157 .matches = {
0158 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0159 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V130"),
0160 },
0161 .driver_data = &quirk_dell_vostro_v130,
0162 },
0163 {
0164 .callback = dmi_matched,
0165 .ident = "Dell Vostro V131",
0166 .matches = {
0167 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0168 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
0169 },
0170 .driver_data = &quirk_dell_vostro_v130,
0171 },
0172 {
0173 .callback = dmi_matched,
0174 .ident = "Dell Vostro 3350",
0175 .matches = {
0176 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0177 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"),
0178 },
0179 .driver_data = &quirk_dell_vostro_v130,
0180 },
0181 {
0182 .callback = dmi_matched,
0183 .ident = "Dell Vostro 3555",
0184 .matches = {
0185 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0186 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3555"),
0187 },
0188 .driver_data = &quirk_dell_vostro_v130,
0189 },
0190 {
0191 .callback = dmi_matched,
0192 .ident = "Dell Inspiron N311z",
0193 .matches = {
0194 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0195 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N311z"),
0196 },
0197 .driver_data = &quirk_dell_vostro_v130,
0198 },
0199 {
0200 .callback = dmi_matched,
0201 .ident = "Dell Inspiron M5110",
0202 .matches = {
0203 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0204 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron M5110"),
0205 },
0206 .driver_data = &quirk_dell_vostro_v130,
0207 },
0208 {
0209 .callback = dmi_matched,
0210 .ident = "Dell Vostro 3360",
0211 .matches = {
0212 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0213 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),
0214 },
0215 .driver_data = &quirk_dell_vostro_v130,
0216 },
0217 {
0218 .callback = dmi_matched,
0219 .ident = "Dell Vostro 3460",
0220 .matches = {
0221 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0222 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3460"),
0223 },
0224 .driver_data = &quirk_dell_vostro_v130,
0225 },
0226 {
0227 .callback = dmi_matched,
0228 .ident = "Dell Vostro 3560",
0229 .matches = {
0230 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0231 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3560"),
0232 },
0233 .driver_data = &quirk_dell_vostro_v130,
0234 },
0235 {
0236 .callback = dmi_matched,
0237 .ident = "Dell Vostro 3450",
0238 .matches = {
0239 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0240 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System Vostro 3450"),
0241 },
0242 .driver_data = &quirk_dell_vostro_v130,
0243 },
0244 {
0245 .callback = dmi_matched,
0246 .ident = "Dell Inspiron 5420",
0247 .matches = {
0248 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0249 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"),
0250 },
0251 .driver_data = &quirk_dell_vostro_v130,
0252 },
0253 {
0254 .callback = dmi_matched,
0255 .ident = "Dell Inspiron 5520",
0256 .matches = {
0257 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0258 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"),
0259 },
0260 .driver_data = &quirk_dell_vostro_v130,
0261 },
0262 {
0263 .callback = dmi_matched,
0264 .ident = "Dell Inspiron 5720",
0265 .matches = {
0266 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0267 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"),
0268 },
0269 .driver_data = &quirk_dell_vostro_v130,
0270 },
0271 {
0272 .callback = dmi_matched,
0273 .ident = "Dell Inspiron 7420",
0274 .matches = {
0275 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0276 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"),
0277 },
0278 .driver_data = &quirk_dell_vostro_v130,
0279 },
0280 {
0281 .callback = dmi_matched,
0282 .ident = "Dell Inspiron 7520",
0283 .matches = {
0284 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0285 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),
0286 },
0287 .driver_data = &quirk_dell_vostro_v130,
0288 },
0289 {
0290 .callback = dmi_matched,
0291 .ident = "Dell Inspiron 7720",
0292 .matches = {
0293 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0294 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),
0295 },
0296 .driver_data = &quirk_dell_vostro_v130,
0297 },
0298 {
0299 .callback = dmi_matched,
0300 .ident = "Dell XPS13 9333",
0301 .matches = {
0302 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0303 DMI_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"),
0304 },
0305 .driver_data = &quirk_dell_xps13_9333,
0306 },
0307 {
0308 .callback = dmi_matched,
0309 .ident = "Dell XPS 13 9370",
0310 .matches = {
0311 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0312 DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9370"),
0313 },
0314 .driver_data = &quirk_dell_xps13_9370,
0315 },
0316 {
0317 .callback = dmi_matched,
0318 .ident = "Dell Latitude E6410",
0319 .matches = {
0320 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0321 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6410"),
0322 },
0323 .driver_data = &quirk_dell_latitude_e6410,
0324 },
0325 {
0326 .callback = dmi_matched,
0327 .ident = "Dell Inspiron 1012",
0328 .matches = {
0329 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0330 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
0331 },
0332 .driver_data = &quirk_dell_inspiron_1012,
0333 },
0334 {
0335 .callback = dmi_matched,
0336 .ident = "Dell Inspiron 1018",
0337 .matches = {
0338 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0339 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1018"),
0340 },
0341 .driver_data = &quirk_dell_inspiron_1012,
0342 },
0343 {
0344 .callback = dmi_matched,
0345 .ident = "Dell Latitude 7520",
0346 .matches = {
0347 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0348 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 7520"),
0349 },
0350 .driver_data = &quirk_dell_latitude_7520,
0351 },
0352 { }
0353 };
0354
0355 static void dell_fill_request(struct calling_interface_buffer *buffer,
0356 u32 arg0, u32 arg1, u32 arg2, u32 arg3)
0357 {
0358 memset(buffer, 0, sizeof(struct calling_interface_buffer));
0359 buffer->input[0] = arg0;
0360 buffer->input[1] = arg1;
0361 buffer->input[2] = arg2;
0362 buffer->input[3] = arg3;
0363 }
0364
0365 static int dell_send_request(struct calling_interface_buffer *buffer,
0366 u16 class, u16 select)
0367 {
0368 int ret;
0369
0370 buffer->cmd_class = class;
0371 buffer->cmd_select = select;
0372 ret = dell_smbios_call(buffer);
0373 if (ret != 0)
0374 return ret;
0375 return dell_smbios_error(buffer->output[0]);
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 static int dell_rfkill_set(void *data, bool blocked)
0499 {
0500 int disable = blocked ? 1 : 0;
0501 unsigned long radio = (unsigned long)data;
0502 int hwswitch_bit = (unsigned long)data - 1;
0503 struct calling_interface_buffer buffer;
0504 int hwswitch;
0505 int status;
0506 int ret;
0507
0508 dell_fill_request(&buffer, 0, 0, 0, 0);
0509 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0510 if (ret)
0511 return ret;
0512 status = buffer.output[1];
0513
0514 dell_fill_request(&buffer, 0x2, 0, 0, 0);
0515 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0516 if (ret)
0517 return ret;
0518 hwswitch = buffer.output[1];
0519
0520
0521
0522 if (ret == 0 && (hwswitch & BIT(hwswitch_bit)) &&
0523 (status & BIT(0)) && !(status & BIT(16)))
0524 disable = 1;
0525
0526 dell_fill_request(&buffer, 1 | (radio<<8) | (disable << 16), 0, 0, 0);
0527 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0528 return ret;
0529 }
0530
0531 static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
0532 int status)
0533 {
0534 if (status & BIT(0)) {
0535
0536 struct calling_interface_buffer buffer;
0537 int block = rfkill_blocked(rfkill);
0538 dell_fill_request(&buffer,
0539 1 | (radio << 8) | (block << 16), 0, 0, 0);
0540 dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0541 } else {
0542
0543 rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
0544 }
0545 }
0546
0547 static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
0548 int status, int hwswitch)
0549 {
0550 if (hwswitch & (BIT(radio - 1)))
0551 rfkill_set_hw_state(rfkill, !(status & BIT(16)));
0552 }
0553
0554 static void dell_rfkill_query(struct rfkill *rfkill, void *data)
0555 {
0556 int radio = ((unsigned long)data & 0xF);
0557 struct calling_interface_buffer buffer;
0558 int hwswitch;
0559 int status;
0560 int ret;
0561
0562 dell_fill_request(&buffer, 0, 0, 0, 0);
0563 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0564 status = buffer.output[1];
0565
0566 if (ret != 0 || !(status & BIT(0))) {
0567 return;
0568 }
0569
0570 dell_fill_request(&buffer, 0x2, 0, 0, 0);
0571 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0572 hwswitch = buffer.output[1];
0573
0574 if (ret != 0)
0575 return;
0576
0577 dell_rfkill_update_hw_state(rfkill, radio, status, hwswitch);
0578 }
0579
0580 static const struct rfkill_ops dell_rfkill_ops = {
0581 .set_block = dell_rfkill_set,
0582 .query = dell_rfkill_query,
0583 };
0584
0585 static struct dentry *dell_laptop_dir;
0586
0587 static int dell_debugfs_show(struct seq_file *s, void *data)
0588 {
0589 struct calling_interface_buffer buffer;
0590 int hwswitch_state;
0591 int hwswitch_ret;
0592 int status;
0593 int ret;
0594
0595 dell_fill_request(&buffer, 0, 0, 0, 0);
0596 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0597 if (ret)
0598 return ret;
0599 status = buffer.output[1];
0600
0601 dell_fill_request(&buffer, 0x2, 0, 0, 0);
0602 hwswitch_ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0603 if (hwswitch_ret)
0604 return hwswitch_ret;
0605 hwswitch_state = buffer.output[1];
0606
0607 seq_printf(s, "return:\t%d\n", ret);
0608 seq_printf(s, "status:\t0x%X\n", status);
0609 seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n",
0610 status & BIT(0));
0611 seq_printf(s, "Bit 1 : Wifi locator supported: %lu\n",
0612 (status & BIT(1)) >> 1);
0613 seq_printf(s, "Bit 2 : Wifi is supported: %lu\n",
0614 (status & BIT(2)) >> 2);
0615 seq_printf(s, "Bit 3 : Bluetooth is supported: %lu\n",
0616 (status & BIT(3)) >> 3);
0617 seq_printf(s, "Bit 4 : WWAN is supported: %lu\n",
0618 (status & BIT(4)) >> 4);
0619 seq_printf(s, "Bit 5 : Wireless keyboard supported: %lu\n",
0620 (status & BIT(5)) >> 5);
0621 seq_printf(s, "Bit 6 : UWB supported: %lu\n",
0622 (status & BIT(6)) >> 6);
0623 seq_printf(s, "Bit 7 : WiGig supported: %lu\n",
0624 (status & BIT(7)) >> 7);
0625 seq_printf(s, "Bit 8 : Wifi is installed: %lu\n",
0626 (status & BIT(8)) >> 8);
0627 seq_printf(s, "Bit 9 : Bluetooth is installed: %lu\n",
0628 (status & BIT(9)) >> 9);
0629 seq_printf(s, "Bit 10: WWAN is installed: %lu\n",
0630 (status & BIT(10)) >> 10);
0631 seq_printf(s, "Bit 11: UWB installed: %lu\n",
0632 (status & BIT(11)) >> 11);
0633 seq_printf(s, "Bit 12: WiGig installed: %lu\n",
0634 (status & BIT(12)) >> 12);
0635
0636 seq_printf(s, "Bit 16: Hardware switch is on: %lu\n",
0637 (status & BIT(16)) >> 16);
0638 seq_printf(s, "Bit 17: Wifi is blocked: %lu\n",
0639 (status & BIT(17)) >> 17);
0640 seq_printf(s, "Bit 18: Bluetooth is blocked: %lu\n",
0641 (status & BIT(18)) >> 18);
0642 seq_printf(s, "Bit 19: WWAN is blocked: %lu\n",
0643 (status & BIT(19)) >> 19);
0644 seq_printf(s, "Bit 20: UWB is blocked: %lu\n",
0645 (status & BIT(20)) >> 20);
0646 seq_printf(s, "Bit 21: WiGig is blocked: %lu\n",
0647 (status & BIT(21)) >> 21);
0648
0649 seq_printf(s, "\nhwswitch_return:\t%d\n", hwswitch_ret);
0650 seq_printf(s, "hwswitch_state:\t0x%X\n", hwswitch_state);
0651 seq_printf(s, "Bit 0 : Wifi controlled by switch: %lu\n",
0652 hwswitch_state & BIT(0));
0653 seq_printf(s, "Bit 1 : Bluetooth controlled by switch: %lu\n",
0654 (hwswitch_state & BIT(1)) >> 1);
0655 seq_printf(s, "Bit 2 : WWAN controlled by switch: %lu\n",
0656 (hwswitch_state & BIT(2)) >> 2);
0657 seq_printf(s, "Bit 3 : UWB controlled by switch: %lu\n",
0658 (hwswitch_state & BIT(3)) >> 3);
0659 seq_printf(s, "Bit 4 : WiGig controlled by switch: %lu\n",
0660 (hwswitch_state & BIT(4)) >> 4);
0661 seq_printf(s, "Bit 7 : Wireless switch config locked: %lu\n",
0662 (hwswitch_state & BIT(7)) >> 7);
0663 seq_printf(s, "Bit 8 : Wifi locator enabled: %lu\n",
0664 (hwswitch_state & BIT(8)) >> 8);
0665 seq_printf(s, "Bit 15: Wifi locator setting locked: %lu\n",
0666 (hwswitch_state & BIT(15)) >> 15);
0667
0668 return 0;
0669 }
0670 DEFINE_SHOW_ATTRIBUTE(dell_debugfs);
0671
0672 static void dell_update_rfkill(struct work_struct *ignored)
0673 {
0674 struct calling_interface_buffer buffer;
0675 int hwswitch = 0;
0676 int status;
0677 int ret;
0678
0679 dell_fill_request(&buffer, 0, 0, 0, 0);
0680 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0681 status = buffer.output[1];
0682
0683 if (ret != 0)
0684 return;
0685
0686 dell_fill_request(&buffer, 0x2, 0, 0, 0);
0687 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0688
0689 if (ret == 0 && (status & BIT(0)))
0690 hwswitch = buffer.output[1];
0691
0692 if (wifi_rfkill) {
0693 dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch);
0694 dell_rfkill_update_sw_state(wifi_rfkill, 1, status);
0695 }
0696 if (bluetooth_rfkill) {
0697 dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status,
0698 hwswitch);
0699 dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status);
0700 }
0701 if (wwan_rfkill) {
0702 dell_rfkill_update_hw_state(wwan_rfkill, 3, status, hwswitch);
0703 dell_rfkill_update_sw_state(wwan_rfkill, 3, status);
0704 }
0705 }
0706 static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
0707
0708 static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
0709 struct serio *port)
0710 {
0711 static bool extended;
0712
0713 if (str & I8042_STR_AUXDATA)
0714 return false;
0715
0716 if (unlikely(data == 0xe0)) {
0717 extended = true;
0718 return false;
0719 } else if (unlikely(extended)) {
0720 switch (data) {
0721 case 0x8:
0722 schedule_delayed_work(&dell_rfkill_work,
0723 round_jiffies_relative(HZ / 4));
0724 break;
0725 }
0726 extended = false;
0727 }
0728
0729 return false;
0730 }
0731
0732 static int (*dell_rbtn_notifier_register_func)(struct notifier_block *);
0733 static int (*dell_rbtn_notifier_unregister_func)(struct notifier_block *);
0734
0735 static int dell_laptop_rbtn_notifier_call(struct notifier_block *nb,
0736 unsigned long action, void *data)
0737 {
0738 schedule_delayed_work(&dell_rfkill_work, 0);
0739 return NOTIFY_OK;
0740 }
0741
0742 static struct notifier_block dell_laptop_rbtn_notifier = {
0743 .notifier_call = dell_laptop_rbtn_notifier_call,
0744 };
0745
0746 static int __init dell_setup_rfkill(void)
0747 {
0748 struct calling_interface_buffer buffer;
0749 int status, ret, whitelisted;
0750 const char *product;
0751
0752
0753
0754
0755
0756 whitelisted = 0;
0757 product = dmi_get_system_info(DMI_PRODUCT_NAME);
0758 if (product && (strncmp(product, "Latitude", 8) == 0 ||
0759 strncmp(product, "Precision", 9) == 0))
0760 whitelisted = 1;
0761 if (!force_rfkill && !whitelisted)
0762 return 0;
0763
0764 dell_fill_request(&buffer, 0, 0, 0, 0);
0765 ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
0766 status = buffer.output[1];
0767
0768
0769 if (ret != 0)
0770 return 0;
0771
0772
0773 if (!(status & BIT(0)) && !force_rfkill)
0774 return 0;
0775
0776 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
0777 wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
0778 RFKILL_TYPE_WLAN,
0779 &dell_rfkill_ops, (void *) 1);
0780 if (!wifi_rfkill) {
0781 ret = -ENOMEM;
0782 goto err_wifi;
0783 }
0784 ret = rfkill_register(wifi_rfkill);
0785 if (ret)
0786 goto err_wifi;
0787 }
0788
0789 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
0790 bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
0791 &platform_device->dev,
0792 RFKILL_TYPE_BLUETOOTH,
0793 &dell_rfkill_ops, (void *) 2);
0794 if (!bluetooth_rfkill) {
0795 ret = -ENOMEM;
0796 goto err_bluetooth;
0797 }
0798 ret = rfkill_register(bluetooth_rfkill);
0799 if (ret)
0800 goto err_bluetooth;
0801 }
0802
0803 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
0804 wwan_rfkill = rfkill_alloc("dell-wwan",
0805 &platform_device->dev,
0806 RFKILL_TYPE_WWAN,
0807 &dell_rfkill_ops, (void *) 3);
0808 if (!wwan_rfkill) {
0809 ret = -ENOMEM;
0810 goto err_wwan;
0811 }
0812 ret = rfkill_register(wwan_rfkill);
0813 if (ret)
0814 goto err_wwan;
0815 }
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836 dell_rbtn_notifier_register_func =
0837 symbol_request(dell_rbtn_notifier_register);
0838 if (dell_rbtn_notifier_register_func) {
0839 dell_rbtn_notifier_unregister_func =
0840 symbol_request(dell_rbtn_notifier_unregister);
0841 if (!dell_rbtn_notifier_unregister_func) {
0842 symbol_put(dell_rbtn_notifier_register);
0843 dell_rbtn_notifier_register_func = NULL;
0844 }
0845 }
0846
0847 if (dell_rbtn_notifier_register_func) {
0848 ret = dell_rbtn_notifier_register_func(
0849 &dell_laptop_rbtn_notifier);
0850 symbol_put(dell_rbtn_notifier_register);
0851 dell_rbtn_notifier_register_func = NULL;
0852 if (ret != 0) {
0853 symbol_put(dell_rbtn_notifier_unregister);
0854 dell_rbtn_notifier_unregister_func = NULL;
0855 }
0856 } else {
0857 pr_info("Symbols from dell-rbtn acpi driver are not available\n");
0858 ret = -ENODEV;
0859 }
0860
0861 if (ret == 0) {
0862 pr_info("Using dell-rbtn acpi driver for receiving events\n");
0863 } else if (ret != -ENODEV) {
0864 pr_warn("Unable to register dell rbtn notifier\n");
0865 goto err_filter;
0866 } else {
0867 ret = i8042_install_filter(dell_laptop_i8042_filter);
0868 if (ret) {
0869 pr_warn("Unable to install key filter\n");
0870 goto err_filter;
0871 }
0872 pr_info("Using i8042 filter function for receiving events\n");
0873 }
0874
0875 return 0;
0876 err_filter:
0877 if (wwan_rfkill)
0878 rfkill_unregister(wwan_rfkill);
0879 err_wwan:
0880 rfkill_destroy(wwan_rfkill);
0881 if (bluetooth_rfkill)
0882 rfkill_unregister(bluetooth_rfkill);
0883 err_bluetooth:
0884 rfkill_destroy(bluetooth_rfkill);
0885 if (wifi_rfkill)
0886 rfkill_unregister(wifi_rfkill);
0887 err_wifi:
0888 rfkill_destroy(wifi_rfkill);
0889
0890 return ret;
0891 }
0892
0893 static void dell_cleanup_rfkill(void)
0894 {
0895 if (dell_rbtn_notifier_unregister_func) {
0896 dell_rbtn_notifier_unregister_func(&dell_laptop_rbtn_notifier);
0897 symbol_put(dell_rbtn_notifier_unregister);
0898 dell_rbtn_notifier_unregister_func = NULL;
0899 } else {
0900 i8042_remove_filter(dell_laptop_i8042_filter);
0901 }
0902 cancel_delayed_work_sync(&dell_rfkill_work);
0903 if (wifi_rfkill) {
0904 rfkill_unregister(wifi_rfkill);
0905 rfkill_destroy(wifi_rfkill);
0906 }
0907 if (bluetooth_rfkill) {
0908 rfkill_unregister(bluetooth_rfkill);
0909 rfkill_destroy(bluetooth_rfkill);
0910 }
0911 if (wwan_rfkill) {
0912 rfkill_unregister(wwan_rfkill);
0913 rfkill_destroy(wwan_rfkill);
0914 }
0915 }
0916
0917 static int dell_send_intensity(struct backlight_device *bd)
0918 {
0919 struct calling_interface_buffer buffer;
0920 struct calling_interface_token *token;
0921 int ret;
0922
0923 token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
0924 if (!token)
0925 return -ENODEV;
0926
0927 dell_fill_request(&buffer,
0928 token->location, bd->props.brightness, 0, 0);
0929 if (power_supply_is_system_supplied() > 0)
0930 ret = dell_send_request(&buffer,
0931 CLASS_TOKEN_WRITE, SELECT_TOKEN_AC);
0932 else
0933 ret = dell_send_request(&buffer,
0934 CLASS_TOKEN_WRITE, SELECT_TOKEN_BAT);
0935
0936 return ret;
0937 }
0938
0939 static int dell_get_intensity(struct backlight_device *bd)
0940 {
0941 struct calling_interface_buffer buffer;
0942 struct calling_interface_token *token;
0943 int ret;
0944
0945 token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
0946 if (!token)
0947 return -ENODEV;
0948
0949 dell_fill_request(&buffer, token->location, 0, 0, 0);
0950 if (power_supply_is_system_supplied() > 0)
0951 ret = dell_send_request(&buffer,
0952 CLASS_TOKEN_READ, SELECT_TOKEN_AC);
0953 else
0954 ret = dell_send_request(&buffer,
0955 CLASS_TOKEN_READ, SELECT_TOKEN_BAT);
0956
0957 if (ret == 0)
0958 ret = buffer.output[1];
0959
0960 return ret;
0961 }
0962
0963 static const struct backlight_ops dell_ops = {
0964 .get_brightness = dell_get_intensity,
0965 .update_status = dell_send_intensity,
0966 };
0967
0968 static void touchpad_led_on(void)
0969 {
0970 int command = 0x97;
0971 char data = 1;
0972 i8042_command(&data, command | 1 << 12);
0973 }
0974
0975 static void touchpad_led_off(void)
0976 {
0977 int command = 0x97;
0978 char data = 2;
0979 i8042_command(&data, command | 1 << 12);
0980 }
0981
0982 static void touchpad_led_set(struct led_classdev *led_cdev,
0983 enum led_brightness value)
0984 {
0985 if (value > 0)
0986 touchpad_led_on();
0987 else
0988 touchpad_led_off();
0989 }
0990
0991 static struct led_classdev touchpad_led = {
0992 .name = "dell-laptop::touchpad",
0993 .brightness_set = touchpad_led_set,
0994 .flags = LED_CORE_SUSPENDRESUME,
0995 };
0996
0997 static int __init touchpad_led_init(struct device *dev)
0998 {
0999 return led_classdev_register(dev, &touchpad_led);
1000 }
1001
1002 static void touchpad_led_exit(void)
1003 {
1004 led_classdev_unregister(&touchpad_led);
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 enum kbd_timeout_unit {
1135 KBD_TIMEOUT_SECONDS = 0,
1136 KBD_TIMEOUT_MINUTES,
1137 KBD_TIMEOUT_HOURS,
1138 KBD_TIMEOUT_DAYS,
1139 };
1140
1141 enum kbd_mode_bit {
1142 KBD_MODE_BIT_OFF = 0,
1143 KBD_MODE_BIT_ON,
1144 KBD_MODE_BIT_ALS,
1145 KBD_MODE_BIT_TRIGGER_ALS,
1146 KBD_MODE_BIT_TRIGGER,
1147 KBD_MODE_BIT_TRIGGER_25,
1148 KBD_MODE_BIT_TRIGGER_50,
1149 KBD_MODE_BIT_TRIGGER_75,
1150 KBD_MODE_BIT_TRIGGER_100,
1151 };
1152
1153 #define kbd_is_als_mode_bit(bit) \
1154 ((bit) == KBD_MODE_BIT_ALS || (bit) == KBD_MODE_BIT_TRIGGER_ALS)
1155 #define kbd_is_trigger_mode_bit(bit) \
1156 ((bit) >= KBD_MODE_BIT_TRIGGER_ALS && (bit) <= KBD_MODE_BIT_TRIGGER_100)
1157 #define kbd_is_level_mode_bit(bit) \
1158 ((bit) >= KBD_MODE_BIT_TRIGGER_25 && (bit) <= KBD_MODE_BIT_TRIGGER_100)
1159
1160 struct kbd_info {
1161 u16 modes;
1162 u8 type;
1163 u8 triggers;
1164 u8 levels;
1165 u8 seconds;
1166 u8 minutes;
1167 u8 hours;
1168 u8 days;
1169 };
1170
1171 struct kbd_state {
1172 u8 mode_bit;
1173 u8 triggers;
1174 u8 timeout_value;
1175 u8 timeout_unit;
1176 u8 timeout_value_ac;
1177 u8 timeout_unit_ac;
1178 u8 als_setting;
1179 u8 als_value;
1180 u8 level;
1181 };
1182
1183 static const int kbd_tokens[] = {
1184 KBD_LED_OFF_TOKEN,
1185 KBD_LED_AUTO_25_TOKEN,
1186 KBD_LED_AUTO_50_TOKEN,
1187 KBD_LED_AUTO_75_TOKEN,
1188 KBD_LED_AUTO_100_TOKEN,
1189 KBD_LED_ON_TOKEN,
1190 };
1191
1192 static u16 kbd_token_bits;
1193
1194 static struct kbd_info kbd_info;
1195 static bool kbd_als_supported;
1196 static bool kbd_triggers_supported;
1197 static bool kbd_timeout_ac_supported;
1198
1199 static u8 kbd_mode_levels[16];
1200 static int kbd_mode_levels_count;
1201
1202 static u8 kbd_previous_level;
1203 static u8 kbd_previous_mode_bit;
1204
1205 static bool kbd_led_present;
1206 static DEFINE_MUTEX(kbd_led_mutex);
1207 static enum led_brightness kbd_led_level;
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 static int kbd_get_info(struct kbd_info *info)
1223 {
1224 struct calling_interface_buffer buffer;
1225 u8 units;
1226 int ret;
1227
1228 dell_fill_request(&buffer, 0, 0, 0, 0);
1229 ret = dell_send_request(&buffer,
1230 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
1231 if (ret)
1232 return ret;
1233
1234 info->modes = buffer.output[1] & 0xFFFF;
1235 info->type = (buffer.output[1] >> 24) & 0xFF;
1236 info->triggers = buffer.output[2] & 0xFF;
1237 units = (buffer.output[2] >> 8) & 0xFF;
1238 info->levels = (buffer.output[2] >> 16) & 0xFF;
1239
1240 if (quirks && quirks->kbd_led_levels_off_1 && info->levels)
1241 info->levels--;
1242
1243 if (units & BIT(0))
1244 info->seconds = (buffer.output[3] >> 0) & 0xFF;
1245 if (units & BIT(1))
1246 info->minutes = (buffer.output[3] >> 8) & 0xFF;
1247 if (units & BIT(2))
1248 info->hours = (buffer.output[3] >> 16) & 0xFF;
1249 if (units & BIT(3))
1250 info->days = (buffer.output[3] >> 24) & 0xFF;
1251
1252 return ret;
1253 }
1254
1255 static unsigned int kbd_get_max_level(void)
1256 {
1257 if (kbd_info.levels != 0)
1258 return kbd_info.levels;
1259 if (kbd_mode_levels_count > 0)
1260 return kbd_mode_levels_count - 1;
1261 return 0;
1262 }
1263
1264 static int kbd_get_level(struct kbd_state *state)
1265 {
1266 int i;
1267
1268 if (kbd_info.levels != 0)
1269 return state->level;
1270
1271 if (kbd_mode_levels_count > 0) {
1272 for (i = 0; i < kbd_mode_levels_count; ++i)
1273 if (kbd_mode_levels[i] == state->mode_bit)
1274 return i;
1275 return 0;
1276 }
1277
1278 return -EINVAL;
1279 }
1280
1281 static int kbd_set_level(struct kbd_state *state, u8 level)
1282 {
1283 if (kbd_info.levels != 0) {
1284 if (level != 0)
1285 kbd_previous_level = level;
1286 if (state->level == level)
1287 return 0;
1288 state->level = level;
1289 if (level != 0 && state->mode_bit == KBD_MODE_BIT_OFF)
1290 state->mode_bit = kbd_previous_mode_bit;
1291 else if (level == 0 && state->mode_bit != KBD_MODE_BIT_OFF) {
1292 kbd_previous_mode_bit = state->mode_bit;
1293 state->mode_bit = KBD_MODE_BIT_OFF;
1294 }
1295 return 0;
1296 }
1297
1298 if (kbd_mode_levels_count > 0 && level < kbd_mode_levels_count) {
1299 if (level != 0)
1300 kbd_previous_level = level;
1301 state->mode_bit = kbd_mode_levels[level];
1302 return 0;
1303 }
1304
1305 return -EINVAL;
1306 }
1307
1308 static int kbd_get_state(struct kbd_state *state)
1309 {
1310 struct calling_interface_buffer buffer;
1311 int ret;
1312
1313 dell_fill_request(&buffer, 0x1, 0, 0, 0);
1314 ret = dell_send_request(&buffer,
1315 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
1316 if (ret)
1317 return ret;
1318
1319 state->mode_bit = ffs(buffer.output[1] & 0xFFFF);
1320 if (state->mode_bit != 0)
1321 state->mode_bit--;
1322
1323 state->triggers = (buffer.output[1] >> 16) & 0xFF;
1324 state->timeout_value = (buffer.output[1] >> 24) & 0x3F;
1325 state->timeout_unit = (buffer.output[1] >> 30) & 0x3;
1326 state->als_setting = buffer.output[2] & 0xFF;
1327 state->als_value = (buffer.output[2] >> 8) & 0xFF;
1328 state->level = (buffer.output[2] >> 16) & 0xFF;
1329 state->timeout_value_ac = (buffer.output[2] >> 24) & 0x3F;
1330 state->timeout_unit_ac = (buffer.output[2] >> 30) & 0x3;
1331
1332 return ret;
1333 }
1334
1335 static int kbd_set_state(struct kbd_state *state)
1336 {
1337 struct calling_interface_buffer buffer;
1338 int ret;
1339 u32 input1;
1340 u32 input2;
1341
1342 input1 = BIT(state->mode_bit) & 0xFFFF;
1343 input1 |= (state->triggers & 0xFF) << 16;
1344 input1 |= (state->timeout_value & 0x3F) << 24;
1345 input1 |= (state->timeout_unit & 0x3) << 30;
1346 input2 = state->als_setting & 0xFF;
1347 input2 |= (state->level & 0xFF) << 16;
1348 input2 |= (state->timeout_value_ac & 0x3F) << 24;
1349 input2 |= (state->timeout_unit_ac & 0x3) << 30;
1350 dell_fill_request(&buffer, 0x2, input1, input2, 0);
1351 ret = dell_send_request(&buffer,
1352 CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
1353
1354 return ret;
1355 }
1356
1357 static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old)
1358 {
1359 int ret;
1360
1361 ret = kbd_set_state(state);
1362 if (ret == 0)
1363 return 0;
1364
1365
1366
1367
1368
1369
1370
1371 if (kbd_set_state(old))
1372 pr_err("Setting old previous keyboard state failed\n");
1373
1374 return ret;
1375 }
1376
1377 static int kbd_set_token_bit(u8 bit)
1378 {
1379 struct calling_interface_buffer buffer;
1380 struct calling_interface_token *token;
1381 int ret;
1382
1383 if (bit >= ARRAY_SIZE(kbd_tokens))
1384 return -EINVAL;
1385
1386 token = dell_smbios_find_token(kbd_tokens[bit]);
1387 if (!token)
1388 return -EINVAL;
1389
1390 dell_fill_request(&buffer, token->location, token->value, 0, 0);
1391 ret = dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
1392
1393 return ret;
1394 }
1395
1396 static int kbd_get_token_bit(u8 bit)
1397 {
1398 struct calling_interface_buffer buffer;
1399 struct calling_interface_token *token;
1400 int ret;
1401 int val;
1402
1403 if (bit >= ARRAY_SIZE(kbd_tokens))
1404 return -EINVAL;
1405
1406 token = dell_smbios_find_token(kbd_tokens[bit]);
1407 if (!token)
1408 return -EINVAL;
1409
1410 dell_fill_request(&buffer, token->location, 0, 0, 0);
1411 ret = dell_send_request(&buffer, CLASS_TOKEN_READ, SELECT_TOKEN_STD);
1412 val = buffer.output[1];
1413
1414 if (ret)
1415 return ret;
1416
1417 return (val == token->value);
1418 }
1419
1420 static int kbd_get_first_active_token_bit(void)
1421 {
1422 int i;
1423 int ret;
1424
1425 for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) {
1426 ret = kbd_get_token_bit(i);
1427 if (ret == 1)
1428 return i;
1429 }
1430
1431 return ret;
1432 }
1433
1434 static int kbd_get_valid_token_counts(void)
1435 {
1436 return hweight16(kbd_token_bits);
1437 }
1438
1439 static inline int kbd_init_info(void)
1440 {
1441 struct kbd_state state;
1442 int ret;
1443 int i;
1444
1445 ret = kbd_get_info(&kbd_info);
1446 if (ret)
1447 return ret;
1448
1449
1450
1451
1452
1453 if ((quirks && quirks->kbd_missing_ac_tag) ||
1454 dell_smbios_find_token(KBD_LED_AC_TOKEN))
1455 kbd_timeout_ac_supported = true;
1456
1457 kbd_get_state(&state);
1458
1459
1460 if (kbd_info.seconds > 63)
1461 kbd_info.seconds = 63;
1462 if (kbd_info.minutes > 63)
1463 kbd_info.minutes = 63;
1464 if (kbd_info.hours > 63)
1465 kbd_info.hours = 63;
1466 if (kbd_info.days > 63)
1467 kbd_info.days = 63;
1468
1469
1470
1471
1472 kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON);
1473
1474 kbd_previous_level = kbd_get_level(&state);
1475 kbd_previous_mode_bit = state.mode_bit;
1476
1477 if (kbd_previous_level == 0 && kbd_get_max_level() != 0)
1478 kbd_previous_level = 1;
1479
1480 if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) {
1481 kbd_previous_mode_bit =
1482 ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF));
1483 if (kbd_previous_mode_bit != 0)
1484 kbd_previous_mode_bit--;
1485 }
1486
1487 if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) |
1488 BIT(KBD_MODE_BIT_TRIGGER_ALS)))
1489 kbd_als_supported = true;
1490
1491 if (kbd_info.modes & (
1492 BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) |
1493 BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) |
1494 BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100)
1495 ))
1496 kbd_triggers_supported = true;
1497
1498
1499 for (i = 0; i < 16; ++i)
1500 if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes))
1501 kbd_mode_levels[1 + kbd_mode_levels_count++] = i;
1502
1503
1504
1505
1506
1507
1508 if (kbd_mode_levels_count > 0) {
1509 for (i = 0; i < 16; ++i) {
1510 if (BIT(i) & kbd_info.modes) {
1511 kbd_mode_levels[0] = i;
1512 break;
1513 }
1514 }
1515 kbd_mode_levels_count++;
1516 }
1517
1518 return 0;
1519
1520 }
1521
1522 static inline void kbd_init_tokens(void)
1523 {
1524 int i;
1525
1526 for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i)
1527 if (dell_smbios_find_token(kbd_tokens[i]))
1528 kbd_token_bits |= BIT(i);
1529 }
1530
1531 static void kbd_init(void)
1532 {
1533 int ret;
1534
1535 if (quirks && quirks->kbd_led_not_present)
1536 return;
1537
1538 ret = kbd_init_info();
1539 kbd_init_tokens();
1540
1541
1542
1543
1544 if ((ret == 0 && (kbd_info.levels != 0 || kbd_mode_levels_count >= 2))
1545 || kbd_get_valid_token_counts() >= 2)
1546 kbd_led_present = true;
1547 }
1548
1549 static ssize_t kbd_led_timeout_store(struct device *dev,
1550 struct device_attribute *attr,
1551 const char *buf, size_t count)
1552 {
1553 struct kbd_state new_state;
1554 struct kbd_state state;
1555 bool convert;
1556 int value;
1557 int ret;
1558 char ch;
1559 u8 unit;
1560 int i;
1561
1562 ret = sscanf(buf, "%d %c", &value, &ch);
1563 if (ret < 1)
1564 return -EINVAL;
1565 else if (ret == 1)
1566 ch = 's';
1567
1568 if (value < 0)
1569 return -EINVAL;
1570
1571 convert = false;
1572
1573 switch (ch) {
1574 case 's':
1575 if (value > kbd_info.seconds)
1576 convert = true;
1577 unit = KBD_TIMEOUT_SECONDS;
1578 break;
1579 case 'm':
1580 if (value > kbd_info.minutes)
1581 convert = true;
1582 unit = KBD_TIMEOUT_MINUTES;
1583 break;
1584 case 'h':
1585 if (value > kbd_info.hours)
1586 convert = true;
1587 unit = KBD_TIMEOUT_HOURS;
1588 break;
1589 case 'd':
1590 if (value > kbd_info.days)
1591 convert = true;
1592 unit = KBD_TIMEOUT_DAYS;
1593 break;
1594 default:
1595 return -EINVAL;
1596 }
1597
1598 if (quirks && quirks->needs_kbd_timeouts)
1599 convert = true;
1600
1601 if (convert) {
1602
1603 switch (unit) {
1604 case KBD_TIMEOUT_DAYS:
1605 value *= 24;
1606 fallthrough;
1607 case KBD_TIMEOUT_HOURS:
1608 value *= 60;
1609 fallthrough;
1610 case KBD_TIMEOUT_MINUTES:
1611 value *= 60;
1612 unit = KBD_TIMEOUT_SECONDS;
1613 }
1614
1615 if (quirks && quirks->needs_kbd_timeouts) {
1616 for (i = 0; quirks->kbd_timeouts[i] != -1; i++) {
1617 if (value <= quirks->kbd_timeouts[i]) {
1618 value = quirks->kbd_timeouts[i];
1619 break;
1620 }
1621 }
1622 }
1623
1624 if (value <= kbd_info.seconds && kbd_info.seconds) {
1625 unit = KBD_TIMEOUT_SECONDS;
1626 } else if (value / 60 <= kbd_info.minutes && kbd_info.minutes) {
1627 value /= 60;
1628 unit = KBD_TIMEOUT_MINUTES;
1629 } else if (value / (60 * 60) <= kbd_info.hours && kbd_info.hours) {
1630 value /= (60 * 60);
1631 unit = KBD_TIMEOUT_HOURS;
1632 } else if (value / (60 * 60 * 24) <= kbd_info.days && kbd_info.days) {
1633 value /= (60 * 60 * 24);
1634 unit = KBD_TIMEOUT_DAYS;
1635 } else {
1636 return -EINVAL;
1637 }
1638 }
1639
1640 mutex_lock(&kbd_led_mutex);
1641
1642 ret = kbd_get_state(&state);
1643 if (ret)
1644 goto out;
1645
1646 new_state = state;
1647
1648 if (kbd_timeout_ac_supported && power_supply_is_system_supplied() > 0) {
1649 new_state.timeout_value_ac = value;
1650 new_state.timeout_unit_ac = unit;
1651 } else {
1652 new_state.timeout_value = value;
1653 new_state.timeout_unit = unit;
1654 }
1655
1656 ret = kbd_set_state_safe(&new_state, &state);
1657 if (ret)
1658 goto out;
1659
1660 ret = count;
1661 out:
1662 mutex_unlock(&kbd_led_mutex);
1663 return ret;
1664 }
1665
1666 static ssize_t kbd_led_timeout_show(struct device *dev,
1667 struct device_attribute *attr, char *buf)
1668 {
1669 struct kbd_state state;
1670 int value;
1671 int ret;
1672 int len;
1673 u8 unit;
1674
1675 ret = kbd_get_state(&state);
1676 if (ret)
1677 return ret;
1678
1679 if (kbd_timeout_ac_supported && power_supply_is_system_supplied() > 0) {
1680 value = state.timeout_value_ac;
1681 unit = state.timeout_unit_ac;
1682 } else {
1683 value = state.timeout_value;
1684 unit = state.timeout_unit;
1685 }
1686
1687 len = sprintf(buf, "%d", value);
1688
1689 switch (unit) {
1690 case KBD_TIMEOUT_SECONDS:
1691 return len + sprintf(buf+len, "s\n");
1692 case KBD_TIMEOUT_MINUTES:
1693 return len + sprintf(buf+len, "m\n");
1694 case KBD_TIMEOUT_HOURS:
1695 return len + sprintf(buf+len, "h\n");
1696 case KBD_TIMEOUT_DAYS:
1697 return len + sprintf(buf+len, "d\n");
1698 default:
1699 return -EINVAL;
1700 }
1701
1702 return len;
1703 }
1704
1705 static DEVICE_ATTR(stop_timeout, S_IRUGO | S_IWUSR,
1706 kbd_led_timeout_show, kbd_led_timeout_store);
1707
1708 static const char * const kbd_led_triggers[] = {
1709 "keyboard",
1710 "touchpad",
1711 NULL,
1712 "mouse",
1713 };
1714
1715 static ssize_t kbd_led_triggers_store(struct device *dev,
1716 struct device_attribute *attr,
1717 const char *buf, size_t count)
1718 {
1719 struct kbd_state new_state;
1720 struct kbd_state state;
1721 bool triggers_enabled = false;
1722 int trigger_bit = -1;
1723 char trigger[21];
1724 int i, ret;
1725
1726 ret = sscanf(buf, "%20s", trigger);
1727 if (ret != 1)
1728 return -EINVAL;
1729
1730 if (trigger[0] != '+' && trigger[0] != '-')
1731 return -EINVAL;
1732
1733 mutex_lock(&kbd_led_mutex);
1734
1735 ret = kbd_get_state(&state);
1736 if (ret)
1737 goto out;
1738
1739 if (kbd_triggers_supported)
1740 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);
1741
1742 if (kbd_triggers_supported) {
1743 for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) {
1744 if (!(kbd_info.triggers & BIT(i)))
1745 continue;
1746 if (!kbd_led_triggers[i])
1747 continue;
1748 if (strcmp(trigger+1, kbd_led_triggers[i]) != 0)
1749 continue;
1750 if (trigger[0] == '+' &&
1751 triggers_enabled && (state.triggers & BIT(i))) {
1752 ret = count;
1753 goto out;
1754 }
1755 if (trigger[0] == '-' &&
1756 (!triggers_enabled || !(state.triggers & BIT(i)))) {
1757 ret = count;
1758 goto out;
1759 }
1760 trigger_bit = i;
1761 break;
1762 }
1763 }
1764
1765 if (trigger_bit == -1) {
1766 ret = -EINVAL;
1767 goto out;
1768 }
1769
1770 new_state = state;
1771 if (trigger[0] == '+')
1772 new_state.triggers |= BIT(trigger_bit);
1773 else {
1774 new_state.triggers &= ~BIT(trigger_bit);
1775
1776
1777
1778
1779
1780 if (trigger_bit == 1)
1781 new_state.triggers &= ~BIT(2);
1782 }
1783 if ((kbd_info.triggers & new_state.triggers) !=
1784 new_state.triggers) {
1785 ret = -EINVAL;
1786 goto out;
1787 }
1788 if (new_state.triggers && !triggers_enabled) {
1789 new_state.mode_bit = KBD_MODE_BIT_TRIGGER;
1790 kbd_set_level(&new_state, kbd_previous_level);
1791 } else if (new_state.triggers == 0) {
1792 kbd_set_level(&new_state, 0);
1793 }
1794 if (!(kbd_info.modes & BIT(new_state.mode_bit))) {
1795 ret = -EINVAL;
1796 goto out;
1797 }
1798 ret = kbd_set_state_safe(&new_state, &state);
1799 if (ret)
1800 goto out;
1801 if (new_state.mode_bit != KBD_MODE_BIT_OFF)
1802 kbd_previous_mode_bit = new_state.mode_bit;
1803 ret = count;
1804 out:
1805 mutex_unlock(&kbd_led_mutex);
1806 return ret;
1807 }
1808
1809 static ssize_t kbd_led_triggers_show(struct device *dev,
1810 struct device_attribute *attr, char *buf)
1811 {
1812 struct kbd_state state;
1813 bool triggers_enabled;
1814 int level, i, ret;
1815 int len = 0;
1816
1817 ret = kbd_get_state(&state);
1818 if (ret)
1819 return ret;
1820
1821 len = 0;
1822
1823 if (kbd_triggers_supported) {
1824 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);
1825 level = kbd_get_level(&state);
1826 for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) {
1827 if (!(kbd_info.triggers & BIT(i)))
1828 continue;
1829 if (!kbd_led_triggers[i])
1830 continue;
1831 if ((triggers_enabled || level <= 0) &&
1832 (state.triggers & BIT(i)))
1833 buf[len++] = '+';
1834 else
1835 buf[len++] = '-';
1836 len += sprintf(buf+len, "%s ", kbd_led_triggers[i]);
1837 }
1838 }
1839
1840 if (len)
1841 buf[len - 1] = '\n';
1842
1843 return len;
1844 }
1845
1846 static DEVICE_ATTR(start_triggers, S_IRUGO | S_IWUSR,
1847 kbd_led_triggers_show, kbd_led_triggers_store);
1848
1849 static ssize_t kbd_led_als_enabled_store(struct device *dev,
1850 struct device_attribute *attr,
1851 const char *buf, size_t count)
1852 {
1853 struct kbd_state new_state;
1854 struct kbd_state state;
1855 bool triggers_enabled = false;
1856 int enable;
1857 int ret;
1858
1859 ret = kstrtoint(buf, 0, &enable);
1860 if (ret)
1861 return ret;
1862
1863 mutex_lock(&kbd_led_mutex);
1864
1865 ret = kbd_get_state(&state);
1866 if (ret)
1867 goto out;
1868
1869 if (enable == kbd_is_als_mode_bit(state.mode_bit)) {
1870 ret = count;
1871 goto out;
1872 }
1873
1874 new_state = state;
1875
1876 if (kbd_triggers_supported)
1877 triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit);
1878
1879 if (enable) {
1880 if (triggers_enabled)
1881 new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS;
1882 else
1883 new_state.mode_bit = KBD_MODE_BIT_ALS;
1884 } else {
1885 if (triggers_enabled) {
1886 new_state.mode_bit = KBD_MODE_BIT_TRIGGER;
1887 kbd_set_level(&new_state, kbd_previous_level);
1888 } else {
1889 new_state.mode_bit = KBD_MODE_BIT_ON;
1890 }
1891 }
1892 if (!(kbd_info.modes & BIT(new_state.mode_bit))) {
1893 ret = -EINVAL;
1894 goto out;
1895 }
1896
1897 ret = kbd_set_state_safe(&new_state, &state);
1898 if (ret)
1899 goto out;
1900 kbd_previous_mode_bit = new_state.mode_bit;
1901
1902 ret = count;
1903 out:
1904 mutex_unlock(&kbd_led_mutex);
1905 return ret;
1906 }
1907
1908 static ssize_t kbd_led_als_enabled_show(struct device *dev,
1909 struct device_attribute *attr,
1910 char *buf)
1911 {
1912 struct kbd_state state;
1913 bool enabled = false;
1914 int ret;
1915
1916 ret = kbd_get_state(&state);
1917 if (ret)
1918 return ret;
1919 enabled = kbd_is_als_mode_bit(state.mode_bit);
1920
1921 return sprintf(buf, "%d\n", enabled ? 1 : 0);
1922 }
1923
1924 static DEVICE_ATTR(als_enabled, S_IRUGO | S_IWUSR,
1925 kbd_led_als_enabled_show, kbd_led_als_enabled_store);
1926
1927 static ssize_t kbd_led_als_setting_store(struct device *dev,
1928 struct device_attribute *attr,
1929 const char *buf, size_t count)
1930 {
1931 struct kbd_state state;
1932 struct kbd_state new_state;
1933 u8 setting;
1934 int ret;
1935
1936 ret = kstrtou8(buf, 10, &setting);
1937 if (ret)
1938 return ret;
1939
1940 mutex_lock(&kbd_led_mutex);
1941
1942 ret = kbd_get_state(&state);
1943 if (ret)
1944 goto out;
1945
1946 new_state = state;
1947 new_state.als_setting = setting;
1948
1949 ret = kbd_set_state_safe(&new_state, &state);
1950 if (ret)
1951 goto out;
1952
1953 ret = count;
1954 out:
1955 mutex_unlock(&kbd_led_mutex);
1956 return ret;
1957 }
1958
1959 static ssize_t kbd_led_als_setting_show(struct device *dev,
1960 struct device_attribute *attr,
1961 char *buf)
1962 {
1963 struct kbd_state state;
1964 int ret;
1965
1966 ret = kbd_get_state(&state);
1967 if (ret)
1968 return ret;
1969
1970 return sprintf(buf, "%d\n", state.als_setting);
1971 }
1972
1973 static DEVICE_ATTR(als_setting, S_IRUGO | S_IWUSR,
1974 kbd_led_als_setting_show, kbd_led_als_setting_store);
1975
1976 static struct attribute *kbd_led_attrs[] = {
1977 &dev_attr_stop_timeout.attr,
1978 &dev_attr_start_triggers.attr,
1979 NULL,
1980 };
1981
1982 static const struct attribute_group kbd_led_group = {
1983 .attrs = kbd_led_attrs,
1984 };
1985
1986 static struct attribute *kbd_led_als_attrs[] = {
1987 &dev_attr_als_enabled.attr,
1988 &dev_attr_als_setting.attr,
1989 NULL,
1990 };
1991
1992 static const struct attribute_group kbd_led_als_group = {
1993 .attrs = kbd_led_als_attrs,
1994 };
1995
1996 static const struct attribute_group *kbd_led_groups[] = {
1997 &kbd_led_group,
1998 &kbd_led_als_group,
1999 NULL,
2000 };
2001
2002 static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
2003 {
2004 int ret;
2005 u16 num;
2006 struct kbd_state state;
2007
2008 if (kbd_get_max_level()) {
2009 ret = kbd_get_state(&state);
2010 if (ret)
2011 return 0;
2012 ret = kbd_get_level(&state);
2013 if (ret < 0)
2014 return 0;
2015 return ret;
2016 }
2017
2018 if (kbd_get_valid_token_counts()) {
2019 ret = kbd_get_first_active_token_bit();
2020 if (ret < 0)
2021 return 0;
2022 for (num = kbd_token_bits; num != 0 && ret > 0; --ret)
2023 num &= num - 1;
2024 if (num == 0)
2025 return 0;
2026 return ffs(num) - 1;
2027 }
2028
2029 pr_warn("Keyboard brightness level control not supported\n");
2030 return 0;
2031 }
2032
2033 static int kbd_led_level_set(struct led_classdev *led_cdev,
2034 enum led_brightness value)
2035 {
2036 enum led_brightness new_value = value;
2037 struct kbd_state state;
2038 struct kbd_state new_state;
2039 u16 num;
2040 int ret;
2041
2042 mutex_lock(&kbd_led_mutex);
2043
2044 if (kbd_get_max_level()) {
2045 ret = kbd_get_state(&state);
2046 if (ret)
2047 goto out;
2048 new_state = state;
2049 ret = kbd_set_level(&new_state, value);
2050 if (ret)
2051 goto out;
2052 ret = kbd_set_state_safe(&new_state, &state);
2053 } else if (kbd_get_valid_token_counts()) {
2054 for (num = kbd_token_bits; num != 0 && value > 0; --value)
2055 num &= num - 1;
2056 if (num == 0)
2057 ret = 0;
2058 else
2059 ret = kbd_set_token_bit(ffs(num) - 1);
2060 } else {
2061 pr_warn("Keyboard brightness level control not supported\n");
2062 ret = -ENXIO;
2063 }
2064
2065 out:
2066 if (ret == 0)
2067 kbd_led_level = new_value;
2068
2069 mutex_unlock(&kbd_led_mutex);
2070 return ret;
2071 }
2072
2073 static struct led_classdev kbd_led = {
2074 .name = "dell::kbd_backlight",
2075 .flags = LED_BRIGHT_HW_CHANGED,
2076 .brightness_set_blocking = kbd_led_level_set,
2077 .brightness_get = kbd_led_level_get,
2078 .groups = kbd_led_groups,
2079 };
2080
2081 static int __init kbd_led_init(struct device *dev)
2082 {
2083 int ret;
2084
2085 kbd_init();
2086 if (!kbd_led_present)
2087 return -ENODEV;
2088 if (!kbd_als_supported)
2089 kbd_led_groups[1] = NULL;
2090 kbd_led.max_brightness = kbd_get_max_level();
2091 if (!kbd_led.max_brightness) {
2092 kbd_led.max_brightness = kbd_get_valid_token_counts();
2093 if (kbd_led.max_brightness)
2094 kbd_led.max_brightness--;
2095 }
2096
2097 kbd_led_level = kbd_led_level_get(NULL);
2098
2099 ret = led_classdev_register(dev, &kbd_led);
2100 if (ret)
2101 kbd_led_present = false;
2102
2103 return ret;
2104 }
2105
2106 static void brightness_set_exit(struct led_classdev *led_cdev,
2107 enum led_brightness value)
2108 {
2109
2110 };
2111
2112 static void kbd_led_exit(void)
2113 {
2114 if (!kbd_led_present)
2115 return;
2116 kbd_led.brightness_set = brightness_set_exit;
2117 led_classdev_unregister(&kbd_led);
2118 }
2119
2120 static int dell_laptop_notifier_call(struct notifier_block *nb,
2121 unsigned long action, void *data)
2122 {
2123 bool changed = false;
2124 enum led_brightness new_kbd_led_level;
2125
2126 switch (action) {
2127 case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:
2128 if (!kbd_led_present)
2129 break;
2130
2131 mutex_lock(&kbd_led_mutex);
2132 new_kbd_led_level = kbd_led_level_get(&kbd_led);
2133 if (kbd_led_level != new_kbd_led_level) {
2134 kbd_led_level = new_kbd_led_level;
2135 changed = true;
2136 }
2137 mutex_unlock(&kbd_led_mutex);
2138
2139 if (changed)
2140 led_classdev_notify_brightness_hw_changed(&kbd_led,
2141 kbd_led_level);
2142 break;
2143 }
2144
2145 return NOTIFY_OK;
2146 }
2147
2148 static struct notifier_block dell_laptop_notifier = {
2149 .notifier_call = dell_laptop_notifier_call,
2150 };
2151
2152 static int micmute_led_set(struct led_classdev *led_cdev,
2153 enum led_brightness brightness)
2154 {
2155 struct calling_interface_buffer buffer;
2156 struct calling_interface_token *token;
2157 int state = brightness != LED_OFF;
2158
2159 if (state == 0)
2160 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE);
2161 else
2162 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE);
2163
2164 if (!token)
2165 return -ENODEV;
2166
2167 dell_fill_request(&buffer, token->location, token->value, 0, 0);
2168 dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
2169
2170 return 0;
2171 }
2172
2173 static struct led_classdev micmute_led_cdev = {
2174 .name = "platform::micmute",
2175 .max_brightness = 1,
2176 .brightness_set_blocking = micmute_led_set,
2177 .default_trigger = "audio-micmute",
2178 };
2179
2180 static int __init dell_init(void)
2181 {
2182 struct calling_interface_token *token;
2183 int max_intensity = 0;
2184 int ret;
2185
2186 if (!dmi_check_system(dell_device_table))
2187 return -ENODEV;
2188
2189 quirks = NULL;
2190
2191 dmi_check_system(dell_quirks);
2192
2193 ret = platform_driver_register(&platform_driver);
2194 if (ret)
2195 goto fail_platform_driver;
2196 platform_device = platform_device_alloc("dell-laptop", -1);
2197 if (!platform_device) {
2198 ret = -ENOMEM;
2199 goto fail_platform_device1;
2200 }
2201 ret = platform_device_add(platform_device);
2202 if (ret)
2203 goto fail_platform_device2;
2204
2205 ret = dell_setup_rfkill();
2206
2207 if (ret) {
2208 pr_warn("Unable to setup rfkill\n");
2209 goto fail_rfkill;
2210 }
2211
2212 if (quirks && quirks->touchpad_led)
2213 touchpad_led_init(&platform_device->dev);
2214
2215 kbd_led_init(&platform_device->dev);
2216
2217 dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
2218 debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
2219 &dell_debugfs_fops);
2220
2221 dell_laptop_register_notifier(&dell_laptop_notifier);
2222
2223 if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) &&
2224 dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE) &&
2225 !dell_privacy_has_mic_mute()) {
2226 micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
2227 ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev);
2228 if (ret < 0)
2229 goto fail_led;
2230 micmute_led_registered = true;
2231 }
2232
2233 if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
2234 return 0;
2235
2236 token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
2237 if (token) {
2238 struct calling_interface_buffer buffer;
2239
2240 dell_fill_request(&buffer, token->location, 0, 0, 0);
2241 ret = dell_send_request(&buffer,
2242 CLASS_TOKEN_READ, SELECT_TOKEN_AC);
2243 if (ret == 0)
2244 max_intensity = buffer.output[3];
2245 }
2246
2247 if (max_intensity) {
2248 struct backlight_properties props;
2249 memset(&props, 0, sizeof(struct backlight_properties));
2250 props.type = BACKLIGHT_PLATFORM;
2251 props.max_brightness = max_intensity;
2252 dell_backlight_device = backlight_device_register("dell_backlight",
2253 &platform_device->dev,
2254 NULL,
2255 &dell_ops,
2256 &props);
2257
2258 if (IS_ERR(dell_backlight_device)) {
2259 ret = PTR_ERR(dell_backlight_device);
2260 dell_backlight_device = NULL;
2261 goto fail_backlight;
2262 }
2263
2264 dell_backlight_device->props.brightness =
2265 dell_get_intensity(dell_backlight_device);
2266 if (dell_backlight_device->props.brightness < 0) {
2267 ret = dell_backlight_device->props.brightness;
2268 goto fail_get_brightness;
2269 }
2270 backlight_update_status(dell_backlight_device);
2271 }
2272
2273 return 0;
2274
2275 fail_get_brightness:
2276 backlight_device_unregister(dell_backlight_device);
2277 fail_backlight:
2278 if (micmute_led_registered)
2279 led_classdev_unregister(&micmute_led_cdev);
2280 fail_led:
2281 dell_cleanup_rfkill();
2282 fail_rfkill:
2283 platform_device_del(platform_device);
2284 fail_platform_device2:
2285 platform_device_put(platform_device);
2286 fail_platform_device1:
2287 platform_driver_unregister(&platform_driver);
2288 fail_platform_driver:
2289 return ret;
2290 }
2291
2292 static void __exit dell_exit(void)
2293 {
2294 dell_laptop_unregister_notifier(&dell_laptop_notifier);
2295 debugfs_remove_recursive(dell_laptop_dir);
2296 if (quirks && quirks->touchpad_led)
2297 touchpad_led_exit();
2298 kbd_led_exit();
2299 backlight_device_unregister(dell_backlight_device);
2300 if (micmute_led_registered)
2301 led_classdev_unregister(&micmute_led_cdev);
2302 dell_cleanup_rfkill();
2303 if (platform_device) {
2304 platform_device_unregister(platform_device);
2305 platform_driver_unregister(&platform_driver);
2306 }
2307 }
2308
2309
2310
2311
2312
2313
2314
2315
2316 late_initcall(dell_init);
2317 module_exit(dell_exit);
2318
2319 MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
2320 MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
2321 MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
2322 MODULE_DESCRIPTION("Dell laptop driver");
2323 MODULE_LICENSE("GPL");