mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-26 23:46:57 +00:00
Pull thinkpad-2.6.24 into release branch
This commit is contained in:
commit
d12dbbfe94
@ -1,7 +1,7 @@
|
|||||||
ThinkPad ACPI Extras Driver
|
ThinkPad ACPI Extras Driver
|
||||||
|
|
||||||
Version 0.16
|
Version 0.17
|
||||||
August 2nd, 2007
|
October 04th, 2007
|
||||||
|
|
||||||
Borislav Deianov <borislav@users.sf.net>
|
Borislav Deianov <borislav@users.sf.net>
|
||||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||||
@ -923,19 +923,34 @@ sysfs backlight device "thinkpad_screen"
|
|||||||
This feature allows software control of the LCD brightness on ThinkPad
|
This feature allows software control of the LCD brightness on ThinkPad
|
||||||
models which don't have a hardware brightness slider.
|
models which don't have a hardware brightness slider.
|
||||||
|
|
||||||
It has some limitations: the LCD backlight cannot be actually turned on or off
|
It has some limitations: the LCD backlight cannot be actually turned on or
|
||||||
by this interface, and in many ThinkPad models, the "dim while on battery"
|
off by this interface, and in many ThinkPad models, the "dim while on
|
||||||
functionality will be enabled by the BIOS when this interface is used, and
|
battery" functionality will be enabled by the BIOS when this interface is
|
||||||
cannot be controlled.
|
used, and cannot be controlled.
|
||||||
|
|
||||||
The backlight control has eight levels, ranging from 0 to 7. Some of the
|
On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
|
||||||
levels may not be distinct.
|
has eight brightness levels, ranging from 0 to 7. Some of the levels
|
||||||
|
may not be distinct. Later Lenovo models that implement the ACPI
|
||||||
|
display backlight brightness control methods have 16 levels, ranging
|
||||||
|
from 0 to 15.
|
||||||
|
|
||||||
There are two interfaces to the firmware for brightness control, EC and CMOS.
|
There are two interfaces to the firmware for direct brightness control,
|
||||||
To select which one should be used, use the brightness_mode module parameter:
|
EC and CMOS. To select which one should be used, use the
|
||||||
brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode,
|
brightness_mode module parameter: brightness_mode=1 selects EC mode,
|
||||||
brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect
|
brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
|
||||||
which interface to use.
|
and CMOS. The driver tries to autodetect which interface to use.
|
||||||
|
|
||||||
|
When display backlight brightness controls are available through the
|
||||||
|
standard ACPI interface, it is best to use it instead of this direct
|
||||||
|
ThinkPad-specific interface. The driver will disable its native
|
||||||
|
backlight brightness control interface if it detects that the standard
|
||||||
|
ACPI interface is available in the ThinkPad.
|
||||||
|
|
||||||
|
The brightness_enable module parameter can be used to control whether
|
||||||
|
the LCD brightness control feature will be enabled when available.
|
||||||
|
brightness_enable=0 forces it to be disabled. brightness_enable=1
|
||||||
|
forces it to be enabled when available, even if the standard ACPI
|
||||||
|
interface is also available.
|
||||||
|
|
||||||
Procfs notes:
|
Procfs notes:
|
||||||
|
|
||||||
@ -947,11 +962,11 @@ Procfs notes:
|
|||||||
|
|
||||||
Sysfs notes:
|
Sysfs notes:
|
||||||
|
|
||||||
The interface is implemented through the backlight sysfs class, which is poorly
|
The interface is implemented through the backlight sysfs class, which is
|
||||||
documented at this time.
|
poorly documented at this time.
|
||||||
|
|
||||||
Locate the thinkpad_screen device under /sys/class/backlight, and inside it
|
Locate the thinkpad_screen device under /sys/class/backlight, and inside
|
||||||
there will be the following attributes:
|
it there will be the following attributes:
|
||||||
|
|
||||||
max_brightness:
|
max_brightness:
|
||||||
Reads the maximum brightness the hardware can be set to.
|
Reads the maximum brightness the hardware can be set to.
|
||||||
@ -961,17 +976,19 @@ there will be the following attributes:
|
|||||||
Reads what brightness the screen is set to at this instant.
|
Reads what brightness the screen is set to at this instant.
|
||||||
|
|
||||||
brightness:
|
brightness:
|
||||||
Writes request the driver to change brightness to the given
|
Writes request the driver to change brightness to the
|
||||||
value. Reads will tell you what brightness the driver is trying
|
given value. Reads will tell you what brightness the
|
||||||
to set the display to when "power" is set to zero and the display
|
driver is trying to set the display to when "power" is set
|
||||||
has not been dimmed by a kernel power management event.
|
to zero and the display has not been dimmed by a kernel
|
||||||
|
power management event.
|
||||||
|
|
||||||
power:
|
power:
|
||||||
power management mode, where 0 is "display on", and 1 to 3 will
|
power management mode, where 0 is "display on", and 1 to 3
|
||||||
dim the display backlight to brightness level 0 because
|
will dim the display backlight to brightness level 0
|
||||||
thinkpad-acpi cannot really turn the backlight off. Kernel
|
because thinkpad-acpi cannot really turn the backlight
|
||||||
power management events can temporarily increase the current
|
off. Kernel power management events can temporarily
|
||||||
power management level, i.e. they can dim the display.
|
increase the current power management level, i.e. they can
|
||||||
|
dim the display.
|
||||||
|
|
||||||
|
|
||||||
Volume control -- /proc/acpi/ibm/volume
|
Volume control -- /proc/acpi/ibm/volume
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IBM_VERSION "0.16"
|
#define IBM_VERSION "0.17"
|
||||||
#define TPACPI_SYSFS_VERSION 0x020000
|
#define TPACPI_SYSFS_VERSION 0x020000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -964,15 +964,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||||||
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
|
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
|
||||||
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
|
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
|
||||||
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
|
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
|
||||||
KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
|
KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
|
||||||
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
|
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
|
||||||
KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
|
KEY_RESERVED, /* 0x10: FN+END (brightness down) */
|
||||||
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
|
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
|
||||||
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
|
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
|
||||||
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
|
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
|
||||||
KEY_VOLUMEUP, /* 0x14: VOLUME UP */
|
KEY_RESERVED, /* 0x14: VOLUME UP */
|
||||||
KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
|
KEY_RESERVED, /* 0x15: VOLUME DOWN */
|
||||||
KEY_MUTE, /* 0x16: MUTE */
|
KEY_RESERVED, /* 0x16: MUTE */
|
||||||
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
|
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
|
||||||
/* (assignments unknown, please report if found) */
|
/* (assignments unknown, please report if found) */
|
||||||
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||||
@ -993,9 +993,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||||||
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
|
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
|
||||||
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
|
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
|
||||||
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
|
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
|
||||||
KEY_VOLUMEUP, /* 0x14: VOLUME UP */
|
KEY_RESERVED, /* 0x14: VOLUME UP */
|
||||||
KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
|
KEY_RESERVED, /* 0x15: VOLUME DOWN */
|
||||||
KEY_MUTE, /* 0x16: MUTE */
|
KEY_RESERVED, /* 0x16: MUTE */
|
||||||
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
|
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
|
||||||
/* (assignments unknown, please report if found) */
|
/* (assignments unknown, please report if found) */
|
||||||
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||||
@ -1342,9 +1342,8 @@ static int hotkey_read(char *p)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = mutex_lock_interruptible(&hotkey_mutex);
|
if (mutex_lock_interruptible(&hotkey_mutex))
|
||||||
if (res < 0)
|
return -ERESTARTSYS;
|
||||||
return res;
|
|
||||||
res = hotkey_get(&status, &mask);
|
res = hotkey_get(&status, &mask);
|
||||||
mutex_unlock(&hotkey_mutex);
|
mutex_unlock(&hotkey_mutex);
|
||||||
if (res)
|
if (res)
|
||||||
@ -1373,9 +1372,8 @@ static int hotkey_write(char *buf)
|
|||||||
if (!tp_features.hotkey)
|
if (!tp_features.hotkey)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
res = mutex_lock_interruptible(&hotkey_mutex);
|
if (mutex_lock_interruptible(&hotkey_mutex))
|
||||||
if (res < 0)
|
return -ERESTARTSYS;
|
||||||
return res;
|
|
||||||
|
|
||||||
res = hotkey_get(&status, &mask);
|
res = hotkey_get(&status, &mask);
|
||||||
if (res)
|
if (res)
|
||||||
@ -3114,6 +3112,99 @@ static struct backlight_ops ibm_backlight_data = {
|
|||||||
|
|
||||||
static struct mutex brightness_mutex;
|
static struct mutex brightness_mutex;
|
||||||
|
|
||||||
|
static int __init tpacpi_query_bcll_levels(acpi_handle handle)
|
||||||
|
{
|
||||||
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
|
union acpi_object *obj;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
|
||||||
|
obj = (union acpi_object *)buffer.pointer;
|
||||||
|
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
|
||||||
|
printk(IBM_ERR "Unknown BCLL data, "
|
||||||
|
"please report this to %s\n", IBM_MAIL);
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = obj->package.count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(buffer.pointer);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
|
||||||
|
void *context, void **rv)
|
||||||
|
{
|
||||||
|
char name[ACPI_PATH_SEGMENT_LENGTH];
|
||||||
|
struct acpi_buffer buffer = { sizeof(name), &name };
|
||||||
|
|
||||||
|
if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
|
||||||
|
!strncmp("BCLL", name, sizeof(name) - 1)) {
|
||||||
|
if (tpacpi_query_bcll_levels(handle) == 16) {
|
||||||
|
*rv = handle;
|
||||||
|
return AE_CTRL_TERMINATE;
|
||||||
|
} else {
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init brightness_check_levels(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
void *found_node = NULL;
|
||||||
|
|
||||||
|
if (!vid_handle) {
|
||||||
|
IBM_ACPIHANDLE_INIT(vid);
|
||||||
|
}
|
||||||
|
if (!vid_handle)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Search for a BCLL package with 16 levels */
|
||||||
|
status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
|
||||||
|
brightness_find_bcll, NULL, &found_node);
|
||||||
|
|
||||||
|
return (ACPI_SUCCESS(status) && found_node != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
|
||||||
|
void *context, void **rv)
|
||||||
|
{
|
||||||
|
char name[ACPI_PATH_SEGMENT_LENGTH];
|
||||||
|
struct acpi_buffer buffer = { sizeof(name), &name };
|
||||||
|
|
||||||
|
if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
|
||||||
|
!strncmp("_BCL", name, sizeof(name) - 1)) {
|
||||||
|
*rv = handle;
|
||||||
|
return AE_CTRL_TERMINATE;
|
||||||
|
} else {
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init brightness_check_std_acpi_support(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
void *found_node = NULL;
|
||||||
|
|
||||||
|
if (!vid_handle) {
|
||||||
|
IBM_ACPIHANDLE_INIT(vid);
|
||||||
|
}
|
||||||
|
if (!vid_handle)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Search for a _BCL method, but don't execute it */
|
||||||
|
status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
|
||||||
|
brightness_find_bcl, NULL, &found_node);
|
||||||
|
|
||||||
|
return (ACPI_SUCCESS(status) && found_node != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int __init brightness_init(struct ibm_init_struct *iibm)
|
static int __init brightness_init(struct ibm_init_struct *iibm)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
@ -3122,6 +3213,18 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
|
|||||||
|
|
||||||
mutex_init(&brightness_mutex);
|
mutex_init(&brightness_mutex);
|
||||||
|
|
||||||
|
if (!brightness_enable) {
|
||||||
|
dbg_printk(TPACPI_DBG_INIT,
|
||||||
|
"brightness support disabled by module parameter\n");
|
||||||
|
return 1;
|
||||||
|
} else if (brightness_enable > 1) {
|
||||||
|
if (brightness_check_std_acpi_support()) {
|
||||||
|
printk(IBM_NOTICE
|
||||||
|
"standard ACPI backlight interface available, not loading native one...\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!brightness_mode) {
|
if (!brightness_mode) {
|
||||||
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
|
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
|
||||||
brightness_mode = 2;
|
brightness_mode = 2;
|
||||||
@ -3135,10 +3238,17 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
|
|||||||
if (brightness_mode > 3)
|
if (brightness_mode > 3)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
tp_features.bright_16levels =
|
||||||
|
thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
|
||||||
|
brightness_check_levels();
|
||||||
|
|
||||||
b = brightness_get(NULL);
|
b = brightness_get(NULL);
|
||||||
if (b < 0)
|
if (b < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (tp_features.bright_16levels)
|
||||||
|
printk(IBM_INFO "detected a 16-level brightness capable ThinkPad\n");
|
||||||
|
|
||||||
ibm_backlight_device = backlight_device_register(
|
ibm_backlight_device = backlight_device_register(
|
||||||
TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
|
TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
|
||||||
&ibm_backlight_data);
|
&ibm_backlight_data);
|
||||||
@ -3148,7 +3258,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
|
|||||||
}
|
}
|
||||||
vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
|
vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
|
||||||
|
|
||||||
ibm_backlight_device->props.max_brightness = 7;
|
ibm_backlight_device->props.max_brightness =
|
||||||
|
(tp_features.bright_16levels)? 15 : 7;
|
||||||
ibm_backlight_device->props.brightness = b;
|
ibm_backlight_device->props.brightness = b;
|
||||||
backlight_update_status(ibm_backlight_device);
|
backlight_update_status(ibm_backlight_device);
|
||||||
|
|
||||||
@ -3167,6 +3278,8 @@ static void brightness_exit(void)
|
|||||||
|
|
||||||
static int brightness_update_status(struct backlight_device *bd)
|
static int brightness_update_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
|
/* it is the backlight class's job (caller) to handle
|
||||||
|
* EINTR and other errors properly */
|
||||||
return brightness_set(
|
return brightness_set(
|
||||||
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
|
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
|
||||||
bd->props.power == FB_BLANK_UNBLANK) ?
|
bd->props.power == FB_BLANK_UNBLANK) ?
|
||||||
@ -3184,13 +3297,14 @@ static int brightness_get(struct backlight_device *bd)
|
|||||||
if (brightness_mode & 1) {
|
if (brightness_mode & 1) {
|
||||||
if (!acpi_ec_read(brightness_offset, &lec))
|
if (!acpi_ec_read(brightness_offset, &lec))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
lec &= 7;
|
lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
|
||||||
level = lec;
|
level = lec;
|
||||||
};
|
};
|
||||||
if (brightness_mode & 2) {
|
if (brightness_mode & 2) {
|
||||||
lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
|
lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
|
||||||
& TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
|
& TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
|
||||||
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
|
>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
|
||||||
|
lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
|
||||||
level = lcmos;
|
level = lcmos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3206,12 +3320,13 @@ static int brightness_get(struct backlight_device *bd)
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* May return EINTR which can always be mapped to ERESTARTSYS */
|
||||||
static int brightness_set(int value)
|
static int brightness_set(int value)
|
||||||
{
|
{
|
||||||
int cmos_cmd, inc, i, res;
|
int cmos_cmd, inc, i, res;
|
||||||
int current_value;
|
int current_value;
|
||||||
|
|
||||||
if (value > 7)
|
if (value > ((tp_features.bright_16levels)? 15 : 7))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
res = mutex_lock_interruptible(&brightness_mutex);
|
res = mutex_lock_interruptible(&brightness_mutex);
|
||||||
@ -3227,7 +3342,7 @@ static int brightness_set(int value)
|
|||||||
cmos_cmd = value > current_value ?
|
cmos_cmd = value > current_value ?
|
||||||
TP_CMOS_BRIGHTNESS_UP :
|
TP_CMOS_BRIGHTNESS_UP :
|
||||||
TP_CMOS_BRIGHTNESS_DOWN;
|
TP_CMOS_BRIGHTNESS_DOWN;
|
||||||
inc = value > current_value ? 1 : -1;
|
inc = (value > current_value)? 1 : -1;
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
for (i = current_value; i != value; i += inc) {
|
for (i = current_value; i != value; i += inc) {
|
||||||
@ -3256,10 +3371,11 @@ static int brightness_read(char *p)
|
|||||||
if ((level = brightness_get(NULL)) < 0) {
|
if ((level = brightness_get(NULL)) < 0) {
|
||||||
len += sprintf(p + len, "level:\t\tunreadable\n");
|
len += sprintf(p + len, "level:\t\tunreadable\n");
|
||||||
} else {
|
} else {
|
||||||
len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
|
len += sprintf(p + len, "level:\t\t%d\n", level);
|
||||||
len += sprintf(p + len, "commands:\tup, down\n");
|
len += sprintf(p + len, "commands:\tup, down\n");
|
||||||
len += sprintf(p + len, "commands:\tlevel <level>"
|
len += sprintf(p + len, "commands:\tlevel <level>"
|
||||||
" (<level> is 0-7)\n");
|
" (<level> is 0-%d)\n",
|
||||||
|
(tp_features.bright_16levels) ? 15 : 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@ -3268,28 +3384,34 @@ static int brightness_read(char *p)
|
|||||||
static int brightness_write(char *buf)
|
static int brightness_write(char *buf)
|
||||||
{
|
{
|
||||||
int level;
|
int level;
|
||||||
int new_level;
|
int rc;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
int max_level = (tp_features.bright_16levels) ? 15 : 7;
|
||||||
|
|
||||||
|
level = brightness_get(NULL);
|
||||||
|
if (level < 0)
|
||||||
|
return level;
|
||||||
|
|
||||||
while ((cmd = next_cmd(&buf))) {
|
while ((cmd = next_cmd(&buf))) {
|
||||||
if ((level = brightness_get(NULL)) < 0)
|
|
||||||
return level;
|
|
||||||
level &= 7;
|
|
||||||
|
|
||||||
if (strlencmp(cmd, "up") == 0) {
|
if (strlencmp(cmd, "up") == 0) {
|
||||||
new_level = level == 7 ? 7 : level + 1;
|
if (level < max_level)
|
||||||
|
level++;
|
||||||
} else if (strlencmp(cmd, "down") == 0) {
|
} else if (strlencmp(cmd, "down") == 0) {
|
||||||
new_level = level == 0 ? 0 : level - 1;
|
if (level > 0)
|
||||||
} else if (sscanf(cmd, "level %d", &new_level) == 1 &&
|
level--;
|
||||||
new_level >= 0 && new_level <= 7) {
|
} else if (sscanf(cmd, "level %d", &level) == 1 &&
|
||||||
/* new_level set */
|
level >= 0 && level <= max_level) {
|
||||||
|
/* new level set */
|
||||||
} else
|
} else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
brightness_set(new_level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/*
|
||||||
|
* Now we know what the final level should be, so we try to set it.
|
||||||
|
* Doing it this way makes the syscall restartable in case of EINTR
|
||||||
|
*/
|
||||||
|
rc = brightness_set(level);
|
||||||
|
return (rc == -EINTR)? ERESTARTSYS : rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ibm_struct brightness_driver_data = {
|
static struct ibm_struct brightness_driver_data = {
|
||||||
@ -3652,9 +3774,8 @@ static ssize_t fan_pwm1_store(struct device *dev,
|
|||||||
/* scale down from 0-255 to 0-7 */
|
/* scale down from 0-255 to 0-7 */
|
||||||
newlevel = (s >> 5) & 0x07;
|
newlevel = (s >> 5) & 0x07;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = fan_get_status(&status);
|
rc = fan_get_status(&status);
|
||||||
if (!rc && (status &
|
if (!rc && (status &
|
||||||
@ -3904,9 +4025,8 @@ static int fan_get_status_safe(u8 *status)
|
|||||||
int rc;
|
int rc;
|
||||||
u8 s;
|
u8 s;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
rc = fan_get_status(&s);
|
rc = fan_get_status(&s);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
fan_update_desired_level(s);
|
fan_update_desired_level(s);
|
||||||
@ -4040,9 +4160,8 @@ static int fan_set_level_safe(int level)
|
|||||||
if (!fan_control_allowed)
|
if (!fan_control_allowed)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (level == TPACPI_FAN_LAST_LEVEL)
|
if (level == TPACPI_FAN_LAST_LEVEL)
|
||||||
level = fan_control_desired_level;
|
level = fan_control_desired_level;
|
||||||
@ -4063,9 +4182,8 @@ static int fan_set_enable(void)
|
|||||||
if (!fan_control_allowed)
|
if (!fan_control_allowed)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
|
|
||||||
switch (fan_control_access_mode) {
|
switch (fan_control_access_mode) {
|
||||||
case TPACPI_FAN_WR_ACPI_FANS:
|
case TPACPI_FAN_WR_ACPI_FANS:
|
||||||
@ -4119,9 +4237,8 @@ static int fan_set_disable(void)
|
|||||||
if (!fan_control_allowed)
|
if (!fan_control_allowed)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
switch (fan_control_access_mode) {
|
switch (fan_control_access_mode) {
|
||||||
@ -4158,9 +4275,8 @@ static int fan_set_speed(int speed)
|
|||||||
if (!fan_control_allowed)
|
if (!fan_control_allowed)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
rc = mutex_lock_interruptible(&fan_mutex);
|
if (mutex_lock_interruptible(&fan_mutex))
|
||||||
if (rc < 0)
|
return -ERESTARTSYS;
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
switch (fan_control_access_mode) {
|
switch (fan_control_access_mode) {
|
||||||
@ -4701,9 +4817,15 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct ibm_struct *ibm;
|
struct ibm_struct *ibm;
|
||||||
|
|
||||||
|
if (!kp || !kp->name || !val)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
|
for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
|
||||||
ibm = ibms_init[i].data;
|
ibm = ibms_init[i].data;
|
||||||
BUG_ON(ibm == NULL);
|
WARN_ON(ibm == NULL);
|
||||||
|
|
||||||
|
if (!ibm || !ibm->name)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
|
if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
|
||||||
if (strlen(val) > sizeof(ibms_init[i].param) - 2)
|
if (strlen(val) > sizeof(ibms_init[i].param) - 2)
|
||||||
@ -4732,6 +4854,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
|
|||||||
static int brightness_mode;
|
static int brightness_mode;
|
||||||
module_param_named(brightness_mode, brightness_mode, int, 0);
|
module_param_named(brightness_mode, brightness_mode, int, 0);
|
||||||
|
|
||||||
|
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
|
||||||
|
module_param(brightness_enable, uint, 0);
|
||||||
|
|
||||||
static unsigned int hotkey_report_mode;
|
static unsigned int hotkey_report_mode;
|
||||||
module_param(hotkey_report_mode, uint, 0);
|
module_param(hotkey_report_mode, uint, 0);
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
/* ThinkPad CMOS NVRAM constants */
|
/* ThinkPad CMOS NVRAM constants */
|
||||||
#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e
|
#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e
|
||||||
#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07
|
#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x0f
|
||||||
#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
|
#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
|
||||||
|
|
||||||
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
|
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
|
||||||
@ -246,6 +246,7 @@ static struct {
|
|||||||
u32 hotkey_wlsw:1;
|
u32 hotkey_wlsw:1;
|
||||||
u32 light:1;
|
u32 light:1;
|
||||||
u32 light_status:1;
|
u32 light_status:1;
|
||||||
|
u32 bright_16levels:1;
|
||||||
u32 wan:1;
|
u32 wan:1;
|
||||||
u32 fan_ctrl_status_undef:1;
|
u32 fan_ctrl_status_undef:1;
|
||||||
u32 input_device_registered:1;
|
u32 input_device_registered:1;
|
||||||
@ -338,6 +339,7 @@ static int bluetooth_write(char *buf);
|
|||||||
static struct backlight_device *ibm_backlight_device;
|
static struct backlight_device *ibm_backlight_device;
|
||||||
static int brightness_offset = 0x31;
|
static int brightness_offset = 0x31;
|
||||||
static int brightness_mode;
|
static int brightness_mode;
|
||||||
|
static unsigned int brightness_enable; /* 0 = no, 1 = yes, 2 = auto */
|
||||||
|
|
||||||
static int brightness_init(struct ibm_init_struct *iibm);
|
static int brightness_init(struct ibm_init_struct *iibm);
|
||||||
static void brightness_exit(void);
|
static void brightness_exit(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user