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;
}
Esempio n. 5
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}