Lines Matching +full:brightness +full:- +full:level
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*-*-linux-c-*-*/
10 Adrian Yee <brewt-fujitsu@brewt.org>
12 Templated from msi-laptop.c and thinkpad_acpi.c which is copyright
18 * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
22 * This driver implements a vendor-specific backlight control interface for
27 * P8010. It should work on most P-series and S-series Lifebooks, but
31 * brightness controls which are used by different Fujitsu laptops. In most
47 #include <linux/input/sparse-keymap.h>
61 #define ACPI_FUJITSU_BL_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver"
69 /* FUNC interface - command values */
75 /* FUNC interface - responses */
78 /* FUNC interface - status flags */
86 /* FUNC interface - LED control */
96 /* FUNC interface - backlight power control */
101 /* FUNC interface - battery control interface */
121 static int use_alt_lcd_levels = -1;
164 status = acpi_evaluate_integer(device->handle, "FUNC", &arg_list, in call_fext_func()
167 acpi_handle_err(device->handle, "Failed to evaluate FUNC\n"); in call_fext_func()
168 return -ENODEV; in call_fext_func()
171 acpi_handle_debug(device->handle, in call_fext_func()
190 return -EINVAL; in charge_control_end_threshold_store()
202 return -EINVAL; in charge_control_end_threshold_store()
227 return device_create_file(&battery->dev, in fujitsu_battery_add_hook()
234 device_remove_file(&battery->dev, in fujitsu_battery_remove_hook()
255 priv->charge_control_supported = false; in fujitsu_battery_charge_control_add()
265 return -ENODEV; in fujitsu_battery_charge_control_add()
267 priv->charge_control_supported = true; in fujitsu_battery_charge_control_add()
277 if (priv->charge_control_supported) in fujitsu_battery_charge_control_remove()
281 /* Hardware access for LCD brightness control */
283 static int set_lcd_level(struct acpi_device *device, int level) in set_lcd_level() argument
290 case -1: in set_lcd_level()
291 if (acpi_has_method(device->handle, "SBL2")) in set_lcd_level()
304 acpi_handle_debug(device->handle, "set lcd level via %s [%d]\n", method, in set_lcd_level()
305 level); in set_lcd_level()
307 if (level < 0 || level >= priv->max_brightness) in set_lcd_level()
308 return -EINVAL; in set_lcd_level()
310 status = acpi_execute_simple_method(device->handle, method, level); in set_lcd_level()
312 acpi_handle_err(device->handle, "Failed to evaluate %s\n", in set_lcd_level()
314 return -ENODEV; in set_lcd_level()
317 priv->brightness_level = level; in set_lcd_level()
328 acpi_handle_debug(device->handle, "get lcd level via GBLL\n"); in get_lcd_level()
330 status = acpi_evaluate_integer(device->handle, "GBLL", NULL, &state); in get_lcd_level()
334 priv->brightness_level = state & 0x0fffffff; in get_lcd_level()
336 return priv->brightness_level; in get_lcd_level()
345 acpi_handle_debug(device->handle, "get max lcd level via RBLL\n"); in get_max_brightness()
347 status = acpi_evaluate_integer(device->handle, "RBLL", NULL, &state); in get_max_brightness()
349 return -1; in get_max_brightness()
351 priv->max_brightness = state; in get_max_brightness()
353 return priv->max_brightness; in get_max_brightness()
362 return b->props.power == BACKLIGHT_POWER_OFF ? 0 : get_lcd_level(device); in bl_get_brightness()
370 if (b->props.power == BACKLIGHT_POWER_OFF) in bl_update_status()
378 return set_lcd_level(device, b->props.brightness); in bl_update_status()
391 if (!(priv->flags_supported & FLAG_LID)) in lid_show()
393 if (priv->flags_state & FLAG_LID) in lid_show()
404 if (!(priv->flags_supported & FLAG_DOCK)) in dock_show()
406 if (priv->flags_state & FLAG_DOCK) in dock_show()
417 if (!(priv->flags_supported & FLAG_RFKILL)) in radios_show()
419 if (priv->flags_state & FLAG_RFKILL) in radios_show()
442 .name = "fujitsu-laptop",
446 /* ACPI device for LCD brightness control */
459 priv->input = devm_input_allocate_device(&device->dev); in acpi_fujitsu_bl_input_setup()
460 if (!priv->input) in acpi_fujitsu_bl_input_setup()
461 return -ENOMEM; in acpi_fujitsu_bl_input_setup()
463 snprintf(priv->phys, sizeof(priv->phys), "%s/video/input0", in acpi_fujitsu_bl_input_setup()
466 priv->input->name = acpi_device_name(device); in acpi_fujitsu_bl_input_setup()
467 priv->input->phys = priv->phys; in acpi_fujitsu_bl_input_setup()
468 priv->input->id.bustype = BUS_HOST; in acpi_fujitsu_bl_input_setup()
469 priv->input->id.product = 0x06; in acpi_fujitsu_bl_input_setup()
471 ret = sparse_keymap_setup(priv->input, keymap_backlight, NULL); in acpi_fujitsu_bl_input_setup()
475 return input_register_device(priv->input); in acpi_fujitsu_bl_input_setup()
482 .brightness = priv->brightness_level, in fujitsu_backlight_register()
483 .max_brightness = priv->max_brightness - 1, in fujitsu_backlight_register()
488 bd = devm_backlight_device_register(&device->dev, "fujitsu-laptop", in fujitsu_backlight_register()
489 &device->dev, device, in fujitsu_backlight_register()
494 priv->bl_device = bd; in fujitsu_backlight_register()
505 return -ENODEV; in acpi_fujitsu_bl_add()
507 priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL); in acpi_fujitsu_bl_add()
509 return -ENOMEM; in acpi_fujitsu_bl_add()
514 device->driver_data = priv; in acpi_fujitsu_bl_add()
520 priv->max_brightness = FUJITSU_LCD_N_LEVELS; in acpi_fujitsu_bl_add()
530 /* Brightness notify */
538 acpi_handle_info(device->handle, "unsupported event [0x%x]\n", in acpi_fujitsu_bl_notify()
540 sparse_keymap_report_event(priv->input, -1, 1, true); in acpi_fujitsu_bl_notify()
544 oldb = priv->brightness_level; in acpi_fujitsu_bl_notify()
546 newb = priv->brightness_level; in acpi_fujitsu_bl_notify()
548 acpi_handle_debug(device->handle, in acpi_fujitsu_bl_notify()
549 "brightness button event [%i -> %i]\n", oldb, newb); in acpi_fujitsu_bl_notify()
557 sparse_keymap_report_event(priv->input, oldb < newb, 1, true); in acpi_fujitsu_bl_notify()
595 { KE_KEY, KEY4_CODE, { KEY_EMAIL } }, /* "E-mail" */
607 pr_info("Identified laptop model '%s'\n", id->ident); in fujitsu_laptop_dmi_keymap_override()
608 keymap = id->driver_data; in fujitsu_laptop_dmi_keymap_override()
657 priv->input = devm_input_allocate_device(&device->dev); in acpi_fujitsu_laptop_input_setup()
658 if (!priv->input) in acpi_fujitsu_laptop_input_setup()
659 return -ENOMEM; in acpi_fujitsu_laptop_input_setup()
661 snprintf(priv->phys, sizeof(priv->phys), "%s/input0", in acpi_fujitsu_laptop_input_setup()
664 priv->input->name = acpi_device_name(device); in acpi_fujitsu_laptop_input_setup()
665 priv->input->phys = priv->phys; in acpi_fujitsu_laptop_input_setup()
666 priv->input->id.bustype = BUS_HOST; in acpi_fujitsu_laptop_input_setup()
669 ret = sparse_keymap_setup(priv->input, keymap, NULL); in acpi_fujitsu_laptop_input_setup()
673 return input_register_device(priv->input); in acpi_fujitsu_laptop_input_setup()
681 priv->pf_device = platform_device_alloc("fujitsu-laptop", PLATFORM_DEVID_NONE); in fujitsu_laptop_platform_add()
682 if (!priv->pf_device) in fujitsu_laptop_platform_add()
683 return -ENOMEM; in fujitsu_laptop_platform_add()
685 platform_set_drvdata(priv->pf_device, priv); in fujitsu_laptop_platform_add()
687 ret = platform_device_add(priv->pf_device); in fujitsu_laptop_platform_add()
691 ret = sysfs_create_group(&priv->pf_device->dev.kobj, in fujitsu_laptop_platform_add()
699 platform_device_del(priv->pf_device); in fujitsu_laptop_platform_add()
701 platform_device_put(priv->pf_device); in fujitsu_laptop_platform_add()
710 sysfs_remove_group(&priv->pf_device->dev.kobj, in fujitsu_laptop_platform_remove()
712 platform_device_unregister(priv->pf_device); in fujitsu_laptop_platform_remove()
716 enum led_brightness brightness) in logolamp_set() argument
718 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in logolamp_set()
722 if (brightness < LED_HALF) in logolamp_set()
725 if (brightness < LED_FULL) in logolamp_set()
737 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in logolamp_get()
752 enum led_brightness brightness) in kblamps_set() argument
754 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in kblamps_set()
756 if (brightness >= LED_FULL) in kblamps_set()
766 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in kblamps_get()
767 enum led_brightness brightness = LED_OFF; in kblamps_get() local
771 brightness = LED_FULL; in kblamps_get()
773 return brightness; in kblamps_get()
777 enum led_brightness brightness) in radio_led_set() argument
779 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in radio_led_set()
781 if (brightness >= LED_FULL) in radio_led_set()
791 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in radio_led_get()
792 enum led_brightness brightness = LED_OFF; in radio_led_get() local
795 brightness = LED_FULL; in radio_led_get()
797 return brightness; in radio_led_get()
801 enum led_brightness brightness) in eco_led_set() argument
803 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in eco_led_set()
807 if (brightness >= LED_FULL) in eco_led_set()
817 struct acpi_device *device = to_acpi_device(cdev->dev->parent); in eco_led_get()
818 enum led_brightness brightness = LED_OFF; in eco_led_get() local
821 brightness = LED_FULL; in eco_led_get()
823 return brightness; in eco_led_get()
834 led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL); in acpi_fujitsu_laptop_leds_register()
836 return -ENOMEM; in acpi_fujitsu_laptop_leds_register()
838 led->name = "fujitsu::logolamp"; in acpi_fujitsu_laptop_leds_register()
839 led->brightness_set_blocking = logolamp_set; in acpi_fujitsu_laptop_leds_register()
840 led->brightness_get = logolamp_get; in acpi_fujitsu_laptop_leds_register()
841 ret = devm_led_classdev_register(&device->dev, led); in acpi_fujitsu_laptop_leds_register()
849 led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL); in acpi_fujitsu_laptop_leds_register()
851 return -ENOMEM; in acpi_fujitsu_laptop_leds_register()
853 led->name = "fujitsu::kblamps"; in acpi_fujitsu_laptop_leds_register()
854 led->brightness_set_blocking = kblamps_set; in acpi_fujitsu_laptop_leds_register()
855 led->brightness_get = kblamps_get; in acpi_fujitsu_laptop_leds_register()
856 ret = devm_led_classdev_register(&device->dev, led); in acpi_fujitsu_laptop_leds_register()
870 if (priv->flags_supported & BIT(17)) { in acpi_fujitsu_laptop_leds_register()
871 led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL); in acpi_fujitsu_laptop_leds_register()
873 return -ENOMEM; in acpi_fujitsu_laptop_leds_register()
875 led->name = "fujitsu::radio_led"; in acpi_fujitsu_laptop_leds_register()
876 led->brightness_set_blocking = radio_led_set; in acpi_fujitsu_laptop_leds_register()
877 led->brightness_get = radio_led_get; in acpi_fujitsu_laptop_leds_register()
878 led->default_trigger = "rfkill-any"; in acpi_fujitsu_laptop_leds_register()
879 ret = devm_led_classdev_register(&device->dev, led); in acpi_fujitsu_laptop_leds_register()
892 led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL); in acpi_fujitsu_laptop_leds_register()
894 return -ENOMEM; in acpi_fujitsu_laptop_leds_register()
896 led->name = "fujitsu::eco_led"; in acpi_fujitsu_laptop_leds_register()
897 led->brightness_set_blocking = eco_led_set; in acpi_fujitsu_laptop_leds_register()
898 led->brightness_get = eco_led_get; in acpi_fujitsu_laptop_leds_register()
899 ret = devm_led_classdev_register(&device->dev, led); in acpi_fujitsu_laptop_leds_register()
912 priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL); in acpi_fujitsu_laptop_add()
914 return -ENOMEM; in acpi_fujitsu_laptop_add()
921 device->driver_data = priv; in acpi_fujitsu_laptop_add()
924 spin_lock_init(&priv->fifo_lock); in acpi_fujitsu_laptop_add()
925 ret = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int), in acpi_fujitsu_laptop_add()
936 acpi_handle_debug(device->handle, "Discarded %i ringbuffer entries\n", in acpi_fujitsu_laptop_add()
939 priv->flags_supported = call_fext_func(device, FUNC_FLAGS, 0x0, 0x0, in acpi_fujitsu_laptop_add()
944 if (priv->flags_supported == UNSUPPORTED_CMD) in acpi_fujitsu_laptop_add()
945 priv->flags_supported = 0; in acpi_fujitsu_laptop_add()
947 if (priv->flags_supported) in acpi_fujitsu_laptop_add()
948 priv->flags_state = call_fext_func(device, FUNC_FLAGS, 0x4, 0x0, in acpi_fujitsu_laptop_add()
952 acpi_handle_info(device->handle, "BTNI: [0x%x]\n", in acpi_fujitsu_laptop_add()
956 if (fujitsu_bl && fujitsu_bl->bl_device && in acpi_fujitsu_laptop_add()
960 fujitsu_bl->bl_device->props.power = BACKLIGHT_POWER_OFF; in acpi_fujitsu_laptop_add()
962 fujitsu_bl->bl_device->props.power = BACKLIGHT_POWER_ON; in acpi_fujitsu_laptop_add()
984 kfifo_free(&priv->fifo); in acpi_fujitsu_laptop_add()
997 kfifo_free(&priv->fifo); in acpi_fujitsu_laptop_remove()
1005 ret = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode, in acpi_fujitsu_laptop_press()
1006 sizeof(scancode), &priv->fifo_lock); in acpi_fujitsu_laptop_press()
1008 dev_info(&priv->input->dev, "Could not push scancode [0x%x]\n", in acpi_fujitsu_laptop_press()
1012 sparse_keymap_report_event(priv->input, scancode, 1, false); in acpi_fujitsu_laptop_press()
1013 dev_dbg(&priv->input->dev, "Push scancode into ringbuffer [0x%x]\n", in acpi_fujitsu_laptop_press()
1023 ret = kfifo_out_locked(&priv->fifo, (unsigned char *)&scancode, in acpi_fujitsu_laptop_release()
1024 sizeof(scancode), &priv->fifo_lock); in acpi_fujitsu_laptop_release()
1027 sparse_keymap_report_event(priv->input, scancode, 0, false); in acpi_fujitsu_laptop_release()
1028 dev_dbg(&priv->input->dev, in acpi_fujitsu_laptop_release()
1041 acpi_handle_info(device->handle, "Unsupported event [0x%x]\n", in acpi_fujitsu_laptop_notify()
1043 sparse_keymap_report_event(priv->input, -1, 1, true); in acpi_fujitsu_laptop_notify()
1047 if (priv->flags_supported) in acpi_fujitsu_laptop_notify()
1048 priv->flags_state = call_fext_func(device, FUNC_FLAGS, 0x4, 0x0, in acpi_fujitsu_laptop_notify()
1055 if (sparse_keymap_entry_from_scancode(priv->input, scancode)) in acpi_fujitsu_laptop_notify()
1060 acpi_handle_info(device->handle, in acpi_fujitsu_laptop_notify()
1065 * First seen on the Skylake-based Lifebook E736/E746/E756), the in acpi_fujitsu_laptop_notify()
1070 if (priv->flags_supported & (FLAG_SOFTKEYS)) { in acpi_fujitsu_laptop_notify()
1074 sparse_keymap_report_event(priv->input, BIT(i), 1, true); in acpi_fujitsu_laptop_notify()
1165 MODULE_PARM_DESC(use_alt_lcd_levels, "Interface used for setting LCD brightness level (-1 = auto, 0…
1167 MODULE_PARM_DESC(disable_brightness_adjust, "Disable LCD brightness adjustment");