xref: /linux/drivers/platform/x86/fujitsu-laptop.c (revision 90d32e92011eaae8e70a9169b4e7acf4ca8f9d3a)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*-*-linux-c-*-*/
3 
4 /*
5   Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@just42.net>
6   Copyright (C) 2008 Peter Gruber <nokos@gmx.net>
7   Copyright (C) 2008 Tony Vroon <tony@linx.net>
8   Based on earlier work:
9     Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
10     Adrian Yee <brewt-fujitsu@brewt.org>
11 
12   Templated from msi-laptop.c and thinkpad_acpi.c which is copyright
13   by its respective authors.
14 
15  */
16 
17 /*
18  * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
19  * features made available on a range of Fujitsu laptops including the
20  * P2xxx/P5xxx/S6xxx/S7xxx series.
21  *
22  * This driver implements a vendor-specific backlight control interface for
23  * Fujitsu laptops and provides support for hotkeys present on certain Fujitsu
24  * laptops.
25  *
26  * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and
27  * P8010.  It should work on most P-series and S-series Lifebooks, but
28  * YMMV.
29  *
30  * The module parameter use_alt_lcd_levels switches between different ACPI
31  * brightness controls which are used by different Fujitsu laptops.  In most
32  * cases the correct method is automatically detected. "use_alt_lcd_levels=1"
33  * is applicable for a Fujitsu Lifebook S6410 if autodetection fails.
34  *
35  */
36 
37 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
38 
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/init.h>
42 #include <linux/acpi.h>
43 #include <linux/bitops.h>
44 #include <linux/dmi.h>
45 #include <linux/backlight.h>
46 #include <linux/fb.h>
47 #include <linux/input.h>
48 #include <linux/input/sparse-keymap.h>
49 #include <linux/kfifo.h>
50 #include <linux/leds.h>
51 #include <linux/platform_device.h>
52 #include <linux/power_supply.h>
53 #include <acpi/battery.h>
54 #include <acpi/video.h>
55 
56 #define FUJITSU_DRIVER_VERSION		"0.6.0"
57 
58 #define FUJITSU_LCD_N_LEVELS		8
59 
60 #define ACPI_FUJITSU_CLASS		"fujitsu"
61 #define ACPI_FUJITSU_BL_HID		"FUJ02B1"
62 #define ACPI_FUJITSU_BL_DRIVER_NAME	"Fujitsu laptop FUJ02B1 ACPI brightness driver"
63 #define ACPI_FUJITSU_BL_DEVICE_NAME	"Fujitsu FUJ02B1"
64 #define ACPI_FUJITSU_LAPTOP_HID		"FUJ02E3"
65 #define ACPI_FUJITSU_LAPTOP_DRIVER_NAME	"Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
66 #define ACPI_FUJITSU_LAPTOP_DEVICE_NAME	"Fujitsu FUJ02E3"
67 
68 #define ACPI_FUJITSU_NOTIFY_CODE	0x80
69 
70 /* FUNC interface - command values */
71 #define FUNC_FLAGS			BIT(12)
72 #define FUNC_LEDS			(BIT(12) | BIT(0))
73 #define FUNC_BUTTONS			(BIT(12) | BIT(1))
74 #define FUNC_BACKLIGHT			(BIT(12) | BIT(2))
75 
76 /* FUNC interface - responses */
77 #define UNSUPPORTED_CMD			0x80000000
78 
79 /* FUNC interface - status flags */
80 #define FLAG_RFKILL			BIT(5)
81 #define FLAG_LID			BIT(8)
82 #define FLAG_DOCK			BIT(9)
83 #define FLAG_TOUCHPAD_TOGGLE		BIT(26)
84 #define FLAG_MICMUTE			BIT(29)
85 #define FLAG_SOFTKEYS			(FLAG_RFKILL | FLAG_TOUCHPAD_TOGGLE | FLAG_MICMUTE)
86 
87 /* FUNC interface - LED control */
88 #define FUNC_LED_OFF			BIT(0)
89 #define FUNC_LED_ON			(BIT(0) | BIT(16) | BIT(17))
90 #define LOGOLAMP_POWERON		BIT(13)
91 #define LOGOLAMP_ALWAYS			BIT(14)
92 #define KEYBOARD_LAMPS			BIT(8)
93 #define RADIO_LED_ON			BIT(5)
94 #define ECO_LED				BIT(16)
95 #define ECO_LED_ON			BIT(19)
96 
97 /* FUNC interface - backlight power control */
98 #define BACKLIGHT_PARAM_POWER		BIT(2)
99 #define BACKLIGHT_OFF			(BIT(0) | BIT(1))
100 #define BACKLIGHT_ON			0
101 
102 /* FUNC interface - battery control interface */
103 #define FUNC_S006_METHOD		0x1006
104 #define CHARGE_CONTROL_RW		0x21
105 
106 /* Scancodes read from the GIRB register */
107 #define KEY1_CODE			0x410
108 #define KEY2_CODE			0x411
109 #define KEY3_CODE			0x412
110 #define KEY4_CODE			0x413
111 #define KEY5_CODE			0x420
112 
113 /* Hotkey ringbuffer limits */
114 #define MAX_HOTKEY_RINGBUFFER_SIZE	100
115 #define RINGBUFFERSIZE			40
116 
117 /* Module parameters */
118 static int use_alt_lcd_levels = -1;
119 static bool disable_brightness_adjust;
120 
121 /* Device controlling the backlight and associated keys */
122 struct fujitsu_bl {
123 	struct input_dev *input;
124 	char phys[32];
125 	struct backlight_device *bl_device;
126 	unsigned int max_brightness;
127 	unsigned int brightness_level;
128 };
129 
130 static struct fujitsu_bl *fujitsu_bl;
131 
132 /* Device used to access hotkeys and other features on the laptop */
133 struct fujitsu_laptop {
134 	struct input_dev *input;
135 	char phys[32];
136 	struct platform_device *pf_device;
137 	struct kfifo fifo;
138 	spinlock_t fifo_lock;
139 	int flags_supported;
140 	int flags_state;
141 	bool charge_control_supported;
142 };
143 
144 static struct acpi_device *fext;
145 
146 /* Fujitsu ACPI interface function */
147 
148 static int call_fext_func(struct acpi_device *device,
149 			  int func, int op, int feature, int state)
150 {
151 	union acpi_object params[4] = {
152 		{ .integer.type = ACPI_TYPE_INTEGER, .integer.value = func },
153 		{ .integer.type = ACPI_TYPE_INTEGER, .integer.value = op },
154 		{ .integer.type = ACPI_TYPE_INTEGER, .integer.value = feature },
155 		{ .integer.type = ACPI_TYPE_INTEGER, .integer.value = state }
156 	};
157 	struct acpi_object_list arg_list = { 4, params };
158 	unsigned long long value;
159 	acpi_status status;
160 
161 	status = acpi_evaluate_integer(device->handle, "FUNC", &arg_list,
162 				       &value);
163 	if (ACPI_FAILURE(status)) {
164 		acpi_handle_err(device->handle, "Failed to evaluate FUNC\n");
165 		return -ENODEV;
166 	}
167 
168 	acpi_handle_debug(device->handle,
169 			  "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) returned 0x%x\n",
170 			  func, op, feature, state, (int)value);
171 	return value;
172 }
173 
174 /* Battery charge control code */
175 static ssize_t charge_control_end_threshold_store(struct device *dev,
176 				struct device_attribute *attr,
177 				const char *buf, size_t count)
178 {
179 	int cc_end_value, s006_cc_return;
180 	int value, ret;
181 
182 	ret = kstrtouint(buf, 10, &value);
183 	if (ret)
184 		return ret;
185 
186 	if (value < 50 || value > 100)
187 		return -EINVAL;
188 
189 	cc_end_value = value * 0x100 + 0x20;
190 	s006_cc_return = call_fext_func(fext, FUNC_S006_METHOD,
191 					CHARGE_CONTROL_RW, cc_end_value, 0x0);
192 	if (s006_cc_return < 0)
193 		return s006_cc_return;
194 	/*
195 	 * The S006 0x21 method returns 0x00 in case the provided value
196 	 * is invalid.
197 	 */
198 	if (s006_cc_return == 0x00)
199 		return -EINVAL;
200 
201 	return count;
202 }
203 
204 static ssize_t charge_control_end_threshold_show(struct device *dev,
205 				struct device_attribute *attr,
206 				char *buf)
207 {
208 	int status;
209 
210 	status = call_fext_func(fext, FUNC_S006_METHOD,
211 				CHARGE_CONTROL_RW, 0x21, 0x0);
212 	if (status < 0)
213 		return status;
214 
215 	return sysfs_emit(buf, "%d\n", status);
216 }
217 
218 static DEVICE_ATTR_RW(charge_control_end_threshold);
219 
220 /* ACPI battery hook */
221 static int fujitsu_battery_add_hook(struct power_supply *battery,
222 			       struct acpi_battery_hook *hook)
223 {
224 	return device_create_file(&battery->dev,
225 				  &dev_attr_charge_control_end_threshold);
226 }
227 
228 static int fujitsu_battery_remove_hook(struct power_supply *battery,
229 				  struct acpi_battery_hook *hook)
230 {
231 	device_remove_file(&battery->dev,
232 			   &dev_attr_charge_control_end_threshold);
233 
234 	return 0;
235 }
236 
237 static struct acpi_battery_hook battery_hook = {
238 	.add_battery = fujitsu_battery_add_hook,
239 	.remove_battery = fujitsu_battery_remove_hook,
240 	.name = "Fujitsu Battery Extension",
241 };
242 
243 /*
244  * These functions are intended to be called from acpi_fujitsu_laptop_add and
245  * acpi_fujitsu_laptop_remove.
246  */
247 static int fujitsu_battery_charge_control_add(struct acpi_device *device)
248 {
249 	struct fujitsu_laptop *priv = acpi_driver_data(device);
250 	int s006_cc_return;
251 
252 	priv->charge_control_supported = false;
253 	/*
254 	 * Check if the S006 0x21 method exists by trying to get the current
255 	 * battery charge limit.
256 	 */
257 	s006_cc_return = call_fext_func(fext, FUNC_S006_METHOD,
258 					CHARGE_CONTROL_RW, 0x21, 0x0);
259 	if (s006_cc_return < 0)
260 		return s006_cc_return;
261 	if (s006_cc_return == UNSUPPORTED_CMD)
262 		return -ENODEV;
263 
264 	priv->charge_control_supported = true;
265 	battery_hook_register(&battery_hook);
266 
267 	return 0;
268 }
269 
270 static void fujitsu_battery_charge_control_remove(struct acpi_device *device)
271 {
272 	struct fujitsu_laptop *priv = acpi_driver_data(device);
273 
274 	if (priv->charge_control_supported)
275 		battery_hook_unregister(&battery_hook);
276 }
277 
278 /* Hardware access for LCD brightness control */
279 
280 static int set_lcd_level(struct acpi_device *device, int level)
281 {
282 	struct fujitsu_bl *priv = acpi_driver_data(device);
283 	acpi_status status;
284 	char *method;
285 
286 	switch (use_alt_lcd_levels) {
287 	case -1:
288 		if (acpi_has_method(device->handle, "SBL2"))
289 			method = "SBL2";
290 		else
291 			method = "SBLL";
292 		break;
293 	case 1:
294 		method = "SBL2";
295 		break;
296 	default:
297 		method = "SBLL";
298 		break;
299 	}
300 
301 	acpi_handle_debug(device->handle, "set lcd level via %s [%d]\n", method,
302 			  level);
303 
304 	if (level < 0 || level >= priv->max_brightness)
305 		return -EINVAL;
306 
307 	status = acpi_execute_simple_method(device->handle, method, level);
308 	if (ACPI_FAILURE(status)) {
309 		acpi_handle_err(device->handle, "Failed to evaluate %s\n",
310 				method);
311 		return -ENODEV;
312 	}
313 
314 	priv->brightness_level = level;
315 
316 	return 0;
317 }
318 
319 static int get_lcd_level(struct acpi_device *device)
320 {
321 	struct fujitsu_bl *priv = acpi_driver_data(device);
322 	unsigned long long state = 0;
323 	acpi_status status = AE_OK;
324 
325 	acpi_handle_debug(device->handle, "get lcd level via GBLL\n");
326 
327 	status = acpi_evaluate_integer(device->handle, "GBLL", NULL, &state);
328 	if (ACPI_FAILURE(status))
329 		return 0;
330 
331 	priv->brightness_level = state & 0x0fffffff;
332 
333 	return priv->brightness_level;
334 }
335 
336 static int get_max_brightness(struct acpi_device *device)
337 {
338 	struct fujitsu_bl *priv = acpi_driver_data(device);
339 	unsigned long long state = 0;
340 	acpi_status status = AE_OK;
341 
342 	acpi_handle_debug(device->handle, "get max lcd level via RBLL\n");
343 
344 	status = acpi_evaluate_integer(device->handle, "RBLL", NULL, &state);
345 	if (ACPI_FAILURE(status))
346 		return -1;
347 
348 	priv->max_brightness = state;
349 
350 	return priv->max_brightness;
351 }
352 
353 /* Backlight device stuff */
354 
355 static int bl_get_brightness(struct backlight_device *b)
356 {
357 	struct acpi_device *device = bl_get_data(b);
358 
359 	return b->props.power == FB_BLANK_POWERDOWN ? 0 : get_lcd_level(device);
360 }
361 
362 static int bl_update_status(struct backlight_device *b)
363 {
364 	struct acpi_device *device = bl_get_data(b);
365 
366 	if (fext) {
367 		if (b->props.power == FB_BLANK_POWERDOWN)
368 			call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
369 				       BACKLIGHT_PARAM_POWER, BACKLIGHT_OFF);
370 		else
371 			call_fext_func(fext, FUNC_BACKLIGHT, 0x1,
372 				       BACKLIGHT_PARAM_POWER, BACKLIGHT_ON);
373 	}
374 
375 	return set_lcd_level(device, b->props.brightness);
376 }
377 
378 static const struct backlight_ops fujitsu_bl_ops = {
379 	.get_brightness = bl_get_brightness,
380 	.update_status = bl_update_status,
381 };
382 
383 static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
384 			char *buf)
385 {
386 	struct fujitsu_laptop *priv = dev_get_drvdata(dev);
387 
388 	if (!(priv->flags_supported & FLAG_LID))
389 		return sysfs_emit(buf, "unknown\n");
390 	if (priv->flags_state & FLAG_LID)
391 		return sysfs_emit(buf, "open\n");
392 	else
393 		return sysfs_emit(buf, "closed\n");
394 }
395 
396 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
397 			 char *buf)
398 {
399 	struct fujitsu_laptop *priv = dev_get_drvdata(dev);
400 
401 	if (!(priv->flags_supported & FLAG_DOCK))
402 		return sysfs_emit(buf, "unknown\n");
403 	if (priv->flags_state & FLAG_DOCK)
404 		return sysfs_emit(buf, "docked\n");
405 	else
406 		return sysfs_emit(buf, "undocked\n");
407 }
408 
409 static ssize_t radios_show(struct device *dev, struct device_attribute *attr,
410 			   char *buf)
411 {
412 	struct fujitsu_laptop *priv = dev_get_drvdata(dev);
413 
414 	if (!(priv->flags_supported & FLAG_RFKILL))
415 		return sysfs_emit(buf, "unknown\n");
416 	if (priv->flags_state & FLAG_RFKILL)
417 		return sysfs_emit(buf, "on\n");
418 	else
419 		return sysfs_emit(buf, "killed\n");
420 }
421 
422 static DEVICE_ATTR_RO(lid);
423 static DEVICE_ATTR_RO(dock);
424 static DEVICE_ATTR_RO(radios);
425 
426 static struct attribute *fujitsu_pf_attributes[] = {
427 	&dev_attr_lid.attr,
428 	&dev_attr_dock.attr,
429 	&dev_attr_radios.attr,
430 	NULL
431 };
432 
433 static const struct attribute_group fujitsu_pf_attribute_group = {
434 	.attrs = fujitsu_pf_attributes
435 };
436 
437 static struct platform_driver fujitsu_pf_driver = {
438 	.driver = {
439 		   .name = "fujitsu-laptop",
440 		   }
441 };
442 
443 /* ACPI device for LCD brightness control */
444 
445 static const struct key_entry keymap_backlight[] = {
446 	{ KE_KEY, true, { KEY_BRIGHTNESSUP } },
447 	{ KE_KEY, false, { KEY_BRIGHTNESSDOWN } },
448 	{ KE_END, 0 }
449 };
450 
451 static int acpi_fujitsu_bl_input_setup(struct acpi_device *device)
452 {
453 	struct fujitsu_bl *priv = acpi_driver_data(device);
454 	int ret;
455 
456 	priv->input = devm_input_allocate_device(&device->dev);
457 	if (!priv->input)
458 		return -ENOMEM;
459 
460 	snprintf(priv->phys, sizeof(priv->phys), "%s/video/input0",
461 		 acpi_device_hid(device));
462 
463 	priv->input->name = acpi_device_name(device);
464 	priv->input->phys = priv->phys;
465 	priv->input->id.bustype = BUS_HOST;
466 	priv->input->id.product = 0x06;
467 
468 	ret = sparse_keymap_setup(priv->input, keymap_backlight, NULL);
469 	if (ret)
470 		return ret;
471 
472 	return input_register_device(priv->input);
473 }
474 
475 static int fujitsu_backlight_register(struct acpi_device *device)
476 {
477 	struct fujitsu_bl *priv = acpi_driver_data(device);
478 	const struct backlight_properties props = {
479 		.brightness = priv->brightness_level,
480 		.max_brightness = priv->max_brightness - 1,
481 		.type = BACKLIGHT_PLATFORM
482 	};
483 	struct backlight_device *bd;
484 
485 	bd = devm_backlight_device_register(&device->dev, "fujitsu-laptop",
486 					    &device->dev, device,
487 					    &fujitsu_bl_ops, &props);
488 	if (IS_ERR(bd))
489 		return PTR_ERR(bd);
490 
491 	priv->bl_device = bd;
492 
493 	return 0;
494 }
495 
496 static int acpi_fujitsu_bl_add(struct acpi_device *device)
497 {
498 	struct fujitsu_bl *priv;
499 	int ret;
500 
501 	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
502 		return -ENODEV;
503 
504 	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
505 	if (!priv)
506 		return -ENOMEM;
507 
508 	fujitsu_bl = priv;
509 	strcpy(acpi_device_name(device), ACPI_FUJITSU_BL_DEVICE_NAME);
510 	strcpy(acpi_device_class(device), ACPI_FUJITSU_CLASS);
511 	device->driver_data = priv;
512 
513 	pr_info("ACPI: %s [%s]\n",
514 		acpi_device_name(device), acpi_device_bid(device));
515 
516 	if (get_max_brightness(device) <= 0)
517 		priv->max_brightness = FUJITSU_LCD_N_LEVELS;
518 	get_lcd_level(device);
519 
520 	ret = acpi_fujitsu_bl_input_setup(device);
521 	if (ret)
522 		return ret;
523 
524 	return fujitsu_backlight_register(device);
525 }
526 
527 /* Brightness notify */
528 
529 static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
530 {
531 	struct fujitsu_bl *priv = acpi_driver_data(device);
532 	int oldb, newb;
533 
534 	if (event != ACPI_FUJITSU_NOTIFY_CODE) {
535 		acpi_handle_info(device->handle, "unsupported event [0x%x]\n",
536 				 event);
537 		sparse_keymap_report_event(priv->input, -1, 1, true);
538 		return;
539 	}
540 
541 	oldb = priv->brightness_level;
542 	get_lcd_level(device);
543 	newb = priv->brightness_level;
544 
545 	acpi_handle_debug(device->handle,
546 			  "brightness button event [%i -> %i]\n", oldb, newb);
547 
548 	if (oldb == newb)
549 		return;
550 
551 	if (!disable_brightness_adjust)
552 		set_lcd_level(device, newb);
553 
554 	sparse_keymap_report_event(priv->input, oldb < newb, 1, true);
555 }
556 
557 /* ACPI device for hotkey handling */
558 
559 static const struct key_entry keymap_default[] = {
560 	{ KE_KEY, KEY1_CODE,            { KEY_PROG1 } },
561 	{ KE_KEY, KEY2_CODE,            { KEY_PROG2 } },
562 	{ KE_KEY, KEY3_CODE,            { KEY_PROG3 } },
563 	{ KE_KEY, KEY4_CODE,            { KEY_PROG4 } },
564 	{ KE_KEY, KEY5_CODE,            { KEY_RFKILL } },
565 	/* Soft keys read from status flags */
566 	{ KE_KEY, FLAG_RFKILL,          { KEY_RFKILL } },
567 	{ KE_KEY, FLAG_TOUCHPAD_TOGGLE, { KEY_TOUCHPAD_TOGGLE } },
568 	{ KE_KEY, FLAG_MICMUTE,         { KEY_MICMUTE } },
569 	{ KE_END, 0 }
570 };
571 
572 static const struct key_entry keymap_s64x0[] = {
573 	{ KE_KEY, KEY1_CODE, { KEY_SCREENLOCK } },	/* "Lock" */
574 	{ KE_KEY, KEY2_CODE, { KEY_HELP } },		/* "Mobility Center */
575 	{ KE_KEY, KEY3_CODE, { KEY_PROG3 } },
576 	{ KE_KEY, KEY4_CODE, { KEY_PROG4 } },
577 	{ KE_END, 0 }
578 };
579 
580 static const struct key_entry keymap_p8010[] = {
581 	{ KE_KEY, KEY1_CODE, { KEY_HELP } },		/* "Support" */
582 	{ KE_KEY, KEY2_CODE, { KEY_PROG2 } },
583 	{ KE_KEY, KEY3_CODE, { KEY_SWITCHVIDEOMODE } },	/* "Presentation" */
584 	{ KE_KEY, KEY4_CODE, { KEY_WWW } },		/* "WWW" */
585 	{ KE_END, 0 }
586 };
587 
588 static const struct key_entry *keymap = keymap_default;
589 
590 static int fujitsu_laptop_dmi_keymap_override(const struct dmi_system_id *id)
591 {
592 	pr_info("Identified laptop model '%s'\n", id->ident);
593 	keymap = id->driver_data;
594 	return 1;
595 }
596 
597 static const struct dmi_system_id fujitsu_laptop_dmi_table[] = {
598 	{
599 		.callback = fujitsu_laptop_dmi_keymap_override,
600 		.ident = "Fujitsu Siemens S6410",
601 		.matches = {
602 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
603 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
604 		},
605 		.driver_data = (void *)keymap_s64x0
606 	},
607 	{
608 		.callback = fujitsu_laptop_dmi_keymap_override,
609 		.ident = "Fujitsu Siemens S6420",
610 		.matches = {
611 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
612 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"),
613 		},
614 		.driver_data = (void *)keymap_s64x0
615 	},
616 	{
617 		.callback = fujitsu_laptop_dmi_keymap_override,
618 		.ident = "Fujitsu LifeBook P8010",
619 		.matches = {
620 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
621 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
622 		},
623 		.driver_data = (void *)keymap_p8010
624 	},
625 	{}
626 };
627 
628 static int acpi_fujitsu_laptop_input_setup(struct acpi_device *device)
629 {
630 	struct fujitsu_laptop *priv = acpi_driver_data(device);
631 	int ret;
632 
633 	priv->input = devm_input_allocate_device(&device->dev);
634 	if (!priv->input)
635 		return -ENOMEM;
636 
637 	snprintf(priv->phys, sizeof(priv->phys), "%s/input0",
638 		 acpi_device_hid(device));
639 
640 	priv->input->name = acpi_device_name(device);
641 	priv->input->phys = priv->phys;
642 	priv->input->id.bustype = BUS_HOST;
643 
644 	dmi_check_system(fujitsu_laptop_dmi_table);
645 	ret = sparse_keymap_setup(priv->input, keymap, NULL);
646 	if (ret)
647 		return ret;
648 
649 	return input_register_device(priv->input);
650 }
651 
652 static int fujitsu_laptop_platform_add(struct acpi_device *device)
653 {
654 	struct fujitsu_laptop *priv = acpi_driver_data(device);
655 	int ret;
656 
657 	priv->pf_device = platform_device_alloc("fujitsu-laptop", PLATFORM_DEVID_NONE);
658 	if (!priv->pf_device)
659 		return -ENOMEM;
660 
661 	platform_set_drvdata(priv->pf_device, priv);
662 
663 	ret = platform_device_add(priv->pf_device);
664 	if (ret)
665 		goto err_put_platform_device;
666 
667 	ret = sysfs_create_group(&priv->pf_device->dev.kobj,
668 				 &fujitsu_pf_attribute_group);
669 	if (ret)
670 		goto err_del_platform_device;
671 
672 	return 0;
673 
674 err_del_platform_device:
675 	platform_device_del(priv->pf_device);
676 err_put_platform_device:
677 	platform_device_put(priv->pf_device);
678 
679 	return ret;
680 }
681 
682 static void fujitsu_laptop_platform_remove(struct acpi_device *device)
683 {
684 	struct fujitsu_laptop *priv = acpi_driver_data(device);
685 
686 	sysfs_remove_group(&priv->pf_device->dev.kobj,
687 			   &fujitsu_pf_attribute_group);
688 	platform_device_unregister(priv->pf_device);
689 }
690 
691 static int logolamp_set(struct led_classdev *cdev,
692 			enum led_brightness brightness)
693 {
694 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
695 	int poweron = FUNC_LED_ON, always = FUNC_LED_ON;
696 	int ret;
697 
698 	if (brightness < LED_HALF)
699 		poweron = FUNC_LED_OFF;
700 
701 	if (brightness < LED_FULL)
702 		always = FUNC_LED_OFF;
703 
704 	ret = call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
705 	if (ret < 0)
706 		return ret;
707 
708 	return call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
709 }
710 
711 static enum led_brightness logolamp_get(struct led_classdev *cdev)
712 {
713 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
714 	int ret;
715 
716 	ret = call_fext_func(device, FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
717 	if (ret == FUNC_LED_ON)
718 		return LED_FULL;
719 
720 	ret = call_fext_func(device, FUNC_LEDS, 0x2, LOGOLAMP_POWERON, 0x0);
721 	if (ret == FUNC_LED_ON)
722 		return LED_HALF;
723 
724 	return LED_OFF;
725 }
726 
727 static int kblamps_set(struct led_classdev *cdev,
728 		       enum led_brightness brightness)
729 {
730 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
731 
732 	if (brightness >= LED_FULL)
733 		return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
734 				      FUNC_LED_ON);
735 	else
736 		return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
737 				      FUNC_LED_OFF);
738 }
739 
740 static enum led_brightness kblamps_get(struct led_classdev *cdev)
741 {
742 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
743 	enum led_brightness brightness = LED_OFF;
744 
745 	if (call_fext_func(device,
746 			   FUNC_LEDS, 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
747 		brightness = LED_FULL;
748 
749 	return brightness;
750 }
751 
752 static int radio_led_set(struct led_classdev *cdev,
753 			 enum led_brightness brightness)
754 {
755 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
756 
757 	if (brightness >= LED_FULL)
758 		return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
759 				      RADIO_LED_ON);
760 	else
761 		return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
762 				      0x0);
763 }
764 
765 static enum led_brightness radio_led_get(struct led_classdev *cdev)
766 {
767 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
768 	enum led_brightness brightness = LED_OFF;
769 
770 	if (call_fext_func(device, FUNC_FLAGS, 0x4, 0x0, 0x0) & RADIO_LED_ON)
771 		brightness = LED_FULL;
772 
773 	return brightness;
774 }
775 
776 static int eco_led_set(struct led_classdev *cdev,
777 		       enum led_brightness brightness)
778 {
779 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
780 	int curr;
781 
782 	curr = call_fext_func(device, FUNC_LEDS, 0x2, ECO_LED, 0x0);
783 	if (brightness >= LED_FULL)
784 		return call_fext_func(device, FUNC_LEDS, 0x1, ECO_LED,
785 				      curr | ECO_LED_ON);
786 	else
787 		return call_fext_func(device, FUNC_LEDS, 0x1, ECO_LED,
788 				      curr & ~ECO_LED_ON);
789 }
790 
791 static enum led_brightness eco_led_get(struct led_classdev *cdev)
792 {
793 	struct acpi_device *device = to_acpi_device(cdev->dev->parent);
794 	enum led_brightness brightness = LED_OFF;
795 
796 	if (call_fext_func(device, FUNC_LEDS, 0x2, ECO_LED, 0x0) & ECO_LED_ON)
797 		brightness = LED_FULL;
798 
799 	return brightness;
800 }
801 
802 static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
803 {
804 	struct fujitsu_laptop *priv = acpi_driver_data(device);
805 	struct led_classdev *led;
806 	int ret;
807 
808 	if (call_fext_func(device,
809 			   FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
810 		led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
811 		if (!led)
812 			return -ENOMEM;
813 
814 		led->name = "fujitsu::logolamp";
815 		led->brightness_set_blocking = logolamp_set;
816 		led->brightness_get = logolamp_get;
817 		ret = devm_led_classdev_register(&device->dev, led);
818 		if (ret)
819 			return ret;
820 	}
821 
822 	if ((call_fext_func(device,
823 			    FUNC_LEDS, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
824 	    (call_fext_func(device, FUNC_BUTTONS, 0x0, 0x0, 0x0) == 0x0)) {
825 		led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
826 		if (!led)
827 			return -ENOMEM;
828 
829 		led->name = "fujitsu::kblamps";
830 		led->brightness_set_blocking = kblamps_set;
831 		led->brightness_get = kblamps_get;
832 		ret = devm_led_classdev_register(&device->dev, led);
833 		if (ret)
834 			return ret;
835 	}
836 
837 	/*
838 	 * Some Fujitsu laptops have a radio toggle button in place of a slide
839 	 * switch and all such machines appear to also have an RF LED.  Based on
840 	 * comparing DSDT tables of four Fujitsu Lifebook models (E744, E751,
841 	 * S7110, S8420; the first one has a radio toggle button, the other
842 	 * three have slide switches), bit 17 of flags_supported (the value
843 	 * returned by method S000 of ACPI device FUJ02E3) seems to indicate
844 	 * whether given model has a radio toggle button.
845 	 */
846 	if (priv->flags_supported & BIT(17)) {
847 		led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
848 		if (!led)
849 			return -ENOMEM;
850 
851 		led->name = "fujitsu::radio_led";
852 		led->brightness_set_blocking = radio_led_set;
853 		led->brightness_get = radio_led_get;
854 		led->default_trigger = "rfkill-any";
855 		ret = devm_led_classdev_register(&device->dev, led);
856 		if (ret)
857 			return ret;
858 	}
859 
860 	/* Support for eco led is not always signaled in bit corresponding
861 	 * to the bit used to control the led. According to the DSDT table,
862 	 * bit 14 seems to indicate presence of said led as well.
863 	 * Confirm by testing the status.
864 	 */
865 	if ((call_fext_func(device, FUNC_LEDS, 0x0, 0x0, 0x0) & BIT(14)) &&
866 	    (call_fext_func(device,
867 			    FUNC_LEDS, 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
868 		led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
869 		if (!led)
870 			return -ENOMEM;
871 
872 		led->name = "fujitsu::eco_led";
873 		led->brightness_set_blocking = eco_led_set;
874 		led->brightness_get = eco_led_get;
875 		ret = devm_led_classdev_register(&device->dev, led);
876 		if (ret)
877 			return ret;
878 	}
879 
880 	return 0;
881 }
882 
883 static int acpi_fujitsu_laptop_add(struct acpi_device *device)
884 {
885 	struct fujitsu_laptop *priv;
886 	int ret, i = 0;
887 
888 	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
889 	if (!priv)
890 		return -ENOMEM;
891 
892 	WARN_ONCE(fext, "More than one FUJ02E3 ACPI device was found.  Driver may not work as intended.");
893 	fext = device;
894 
895 	strcpy(acpi_device_name(device), ACPI_FUJITSU_LAPTOP_DEVICE_NAME);
896 	strcpy(acpi_device_class(device), ACPI_FUJITSU_CLASS);
897 	device->driver_data = priv;
898 
899 	/* kfifo */
900 	spin_lock_init(&priv->fifo_lock);
901 	ret = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
902 			  GFP_KERNEL);
903 	if (ret)
904 		return ret;
905 
906 	pr_info("ACPI: %s [%s]\n",
907 		acpi_device_name(device), acpi_device_bid(device));
908 
909 	while (call_fext_func(device, FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0 &&
910 	       i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
911 		; /* No action, result is discarded */
912 	acpi_handle_debug(device->handle, "Discarded %i ringbuffer entries\n",
913 			  i);
914 
915 	priv->flags_supported = call_fext_func(device, FUNC_FLAGS, 0x0, 0x0,
916 					       0x0);
917 
918 	/* Make sure our bitmask of supported functions is cleared if the
919 	   RFKILL function block is not implemented, like on the S7020. */
920 	if (priv->flags_supported == UNSUPPORTED_CMD)
921 		priv->flags_supported = 0;
922 
923 	if (priv->flags_supported)
924 		priv->flags_state = call_fext_func(device, FUNC_FLAGS, 0x4, 0x0,
925 						   0x0);
926 
927 	/* Suspect this is a keymap of the application panel, print it */
928 	acpi_handle_info(device->handle, "BTNI: [0x%x]\n",
929 			 call_fext_func(device, FUNC_BUTTONS, 0x0, 0x0, 0x0));
930 
931 	/* Sync backlight power status */
932 	if (fujitsu_bl && fujitsu_bl->bl_device &&
933 	    acpi_video_get_backlight_type() == acpi_backlight_vendor) {
934 		if (call_fext_func(fext, FUNC_BACKLIGHT, 0x2,
935 				   BACKLIGHT_PARAM_POWER, 0x0) == BACKLIGHT_OFF)
936 			fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
937 		else
938 			fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
939 	}
940 
941 	ret = acpi_fujitsu_laptop_input_setup(device);
942 	if (ret)
943 		goto err_free_fifo;
944 
945 	ret = acpi_fujitsu_laptop_leds_register(device);
946 	if (ret)
947 		goto err_free_fifo;
948 
949 	ret = fujitsu_laptop_platform_add(device);
950 	if (ret)
951 		goto err_free_fifo;
952 
953 	ret = fujitsu_battery_charge_control_add(device);
954 	if (ret < 0)
955 		pr_warn("Unable to register battery charge control: %d\n", ret);
956 
957 	return 0;
958 
959 err_free_fifo:
960 	kfifo_free(&priv->fifo);
961 
962 	return ret;
963 }
964 
965 static void acpi_fujitsu_laptop_remove(struct acpi_device *device)
966 {
967 	struct fujitsu_laptop *priv = acpi_driver_data(device);
968 
969 	fujitsu_battery_charge_control_remove(device);
970 
971 	fujitsu_laptop_platform_remove(device);
972 
973 	kfifo_free(&priv->fifo);
974 }
975 
976 static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
977 {
978 	struct fujitsu_laptop *priv = acpi_driver_data(device);
979 	int ret;
980 
981 	ret = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
982 			      sizeof(scancode), &priv->fifo_lock);
983 	if (ret != sizeof(scancode)) {
984 		dev_info(&priv->input->dev, "Could not push scancode [0x%x]\n",
985 			 scancode);
986 		return;
987 	}
988 	sparse_keymap_report_event(priv->input, scancode, 1, false);
989 	dev_dbg(&priv->input->dev, "Push scancode into ringbuffer [0x%x]\n",
990 		scancode);
991 }
992 
993 static void acpi_fujitsu_laptop_release(struct acpi_device *device)
994 {
995 	struct fujitsu_laptop *priv = acpi_driver_data(device);
996 	int scancode, ret;
997 
998 	while (true) {
999 		ret = kfifo_out_locked(&priv->fifo, (unsigned char *)&scancode,
1000 				       sizeof(scancode), &priv->fifo_lock);
1001 		if (ret != sizeof(scancode))
1002 			return;
1003 		sparse_keymap_report_event(priv->input, scancode, 0, false);
1004 		dev_dbg(&priv->input->dev,
1005 			"Pop scancode from ringbuffer [0x%x]\n", scancode);
1006 	}
1007 }
1008 
1009 static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
1010 {
1011 	struct fujitsu_laptop *priv = acpi_driver_data(device);
1012 	unsigned long flags;
1013 	int scancode, i = 0;
1014 	unsigned int irb;
1015 
1016 	if (event != ACPI_FUJITSU_NOTIFY_CODE) {
1017 		acpi_handle_info(device->handle, "Unsupported event [0x%x]\n",
1018 				 event);
1019 		sparse_keymap_report_event(priv->input, -1, 1, true);
1020 		return;
1021 	}
1022 
1023 	if (priv->flags_supported)
1024 		priv->flags_state = call_fext_func(device, FUNC_FLAGS, 0x4, 0x0,
1025 						   0x0);
1026 
1027 	while ((irb = call_fext_func(device,
1028 				     FUNC_BUTTONS, 0x1, 0x0, 0x0)) != 0 &&
1029 	       i++ < MAX_HOTKEY_RINGBUFFER_SIZE) {
1030 		scancode = irb & 0x4ff;
1031 		if (sparse_keymap_entry_from_scancode(priv->input, scancode))
1032 			acpi_fujitsu_laptop_press(device, scancode);
1033 		else if (scancode == 0)
1034 			acpi_fujitsu_laptop_release(device);
1035 		else
1036 			acpi_handle_info(device->handle,
1037 					 "Unknown GIRB result [%x]\n", irb);
1038 	}
1039 
1040 	/*
1041 	 * First seen on the Skylake-based Lifebook E736/E746/E756), the
1042 	 * touchpad toggle hotkey (Fn+F4) is handled in software. Other models
1043 	 * have since added additional "soft keys". These are reported in the
1044 	 * status flags queried using FUNC_FLAGS.
1045 	 */
1046 	if (priv->flags_supported & (FLAG_SOFTKEYS)) {
1047 		flags = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
1048 		flags &= (FLAG_SOFTKEYS);
1049 		for_each_set_bit(i, &flags, BITS_PER_LONG)
1050 			sparse_keymap_report_event(priv->input, BIT(i), 1, true);
1051 	}
1052 }
1053 
1054 /* Initialization */
1055 
1056 static const struct acpi_device_id fujitsu_bl_device_ids[] = {
1057 	{ACPI_FUJITSU_BL_HID, 0},
1058 	{"", 0},
1059 };
1060 
1061 static struct acpi_driver acpi_fujitsu_bl_driver = {
1062 	.name = ACPI_FUJITSU_BL_DRIVER_NAME,
1063 	.class = ACPI_FUJITSU_CLASS,
1064 	.ids = fujitsu_bl_device_ids,
1065 	.ops = {
1066 		.add = acpi_fujitsu_bl_add,
1067 		.notify = acpi_fujitsu_bl_notify,
1068 		},
1069 };
1070 
1071 static const struct acpi_device_id fujitsu_laptop_device_ids[] = {
1072 	{ACPI_FUJITSU_LAPTOP_HID, 0},
1073 	{"", 0},
1074 };
1075 
1076 static struct acpi_driver acpi_fujitsu_laptop_driver = {
1077 	.name = ACPI_FUJITSU_LAPTOP_DRIVER_NAME,
1078 	.class = ACPI_FUJITSU_CLASS,
1079 	.ids = fujitsu_laptop_device_ids,
1080 	.ops = {
1081 		.add = acpi_fujitsu_laptop_add,
1082 		.remove = acpi_fujitsu_laptop_remove,
1083 		.notify = acpi_fujitsu_laptop_notify,
1084 		},
1085 };
1086 
1087 static const struct acpi_device_id fujitsu_ids[] __used = {
1088 	{ACPI_FUJITSU_BL_HID, 0},
1089 	{ACPI_FUJITSU_LAPTOP_HID, 0},
1090 	{"", 0}
1091 };
1092 MODULE_DEVICE_TABLE(acpi, fujitsu_ids);
1093 
1094 static int __init fujitsu_init(void)
1095 {
1096 	int ret;
1097 
1098 	ret = acpi_bus_register_driver(&acpi_fujitsu_bl_driver);
1099 	if (ret)
1100 		return ret;
1101 
1102 	/* Register platform stuff */
1103 
1104 	ret = platform_driver_register(&fujitsu_pf_driver);
1105 	if (ret)
1106 		goto err_unregister_acpi;
1107 
1108 	/* Register laptop driver */
1109 
1110 	ret = acpi_bus_register_driver(&acpi_fujitsu_laptop_driver);
1111 	if (ret)
1112 		goto err_unregister_platform_driver;
1113 
1114 	pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n");
1115 
1116 	return 0;
1117 
1118 err_unregister_platform_driver:
1119 	platform_driver_unregister(&fujitsu_pf_driver);
1120 err_unregister_acpi:
1121 	acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver);
1122 
1123 	return ret;
1124 }
1125 
1126 static void __exit fujitsu_cleanup(void)
1127 {
1128 	acpi_bus_unregister_driver(&acpi_fujitsu_laptop_driver);
1129 
1130 	platform_driver_unregister(&fujitsu_pf_driver);
1131 
1132 	acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver);
1133 
1134 	pr_info("driver unloaded\n");
1135 }
1136 
1137 module_init(fujitsu_init);
1138 module_exit(fujitsu_cleanup);
1139 
1140 module_param(use_alt_lcd_levels, int, 0644);
1141 MODULE_PARM_DESC(use_alt_lcd_levels, "Interface used for setting LCD brightness level (-1 = auto, 0 = force SBLL, 1 = force SBL2)");
1142 module_param(disable_brightness_adjust, bool, 0644);
1143 MODULE_PARM_DESC(disable_brightness_adjust, "Disable LCD brightness adjustment");
1144 
1145 MODULE_AUTHOR("Jonathan Woithe, Peter Gruber, Tony Vroon");
1146 MODULE_DESCRIPTION("Fujitsu laptop extras support");
1147 MODULE_VERSION(FUJITSU_DRIVER_VERSION);
1148 MODULE_LICENSE("GPL");
1149