Commit 800f2017 authored by Mattia Dongili's avatar Mattia Dongili Committed by Darren Hart
Browse files

Keyboard backlight control for some Vaio Fit models



SVF1521P6EW, SVF1521DCXW, SVF13N1L2ES and likely most SVF*.
do not expose separate timeout controls in auto mode.

Signed-off-by: default avatarDominik Matta <dominik@matta.sk>
Signed-off-by: default avatarMattia Dongili <malattia@linux.it>
Signed-off-by: default avatarDarren Hart <dvhart@linux.intel.com>
parent dc4522be
Loading
Loading
Loading
Loading
+45 −20
Original line number Diff line number Diff line
@@ -1393,6 +1393,7 @@ static void sony_nc_function_setup(struct acpi_device *device,
		case 0x0143:
		case 0x014b:
		case 0x014c:
		case 0x0153:
		case 0x0163:
			result = sony_nc_kbd_backlight_setup(pf_device, handle);
			if (result)
@@ -1490,6 +1491,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
		case 0x0143:
		case 0x014b:
		case 0x014c:
		case 0x0153:
		case 0x0163:
			sony_nc_kbd_backlight_cleanup(pd, handle);
			break;
@@ -1773,6 +1775,7 @@ struct kbd_backlight {
	unsigned int base;
	unsigned int mode;
	unsigned int timeout;
	unsigned int has_timeout;
	struct device_attribute mode_attr;
	struct device_attribute timeout_attr;
};
@@ -1877,6 +1880,8 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
		unsigned int handle)
{
	int result;
	int probe_base = 0;
	int ctl_base = 0;
	int ret = 0;

	if (kbdbl_ctl) {
@@ -1885,11 +1890,25 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
		return -EBUSY;
	}

	/* verify the kbd backlight presence, these handles are not used for
	 * keyboard backlight only
	/* verify the kbd backlight presence, some of these handles are not used
	 * for keyboard backlight only
	 */
	ret = sony_call_snc_handle(handle, handle == 0x0137 ? 0x0B00 : 0x0100,
			&result);
	switch (handle) {
	case 0x0153:
		probe_base = 0x0;
		ctl_base = 0x0;
		break;
	case 0x0137:
		probe_base = 0x0B00;
		ctl_base = 0x0C00;
		break;
	default:
		probe_base = 0x0100;
		ctl_base = 0x4000;
		break;
	}

	ret = sony_call_snc_handle(handle, probe_base, &result);
	if (ret)
		return ret;

@@ -1906,10 +1925,9 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
	kbdbl_ctl->mode = kbd_backlight;
	kbdbl_ctl->timeout = kbd_backlight_timeout;
	kbdbl_ctl->handle = handle;
	if (handle == 0x0137)
		kbdbl_ctl->base = 0x0C00;
	else
		kbdbl_ctl->base = 0x4000;
	kbdbl_ctl->base = ctl_base;
	/* Some models do not allow timeout control */
	kbdbl_ctl->has_timeout = handle != 0x0153;

	sysfs_attr_init(&kbdbl_ctl->mode_attr.attr);
	kbdbl_ctl->mode_attr.attr.name = "kbd_backlight";
@@ -1917,22 +1935,28 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
	kbdbl_ctl->mode_attr.show = sony_nc_kbd_backlight_mode_show;
	kbdbl_ctl->mode_attr.store = sony_nc_kbd_backlight_mode_store;

	sysfs_attr_init(&kbdbl_ctl->timeout_attr.attr);
	kbdbl_ctl->timeout_attr.attr.name = "kbd_backlight_timeout";
	kbdbl_ctl->timeout_attr.attr.mode = S_IRUGO | S_IWUSR;
	kbdbl_ctl->timeout_attr.show = sony_nc_kbd_backlight_timeout_show;
	kbdbl_ctl->timeout_attr.store = sony_nc_kbd_backlight_timeout_store;

	ret = device_create_file(&pd->dev, &kbdbl_ctl->mode_attr);
	if (ret)
		goto outkzalloc;

	__sony_nc_kbd_backlight_mode_set(kbdbl_ctl->mode);

	if (kbdbl_ctl->has_timeout) {
		sysfs_attr_init(&kbdbl_ctl->timeout_attr.attr);
		kbdbl_ctl->timeout_attr.attr.name = "kbd_backlight_timeout";
		kbdbl_ctl->timeout_attr.attr.mode = S_IRUGO | S_IWUSR;
		kbdbl_ctl->timeout_attr.show =
			sony_nc_kbd_backlight_timeout_show;
		kbdbl_ctl->timeout_attr.store =
			sony_nc_kbd_backlight_timeout_store;

		ret = device_create_file(&pd->dev, &kbdbl_ctl->timeout_attr);
		if (ret)
			goto outmode;

	__sony_nc_kbd_backlight_mode_set(kbdbl_ctl->mode);
		__sony_nc_kbd_backlight_timeout_set(kbdbl_ctl->timeout);
	}


	return 0;

@@ -1949,6 +1973,7 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
{
	if (kbdbl_ctl && handle == kbdbl_ctl->handle) {
		device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr);
		if (kbdbl_ctl->has_timeout)
			device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr);
		kfree(kbdbl_ctl);
		kbdbl_ctl = NULL;