Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 243090
b: refs/heads/master
c: bf15571
h: refs/heads/master
v: v3
  • Loading branch information
Mattia Dongili authored and Matthew Garrett committed Mar 28, 2011
1 parent 3158eef commit d350cf9
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2a4f0c81adcd1f812a63bc9106be2fd26f437730
refs/heads/master: bf155714013e59c299e378055d60a4adf92e79db
176 changes: 175 additions & 1 deletion trunk/drivers/platform/x86/sony-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif

static int kbd_backlight; /* = 1 */
module_param(kbd_backlight, int, 0444);
MODULE_PARM_DESC(kbd_backlight,
"set this to 0 to disable keyboard backlight, "
"1 to enable it (default: 0)");

static int kbd_backlight_timeout; /* = 0 */
module_param(kbd_backlight_timeout, int, 0444);
MODULE_PARM_DESC(kbd_backlight_timeout,
"set this to 0 to set the default 10 seconds timeout, "
"1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
"(default: 0)");

enum sony_nc_rfkill {
SONY_WIFI,
SONY_BLUETOOTH,
Expand Down Expand Up @@ -1309,6 +1322,161 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
return;
}

/* Keyboard backlight feature */
#define KBDBL_HANDLER 0x137
#define KBDBL_PRESENT 0xB00
#define SET_MODE 0xC00
#define SET_TIMEOUT 0xE00

struct kbd_backlight {
int mode;
int timeout;
struct device_attribute mode_attr;
struct device_attribute timeout_attr;
};

struct kbd_backlight *kbdbl_handle;

static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
{
int result;

if (value > 1)
return -EINVAL;

if (sony_call_snc_handle(KBDBL_HANDLER,
(value << 0x10) | SET_MODE, &result))
return -EIO;

kbdbl_handle->mode = value;

return 0;
}

static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
int ret = 0;
unsigned long value;

if (count > 31)
return -EINVAL;

if (strict_strtoul(buffer, 10, &value))
return -EINVAL;

ret = __sony_nc_kbd_backlight_mode_set(value);
if (ret < 0)
return ret;

return count;
}

static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
ssize_t count = 0;
count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode);
return count;
}

static int __sony_nc_kbd_backlight_timeout_set(u8 value)
{
int result;

if (value > 3)
return -EINVAL;

if (sony_call_snc_handle(KBDBL_HANDLER,
(value << 0x10) | SET_TIMEOUT, &result))
return -EIO;

kbdbl_handle->timeout = value;

return 0;
}

static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev,
struct device_attribute *attr,
const char *buffer, size_t count)
{
int ret = 0;
unsigned long value;

if (count > 31)
return -EINVAL;

if (strict_strtoul(buffer, 10, &value))
return -EINVAL;

ret = __sony_nc_kbd_backlight_timeout_set(value);
if (ret < 0)
return ret;

return count;
}

static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev,
struct device_attribute *attr, char *buffer)
{
ssize_t count = 0;
count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout);
return count;
}

static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
{
int result;

if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result))
return 0;
if (!(result & 0x02))
return 0;

kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL);

sysfs_attr_init(&kbdbl_handle->mode_attr.attr);
kbdbl_handle->mode_attr.attr.name = "kbd_backlight";
kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR;
kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show;
kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store;

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

if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr))
goto outkzalloc;

if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr))
goto outmode;

__sony_nc_kbd_backlight_mode_set(kbd_backlight);
__sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout);

return 0;

outmode:
device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
outkzalloc:
kfree(kbdbl_handle);
kbdbl_handle = NULL;
return -1;
}

static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
{
if (kbdbl_handle) {
device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
kfree(kbdbl_handle);
}
return 0;
}

static int sony_nc_add(struct acpi_device *device)
{
acpi_status status;
Expand Down Expand Up @@ -1359,6 +1527,8 @@ static int sony_nc_add(struct acpi_device *device)
dprintk("Doing SNC setup\n");
if (sony_nc_handles_setup(sony_pf_device))
goto outpresent;
if (sony_nc_kbd_backlight_setup(sony_pf_device))
goto outsnc;
sony_nc_function_setup(device);
sony_nc_rfkill_setup(device);
}
Expand All @@ -1367,7 +1537,7 @@ static int sony_nc_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
pr_err(DRV_PFX "Unable to create input devices.\n");
goto outsnc;
goto outkbdbacklight;
}

if (acpi_video_backlight_support()) {
Expand Down Expand Up @@ -1445,6 +1615,9 @@ static int sony_nc_add(struct acpi_device *device)

sony_laptop_remove_input();

outkbdbacklight:
sony_nc_kbd_backlight_cleanup(sony_pf_device);

outsnc:
sony_nc_handles_cleanup(sony_pf_device);

Expand All @@ -1469,6 +1642,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
device_remove_file(&sony_pf_device->dev, &item->devattr);
}

sony_nc_kbd_backlight_cleanup(sony_pf_device);
sony_nc_handles_cleanup(sony_pf_device);
sony_pf_remove();
sony_laptop_remove_input();
Expand Down

0 comments on commit d350cf9

Please sign in to comment.