Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62cce752 authored by Seth Forshee's avatar Seth Forshee Committed by Matthew Garrett
Browse files

toshiba_acpi: Only register backlight device when interface is read/write



Currently the backlight device is registered unconditionally, but many
(probably most) Toshibas either don't support HCI_LCD_BRIGHTNESS or only
support reading from it. This patch adds a test of HCI_LCD_BRIGHTNESS
during initialization and only registers the backlight device if this
interface supports both reads and writes.

Cc: Akio Idehara <zbe64533@gmail.com>
Signed-off-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Signed-off-by: default avatarMatthew Garrett <mjg@redhat.com>
parent 20a769c1
Loading
Loading
Loading
Loading
+56 −24
Original line number Diff line number Diff line
@@ -480,9 +480,8 @@ static const struct rfkill_ops toshiba_rfk_ops = {

static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;

static int get_lcd(struct backlight_device *bd)
static int __get_lcd_brightness(struct toshiba_acpi_dev *dev)
{
	struct toshiba_acpi_dev *dev = bl_get_data(bd);
	u32 hci_result;
	u32 value;

@@ -493,6 +492,12 @@ static int get_lcd(struct backlight_device *bd)
	return -EIO;
}

static int get_lcd_brightness(struct backlight_device *bd)
{
	struct toshiba_acpi_dev *dev = bl_get_data(bd);
	return __get_lcd_brightness(dev);
}

static int lcd_proc_show(struct seq_file *m, void *v)
{
	struct toshiba_acpi_dev *dev = m->private;
@@ -501,7 +506,7 @@ static int lcd_proc_show(struct seq_file *m, void *v)
	if (!dev->backlight_dev)
		return -ENODEV;

	value = get_lcd(dev->backlight_dev);
	value = get_lcd_brightness(dev->backlight_dev);
	if (value >= 0) {
		seq_printf(m, "brightness:              %d\n", value);
		seq_printf(m, "brightness_levels:       %d\n",
@@ -518,7 +523,7 @@ static int lcd_proc_open(struct inode *inode, struct file *file)
	return single_open(file, lcd_proc_show, PDE(inode)->data);
}

static int set_lcd(struct toshiba_acpi_dev *dev, int value)
static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
{
	u32 hci_result;

@@ -530,7 +535,7 @@ static int set_lcd(struct toshiba_acpi_dev *dev, int value)
static int set_lcd_status(struct backlight_device *bd)
{
	struct toshiba_acpi_dev *dev = bl_get_data(bd);
	return set_lcd(dev, bd->props.brightness);
	return set_lcd_brightness(dev, bd->props.brightness);
}

static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
@@ -549,7 +554,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,

	if (sscanf(cmd, " brightness : %i", &value) == 1 &&
	    value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
		ret = set_lcd(dev, value);
		ret = set_lcd_brightness(dev, value);
		if (ret == 0)
			ret = count;
	} else {
@@ -860,7 +865,7 @@ static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
}

static const struct backlight_ops toshiba_backlight_data = {
        .get_brightness = get_lcd,
	.get_brightness = get_lcd_brightness,
	.update_status  = set_lcd_status,
};

@@ -1020,6 +1025,47 @@ static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
	return error;
}

static int __devinit toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
{
	struct backlight_properties props;
	int brightness;
	int ret;

	/*
	 * Some machines don't support the backlight methods at all, and
	 * others support it read-only. Either of these is pretty useless,
	 * so only register the backlight device if the backlight method
	 * supports both reads and writes.
	 */
	brightness = __get_lcd_brightness(dev);
	if (brightness < 0)
		return 0;
	ret = set_lcd_brightness(dev, brightness);
	if (ret) {
		pr_debug("Backlight method is read-only, disabling backlight support\n");
		return 0;
	}

	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
	memset(&props, 0, sizeof(props));

	dev->backlight_dev = backlight_device_register("toshiba",
						       &dev->acpi_dev->dev,
						       dev,
						       &toshiba_backlight_data,
						       &props);
	if (IS_ERR(dev->backlight_dev)) {
		ret = PTR_ERR(dev->backlight_dev);
		pr_err("Could not register toshiba backlight device\n");
		dev->backlight_dev = NULL;
		return ret;
	}

	dev->backlight_dev->props.brightness = brightness;
	return 0;
}

static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
{
	struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
@@ -1078,7 +1124,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
	u32 dummy;
	bool bt_present;
	int ret = 0;
	struct backlight_properties props;

	if (toshiba_acpi)
		return -EBUSY;
@@ -1104,22 +1149,9 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)

	mutex_init(&dev->mutex);

	memset(&props, 0, sizeof(props));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
	dev->backlight_dev = backlight_device_register("toshiba",
						       &acpi_dev->dev,
						       dev,
						       &toshiba_backlight_data,
						       &props);
	if (IS_ERR(dev->backlight_dev)) {
		ret = PTR_ERR(dev->backlight_dev);

		pr_err("Could not register toshiba backlight device\n");
		dev->backlight_dev = NULL;
	ret = toshiba_acpi_setup_backlight(dev);
	if (ret)
		goto error;
	}
	dev->backlight_dev->props.brightness = get_lcd(dev->backlight_dev);

	/* Register rfkill switch for Bluetooth */
	if (hci_get_bt_present(dev, &bt_present) == HCI_SUCCESS && bt_present) {