static int keys_proc_show(struct seq_file *m, void *v) { struct toshiba_acpi_dev *dev = m->private; u32 hci_result; u32 value; if (!dev->key_event_valid && dev->system_event_supported) { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); if (hci_result == HCI_SUCCESS) { dev->key_event_valid = 1; dev->last_key_event = value; } else if (hci_result == HCI_EMPTY) { /* */ } else if (hci_result == HCI_NOT_SUPPORTED) { /* */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); pr_notice("Re-enabled hotkeys\n"); } else { pr_err("Error reading hotkey status\n"); return -EIO; } } seq_printf(m, "hotkey_ready: %d\n", dev->key_event_valid); seq_printf(m, "hotkey: 0x%04x\n", dev->last_key_event); return 0; }
static int keys_proc_show(struct seq_file *m, void *v) { struct toshiba_acpi_dev *dev = m->private; u32 hci_result; u32 value; if (!dev->key_event_valid && dev->system_event_supported) { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); if (hci_result == HCI_SUCCESS) { dev->key_event_valid = 1; dev->last_key_event = value; } else if (hci_result == HCI_EMPTY) { /* better luck next time */ } else if (hci_result == HCI_NOT_SUPPORTED) { /* This is a workaround for an unresolved issue on * some machines where system events sporadically * become disabled. */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); pr_notice("Re-enabled hotkeys\n"); } else { pr_err("Error reading hotkey status\n"); return -EIO; } } seq_printf(m, "hotkey_ready: %d\n", dev->key_event_valid); seq_printf(m, "hotkey: 0x%04x\n", dev->last_key_event); return 0; }
static ssize_t fan_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct toshiba_acpi_dev *dev = PDE(file->f_path.dentry->d_inode)->data; char cmd[42]; size_t len; int value; u32 hci_result; len = min(count, sizeof(cmd) - 1); if (copy_from_user(cmd, buf, len)) return -EFAULT; cmd[len] = '\0'; if (sscanf(cmd, " force_on : %i", &value) == 1 && value >= 0 && value <= 1) { hci_write1(dev, HCI_FAN, value, &hci_result); if (hci_result != HCI_SUCCESS) return -EIO; else dev->force_fan = value; } else { return -EINVAL; } return count; }
static int set_lcd(struct toshiba_acpi_dev *dev, int value) { u32 hci_result; value = value << HCI_LCD_BRIGHTNESS_SHIFT; hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result); return hci_result == HCI_SUCCESS ? 0 : -EIO; }
static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable) { u32 hci_result; u32 value = !enable; hci_write1(dev, HCI_TR_BACKLIGHT, value, &hci_result); return hci_result == HCI_SUCCESS ? 0 : -EIO; }
static int toshiba_acpi_resume(struct acpi_device *acpi_dev) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 result; if (dev->hotkey_dev) hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result); return 0; }
static int toshiba_acpi_suspend(struct device *device) { struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); u32 result; if (dev->hotkey_dev) hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE, &result); return 0; }
static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) { u32 hci_result; if (dev->tr_backlight_supported) { bool enable = !value; int ret = set_tr_backlight_status(dev, enable); if (ret) return ret; if (value) value--; } value = value << HCI_LCD_BRIGHTNESS_SHIFT; hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result); return hci_result == HCI_SUCCESS ? 0 : -EIO; }
static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 hci_result, value; int retries = 3; int scancode; if (event != 0x80) return; if (dev->info_supported) { scancode = toshiba_acpi_query_hotkey(dev); if (scancode < 0) pr_err("Failed to query hotkey event\n"); else if (scancode != 0) toshiba_acpi_report_hotkey(dev, scancode); } else if (dev->system_event_supported) { do { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); switch (hci_result) { case HCI_SUCCESS: toshiba_acpi_report_hotkey(dev, (int)value); break; case HCI_NOT_SUPPORTED: /* */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); pr_notice("Re-enabled hotkeys\n"); /* */ default: retries--; break; } } while (retries && hci_result != HCI_EMPTY); } }
static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) { acpi_status status; acpi_handle ec_handle, handle; int error; u32 hci_result; dev->hotkey_dev = input_allocate_device(); if (!dev->hotkey_dev) { pr_info("Unable to register input device\n"); return -ENOMEM; } dev->hotkey_dev->name = "Toshiba input device"; dev->hotkey_dev->phys = "toshiba_acpi/input0"; dev->hotkey_dev->id.bustype = BUS_HOST; error = sparse_keymap_setup(dev->hotkey_dev, toshiba_acpi_keymap, NULL); if (error) goto err_free_dev; /* */ status = AE_ERROR; ec_handle = ec_get_handle(); if (ec_handle) status = acpi_get_handle(ec_handle, "NTFY", &handle); if (ACPI_SUCCESS(status)) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); error = i8042_install_filter(toshiba_acpi_i8042_filter); if (error) { pr_err("Error installing key filter\n"); goto err_free_keymap; } dev->ntfy_supported = 1; } /* */ status = acpi_get_handle(dev->acpi_dev->handle, "INFO", &handle); if (ACPI_SUCCESS(status)) { dev->info_supported = 1; } else { hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); if (hci_result == HCI_SUCCESS) dev->system_event_supported = 1; } if (!dev->info_supported && !dev->system_event_supported) { pr_warn("No hotkey query interface found\n"); goto err_remove_filter; } status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); if (ACPI_FAILURE(status)) { pr_info("Unable to enable hotkeys\n"); error = -ENODEV; goto err_remove_filter; } error = input_register_device(dev->hotkey_dev); if (error) { pr_info("Unable to register input device\n"); goto err_remove_filter; } hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &hci_result); return 0; err_remove_filter: if (dev->ntfy_supported) i8042_remove_filter(toshiba_acpi_i8042_filter); err_free_keymap: sparse_keymap_free(dev->hotkey_dev); err_free_dev: input_free_device(dev->hotkey_dev); dev->hotkey_dev = NULL; return error; }
static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) { acpi_status status; acpi_handle ec_handle, handle; int error; u32 hci_result; dev->hotkey_dev = input_allocate_device(); if (!dev->hotkey_dev) { pr_info("Unable to register input device\n"); return -ENOMEM; } dev->hotkey_dev->name = "Toshiba input device"; dev->hotkey_dev->phys = "toshiba_acpi/input0"; dev->hotkey_dev->id.bustype = BUS_HOST; error = sparse_keymap_setup(dev->hotkey_dev, toshiba_acpi_keymap, NULL); if (error) goto err_free_dev; /* * For some machines the SCI responsible for providing hotkey * notification doesn't fire. We can trigger the notification * whenever the Fn key is pressed using the NTFY method, if * supported, so if it's present set up an i8042 key filter * for this purpose. */ status = AE_ERROR; ec_handle = ec_get_handle(); if (ec_handle) status = acpi_get_handle(ec_handle, "NTFY", &handle); if (ACPI_SUCCESS(status)) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); error = i8042_install_filter(toshiba_acpi_i8042_filter); if (error) { pr_err("Error installing key filter\n"); goto err_free_keymap; } dev->ntfy_supported = 1; } /* * Determine hotkey query interface. Prefer using the INFO * method when it is available. */ status = acpi_get_handle(dev->acpi_dev->handle, "INFO", &handle); if (ACPI_SUCCESS(status)) { dev->info_supported = 1; } else { hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); if (hci_result == HCI_SUCCESS) dev->system_event_supported = 1; } if (!dev->info_supported && !dev->system_event_supported) { pr_warn("No hotkey query interface found\n"); goto err_remove_filter; } status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); if (ACPI_FAILURE(status)) { pr_info("Unable to enable hotkeys\n"); error = -ENODEV; goto err_remove_filter; } error = input_register_device(dev->hotkey_dev); if (error) { pr_info("Unable to register input device\n"); goto err_remove_filter; } hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &hci_result); return 0; err_remove_filter: if (dev->ntfy_supported) i8042_remove_filter(toshiba_acpi_i8042_filter); err_free_keymap: sparse_keymap_free(dev->hotkey_dev); err_free_dev: input_free_device(dev->hotkey_dev); dev->hotkey_dev = NULL; return error; }