Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
This commit is contained in:
commit
dd07a8db72
@ -1,7 +1,7 @@
|
||||
ThinkPad ACPI Extras Driver
|
||||
|
||||
Version 0.17
|
||||
October 04th, 2007
|
||||
Version 0.19
|
||||
January 06th, 2008
|
||||
|
||||
Borislav Deianov <borislav@users.sf.net>
|
||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
@ -215,6 +215,11 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file:
|
||||
... any other 8-hex-digit mask ...
|
||||
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
|
||||
|
||||
The procfs interface does not support NVRAM polling control. So as to
|
||||
maintain maximum bug-to-bug compatibility, it does not report any masks,
|
||||
nor does it allow one to manipulate the hot key mask when the firmware
|
||||
does not support masks at all, even if NVRAM polling is in use.
|
||||
|
||||
sysfs notes:
|
||||
|
||||
hotkey_bios_enabled:
|
||||
@ -231,17 +236,26 @@ sysfs notes:
|
||||
to this value.
|
||||
|
||||
hotkey_enable:
|
||||
Enables/disables the hot keys feature, and reports
|
||||
current status of the hot keys feature.
|
||||
Enables/disables the hot keys feature in the ACPI
|
||||
firmware, and reports current status of the hot keys
|
||||
feature. Has no effect on the NVRAM hot key polling
|
||||
functionality.
|
||||
|
||||
0: disables the hot keys feature / feature disabled
|
||||
1: enables the hot keys feature / feature enabled
|
||||
|
||||
hotkey_mask:
|
||||
bit mask to enable driver-handling and ACPI event
|
||||
generation for each hot key (see above). Returns the
|
||||
current status of the hot keys mask, and allows one to
|
||||
modify it.
|
||||
bit mask to enable driver-handling (and depending on
|
||||
the firmware, ACPI event generation) for each hot key
|
||||
(see above). Returns the current status of the hot keys
|
||||
mask, and allows one to modify it.
|
||||
|
||||
Note: when NVRAM polling is active, the firmware mask
|
||||
will be different from the value returned by
|
||||
hotkey_mask. The driver will retain enabled bits for
|
||||
hotkeys that are under NVRAM polling even if the
|
||||
firmware refuses them, and will not set these bits on
|
||||
the firmware hot key mask.
|
||||
|
||||
hotkey_all_mask:
|
||||
bit mask that should enable event reporting for all
|
||||
@ -257,12 +271,48 @@ sysfs notes:
|
||||
handled by the firmware anyway. Echo it to
|
||||
hotkey_mask above, to use.
|
||||
|
||||
hotkey_source_mask:
|
||||
bit mask that selects which hot keys will the driver
|
||||
poll the NVRAM for. This is auto-detected by the driver
|
||||
based on the capabilities reported by the ACPI firmware,
|
||||
but it can be overridden at runtime.
|
||||
|
||||
Hot keys whose bits are set in both hotkey_source_mask
|
||||
and also on hotkey_mask are polled for in NVRAM. Only a
|
||||
few hot keys are available through CMOS NVRAM polling.
|
||||
|
||||
Warning: when in NVRAM mode, the volume up/down/mute
|
||||
keys are synthesized according to changes in the mixer,
|
||||
so you have to use volume up or volume down to unmute,
|
||||
as per the ThinkPad volume mixer user interface. When
|
||||
in ACPI event mode, volume up/down/mute are reported as
|
||||
separate events, but this behaviour may be corrected in
|
||||
future releases of this driver, in which case the
|
||||
ThinkPad volume mixer user interface semanthics will be
|
||||
enforced.
|
||||
|
||||
hotkey_poll_freq:
|
||||
frequency in Hz for hot key polling. It must be between
|
||||
0 and 25 Hz. Polling is only carried out when strictly
|
||||
needed.
|
||||
|
||||
Setting hotkey_poll_freq to zero disables polling, and
|
||||
will cause hot key presses that require NVRAM polling
|
||||
to never be reported.
|
||||
|
||||
Setting hotkey_poll_freq too low will cause repeated
|
||||
pressings of the same hot key to be misreported as a
|
||||
single key press, or to not even be detected at all.
|
||||
The recommended polling frequency is 10Hz.
|
||||
|
||||
hotkey_radio_sw:
|
||||
if the ThinkPad has a hardware radio switch, this
|
||||
attribute will read 0 if the switch is in the "radios
|
||||
disabled" postition, and 1 if the switch is in the
|
||||
"radios enabled" position.
|
||||
|
||||
This attribute has poll()/select() support.
|
||||
|
||||
hotkey_report_mode:
|
||||
Returns the state of the procfs ACPI event report mode
|
||||
filter for hot keys. If it is set to 1 (the default),
|
||||
@ -277,6 +327,25 @@ sysfs notes:
|
||||
May return -EPERM (write access locked out by module
|
||||
parameter) or -EACCES (read-only).
|
||||
|
||||
wakeup_reason:
|
||||
Set to 1 if the system is waking up because the user
|
||||
requested a bay ejection. Set to 2 if the system is
|
||||
waking up because the user requested the system to
|
||||
undock. Set to zero for normal wake-ups or wake-ups
|
||||
due to unknown reasons.
|
||||
|
||||
This attribute has poll()/select() support.
|
||||
|
||||
wakeup_hotunplug_complete:
|
||||
Set to 1 if the system was waken up because of an
|
||||
undock or bay ejection request, and that request
|
||||
was sucessfully completed. At this point, it might
|
||||
be useful to send the system back to sleep, at the
|
||||
user's choice. Refer to HKEY events 0x4003 and
|
||||
0x3003, below.
|
||||
|
||||
This attribute has poll()/select() support.
|
||||
|
||||
input layer notes:
|
||||
|
||||
A Hot key is mapped to a single input layer EV_KEY event, possibly
|
||||
@ -427,6 +496,23 @@ Non hot-key ACPI HKEY event map:
|
||||
The above events are not propagated by the driver, except for legacy
|
||||
compatibility purposes when hotkey_report_mode is set to 1.
|
||||
|
||||
0x2304 System is waking up from suspend to undock
|
||||
0x2305 System is waking up from suspend to eject bay
|
||||
0x2404 System is waking up from hibernation to undock
|
||||
0x2405 System is waking up from hibernation to eject bay
|
||||
|
||||
The above events are never propagated by the driver.
|
||||
|
||||
0x3003 Bay ejection (see 0x2x05) complete, can sleep again
|
||||
0x4003 Undocked (see 0x2x04), can sleep again
|
||||
0x5009 Tablet swivel: switched to tablet mode
|
||||
0x500A Tablet swivel: switched to normal mode
|
||||
0x500B Tablet pen insterted into its storage bay
|
||||
0x500C Tablet pen removed from its storage bay
|
||||
0x5010 Brightness level changed (newer Lenovo BIOSes)
|
||||
|
||||
The above events are propagated by the driver.
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never
|
||||
@ -1263,3 +1349,17 @@ Sysfs interface changelog:
|
||||
and the hwmon class for libsensors4 (lm-sensors 3)
|
||||
compatibility. Moved all hwmon attributes to this
|
||||
new platform device.
|
||||
|
||||
0x020100: Marker for thinkpad-acpi with hot key NVRAM polling
|
||||
support. If you must, use it to know you should not
|
||||
start an userspace NVRAM poller (allows to detect when
|
||||
NVRAM is compiled out by the user because it is
|
||||
unneeded/undesired in the first place).
|
||||
0x020101: Marker for thinkpad-acpi with hot key NVRAM polling
|
||||
and proper hotkey_mask semanthics (version 8 of the
|
||||
NVRAM polling patch). Some development snapshots of
|
||||
0.18 had an earlier version that did strange things
|
||||
to hotkey_mask.
|
||||
|
||||
0x020200: Add poll()/select() support to the following attributes:
|
||||
hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
|
||||
|
@ -142,6 +142,7 @@ struct asus_hotk {
|
||||
xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
|
||||
A4S, //Z81sp
|
||||
//(Centrino)
|
||||
F3Sa,
|
||||
END_MODEL
|
||||
} model; //Models currently supported
|
||||
u16 event_count[128]; //count for each event TODO make this better
|
||||
@ -405,7 +406,20 @@ static struct model_data model_conf[END_MODEL] = {
|
||||
.brightness_get = "GPLV",
|
||||
.mt_bt_switch = "BLED",
|
||||
.mt_wled = "WLED"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
.name = "F3Sa",
|
||||
.mt_bt_switch = "BLED",
|
||||
.mt_wled = "WLED",
|
||||
.mt_mled = "MLED",
|
||||
.brightness_get = "GPLV",
|
||||
.brightness_set = "SPLV",
|
||||
.mt_lcd_switch = "\\_SB.PCI0.SBRG.EC0._Q10",
|
||||
.lcd_status = "\\_SB.PCI0.SBRG.EC0.RPIN",
|
||||
.display_get = "\\ADVG",
|
||||
.display_set = "SDSP",
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@ -710,15 +724,8 @@ static int get_lcd_state(void)
|
||||
{
|
||||
int lcd = 0;
|
||||
|
||||
if (hotk->model != L3H) {
|
||||
/* We don't have to check anything if we are here */
|
||||
if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
|
||||
printk(KERN_WARNING
|
||||
"Asus ACPI: Error reading LCD status\n");
|
||||
|
||||
if (hotk->model == L2D)
|
||||
lcd = ~lcd;
|
||||
} else { /* L3H and the like have to be handled differently */
|
||||
if (hotk->model == L3H) {
|
||||
/* L3H and the like have to be handled differently */
|
||||
acpi_status status = 0;
|
||||
struct acpi_object_list input;
|
||||
union acpi_object mt_params[2];
|
||||
@ -745,6 +752,32 @@ static int get_lcd_state(void)
|
||||
if (out_obj.type == ACPI_TYPE_INTEGER)
|
||||
/* That's what the AML code does */
|
||||
lcd = out_obj.integer.value >> 8;
|
||||
} else if (hotk->model == F3Sa) {
|
||||
unsigned long tmp;
|
||||
union acpi_object param;
|
||||
struct acpi_object_list input;
|
||||
acpi_status status;
|
||||
|
||||
/* Read pin 11 */
|
||||
param.type = ACPI_TYPE_INTEGER;
|
||||
param.integer.value = 0x11;
|
||||
input.count = 1;
|
||||
input.pointer = ¶m;
|
||||
|
||||
status = acpi_evaluate_integer(NULL, hotk->methods->lcd_status,
|
||||
&input, &tmp);
|
||||
if (status != AE_OK)
|
||||
return -1;
|
||||
|
||||
lcd = tmp;
|
||||
} else {
|
||||
/* We don't have to check anything if we are here */
|
||||
if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
|
||||
printk(KERN_WARNING
|
||||
"Asus ACPI: Error reading LCD status\n");
|
||||
|
||||
if (hotk->model == L2D)
|
||||
lcd = ~lcd;
|
||||
}
|
||||
|
||||
return (lcd & 1);
|
||||
@ -1134,6 +1167,8 @@ static int asus_model_match(char *model)
|
||||
return W5A;
|
||||
else if (strncmp(model, "A4S", 3) == 0)
|
||||
return A4S;
|
||||
else if (strncmp(model, "F3Sa", 4) == 0)
|
||||
return F3Sa;
|
||||
else
|
||||
return END_MODEL;
|
||||
}
|
||||
|
@ -219,6 +219,25 @@ config THINKPAD_ACPI_BAY
|
||||
|
||||
If you are not sure, say Y here.
|
||||
|
||||
config THINKPAD_ACPI_HOTKEY_POLL
|
||||
bool "Suport NVRAM polling for hot keys"
|
||||
depends on THINKPAD_ACPI
|
||||
default y
|
||||
---help---
|
||||
Some thinkpad models benefit from NVRAM polling to detect a few of
|
||||
the hot key press events. If you know your ThinkPad model does not
|
||||
need to do NVRAM polling to support any of the hot keys you use,
|
||||
unselecting this option will save about 1kB of memory.
|
||||
|
||||
ThinkPads T40 and newer, R52 and newer, and X31 and newer are
|
||||
unlikely to need NVRAM polling in their latest BIOS versions.
|
||||
|
||||
NVRAM polling can detect at most the following keys: ThinkPad/Access
|
||||
IBM, Zoom, Switch Display (fn+F7), ThinkLight, Volume up/down/mute,
|
||||
Brightness up/down, Display Expand (fn+F8), Hibernate (fn+F12).
|
||||
|
||||
If you are not sure, say Y here. The driver enables polling only if
|
||||
it is strictly necessary to do so.
|
||||
|
||||
config ATMEL_SSC
|
||||
tristate "Device driver for Atmel SSC peripheral"
|
||||
|
@ -254,7 +254,7 @@ ASUS_LED(gled, "gaming");
|
||||
* method is searched within the scope of the handle, can be NULL. The output
|
||||
* of the method is written is output, which can also be NULL
|
||||
*
|
||||
* returns 1 if write is successful, 0 else.
|
||||
* returns 0 if write is successful, -1 else.
|
||||
*/
|
||||
static int write_acpi_int(acpi_handle handle, const char *method, int val,
|
||||
struct acpi_buffer *output)
|
||||
@ -263,13 +263,19 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
|
||||
union acpi_object in_obj; //the only param we use
|
||||
acpi_status status;
|
||||
|
||||
if (!handle)
|
||||
return 0;
|
||||
|
||||
params.count = 1;
|
||||
params.pointer = &in_obj;
|
||||
in_obj.type = ACPI_TYPE_INTEGER;
|
||||
in_obj.integer.value = val;
|
||||
|
||||
status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
|
||||
return (status == AE_OK);
|
||||
if (status == AE_OK)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int read_wireless_status(int mask)
|
||||
@ -321,7 +327,7 @@ static void write_status(acpi_handle handle, int out, int mask)
|
||||
|
||||
switch (mask) {
|
||||
case MLED_ON:
|
||||
out = !out & 0x1;
|
||||
out = !(out & 0x1);
|
||||
break;
|
||||
case GLED_ON:
|
||||
out = (out & 0x1) + 1;
|
||||
@ -335,7 +341,7 @@ static void write_status(acpi_handle handle, int out, int mask)
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle && !write_acpi_int(handle, NULL, out, NULL))
|
||||
if (write_acpi_int(handle, NULL, out, NULL))
|
||||
printk(ASUS_WARNING " write failed %x\n", mask);
|
||||
}
|
||||
|
||||
@ -415,7 +421,7 @@ static int set_brightness(struct backlight_device *bd, int value)
|
||||
value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
|
||||
/* 0 <= value <= 15 */
|
||||
|
||||
if (!write_acpi_int(brightness_set_handle, NULL, value, NULL)) {
|
||||
if (write_acpi_int(brightness_set_handle, NULL, value, NULL)) {
|
||||
printk(ASUS_WARNING "Error changing brightness\n");
|
||||
ret = -EIO;
|
||||
}
|
||||
@ -545,7 +551,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
rv = parse_arg(buf, count, &value);
|
||||
if (rv > 0) {
|
||||
if (!write_acpi_int(ledd_set_handle, NULL, value, NULL))
|
||||
if (write_acpi_int(ledd_set_handle, NULL, value, NULL))
|
||||
printk(ASUS_WARNING "LED display write failed\n");
|
||||
else
|
||||
hotk->ledd_status = (u32) value;
|
||||
@ -590,7 +596,7 @@ static ssize_t store_bluetooth(struct device *dev,
|
||||
static void set_display(int value)
|
||||
{
|
||||
/* no sanity check needed for now */
|
||||
if (!write_acpi_int(display_set_handle, NULL, value, NULL))
|
||||
if (write_acpi_int(display_set_handle, NULL, value, NULL))
|
||||
printk(ASUS_WARNING "Error setting display\n");
|
||||
return;
|
||||
}
|
||||
@ -647,7 +653,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
|
||||
*/
|
||||
static void set_light_sens_switch(int value)
|
||||
{
|
||||
if (!write_acpi_int(ls_switch_handle, NULL, value, NULL))
|
||||
if (write_acpi_int(ls_switch_handle, NULL, value, NULL))
|
||||
printk(ASUS_WARNING "Error setting light sensor switch\n");
|
||||
hotk->light_switch = value;
|
||||
}
|
||||
@ -672,7 +678,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
static void set_light_sens_level(int value)
|
||||
{
|
||||
if (!write_acpi_int(ls_level_handle, NULL, value, NULL))
|
||||
if (write_acpi_int(ls_level_handle, NULL, value, NULL))
|
||||
printk(ASUS_WARNING "Error setting light sensor level\n");
|
||||
hotk->light_level = value;
|
||||
}
|
||||
@ -860,7 +866,7 @@ static int asus_hotk_get_info(void)
|
||||
printk(ASUS_WARNING "Couldn't get the DSDT table header\n");
|
||||
|
||||
/* We have to write 0 on init this far for all ASUS models */
|
||||
if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
|
||||
if (write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
|
||||
printk(ASUS_ERR "Hotkey initialization failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@
|
||||
if (debug) printk(KERN_WARNING DRV_PFX msg); \
|
||||
} while (0)
|
||||
|
||||
#define SONY_LAPTOP_DRIVER_VERSION "0.5"
|
||||
#define SONY_LAPTOP_DRIVER_VERSION "0.6"
|
||||
|
||||
#define SONY_NC_CLASS "sony-nc"
|
||||
#define SONY_NC_HID "SNY5001"
|
||||
@ -146,68 +146,70 @@ struct sony_laptop_keypress {
|
||||
* and input layer indexes in the keymap
|
||||
*/
|
||||
static int sony_laptop_input_index[] = {
|
||||
-1, /* no event */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_DOWN */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_UP */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_PRESSED */
|
||||
-1, /* SONYPI_EVENT_JOGDIAL_RELEASED */
|
||||
0, /* SONYPI_EVENT_CAPTURE_PRESSED */
|
||||
1, /* SONYPI_EVENT_CAPTURE_RELEASED */
|
||||
2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
|
||||
3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
|
||||
4, /* SONYPI_EVENT_FNKEY_ESC */
|
||||
5, /* SONYPI_EVENT_FNKEY_F1 */
|
||||
6, /* SONYPI_EVENT_FNKEY_F2 */
|
||||
7, /* SONYPI_EVENT_FNKEY_F3 */
|
||||
8, /* SONYPI_EVENT_FNKEY_F4 */
|
||||
9, /* SONYPI_EVENT_FNKEY_F5 */
|
||||
10, /* SONYPI_EVENT_FNKEY_F6 */
|
||||
11, /* SONYPI_EVENT_FNKEY_F7 */
|
||||
12, /* SONYPI_EVENT_FNKEY_F8 */
|
||||
13, /* SONYPI_EVENT_FNKEY_F9 */
|
||||
14, /* SONYPI_EVENT_FNKEY_F10 */
|
||||
15, /* SONYPI_EVENT_FNKEY_F11 */
|
||||
16, /* SONYPI_EVENT_FNKEY_F12 */
|
||||
17, /* SONYPI_EVENT_FNKEY_1 */
|
||||
18, /* SONYPI_EVENT_FNKEY_2 */
|
||||
19, /* SONYPI_EVENT_FNKEY_D */
|
||||
20, /* SONYPI_EVENT_FNKEY_E */
|
||||
21, /* SONYPI_EVENT_FNKEY_F */
|
||||
22, /* SONYPI_EVENT_FNKEY_S */
|
||||
23, /* SONYPI_EVENT_FNKEY_B */
|
||||
24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */
|
||||
25, /* SONYPI_EVENT_PKEY_P1 */
|
||||
26, /* SONYPI_EVENT_PKEY_P2 */
|
||||
27, /* SONYPI_EVENT_PKEY_P3 */
|
||||
28, /* SONYPI_EVENT_BACK_PRESSED */
|
||||
-1, /* SONYPI_EVENT_LID_CLOSED */
|
||||
-1, /* SONYPI_EVENT_LID_OPENED */
|
||||
29, /* SONYPI_EVENT_BLUETOOTH_ON */
|
||||
30, /* SONYPI_EVENT_BLUETOOTH_OFF */
|
||||
31, /* SONYPI_EVENT_HELP_PRESSED */
|
||||
32, /* SONYPI_EVENT_FNKEY_ONLY */
|
||||
33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */
|
||||
34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */
|
||||
35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
|
||||
36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
|
||||
37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
|
||||
38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */
|
||||
39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
|
||||
40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
|
||||
41, /* SONYPI_EVENT_ZOOM_PRESSED */
|
||||
42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */
|
||||
43, /* SONYPI_EVENT_MEYE_FACE */
|
||||
44, /* SONYPI_EVENT_MEYE_OPPOSITE */
|
||||
45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */
|
||||
46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */
|
||||
-1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */
|
||||
-1, /* SONYPI_EVENT_BATTERY_INSERT */
|
||||
-1, /* SONYPI_EVENT_BATTERY_REMOVE */
|
||||
-1, /* SONYPI_EVENT_FNKEY_RELEASED */
|
||||
47, /* SONYPI_EVENT_WIRELESS_ON */
|
||||
48, /* SONYPI_EVENT_WIRELESS_OFF */
|
||||
-1, /* 0 no event */
|
||||
-1, /* 1 SONYPI_EVENT_JOGDIAL_DOWN */
|
||||
-1, /* 2 SONYPI_EVENT_JOGDIAL_UP */
|
||||
-1, /* 3 SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */
|
||||
-1, /* 4 SONYPI_EVENT_JOGDIAL_UP_PRESSED */
|
||||
-1, /* 5 SONYPI_EVENT_JOGDIAL_PRESSED */
|
||||
-1, /* 6 SONYPI_EVENT_JOGDIAL_RELEASED */
|
||||
0, /* 7 SONYPI_EVENT_CAPTURE_PRESSED */
|
||||
1, /* 8 SONYPI_EVENT_CAPTURE_RELEASED */
|
||||
2, /* 9 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
|
||||
3, /* 10 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
|
||||
4, /* 11 SONYPI_EVENT_FNKEY_ESC */
|
||||
5, /* 12 SONYPI_EVENT_FNKEY_F1 */
|
||||
6, /* 13 SONYPI_EVENT_FNKEY_F2 */
|
||||
7, /* 14 SONYPI_EVENT_FNKEY_F3 */
|
||||
8, /* 15 SONYPI_EVENT_FNKEY_F4 */
|
||||
9, /* 16 SONYPI_EVENT_FNKEY_F5 */
|
||||
10, /* 17 SONYPI_EVENT_FNKEY_F6 */
|
||||
11, /* 18 SONYPI_EVENT_FNKEY_F7 */
|
||||
12, /* 19 SONYPI_EVENT_FNKEY_F8 */
|
||||
13, /* 20 SONYPI_EVENT_FNKEY_F9 */
|
||||
14, /* 21 SONYPI_EVENT_FNKEY_F10 */
|
||||
15, /* 22 SONYPI_EVENT_FNKEY_F11 */
|
||||
16, /* 23 SONYPI_EVENT_FNKEY_F12 */
|
||||
17, /* 24 SONYPI_EVENT_FNKEY_1 */
|
||||
18, /* 25 SONYPI_EVENT_FNKEY_2 */
|
||||
19, /* 26 SONYPI_EVENT_FNKEY_D */
|
||||
20, /* 27 SONYPI_EVENT_FNKEY_E */
|
||||
21, /* 28 SONYPI_EVENT_FNKEY_F */
|
||||
22, /* 29 SONYPI_EVENT_FNKEY_S */
|
||||
23, /* 30 SONYPI_EVENT_FNKEY_B */
|
||||
24, /* 31 SONYPI_EVENT_BLUETOOTH_PRESSED */
|
||||
25, /* 32 SONYPI_EVENT_PKEY_P1 */
|
||||
26, /* 33 SONYPI_EVENT_PKEY_P2 */
|
||||
27, /* 34 SONYPI_EVENT_PKEY_P3 */
|
||||
28, /* 35 SONYPI_EVENT_BACK_PRESSED */
|
||||
-1, /* 36 SONYPI_EVENT_LID_CLOSED */
|
||||
-1, /* 37 SONYPI_EVENT_LID_OPENED */
|
||||
29, /* 38 SONYPI_EVENT_BLUETOOTH_ON */
|
||||
30, /* 39 SONYPI_EVENT_BLUETOOTH_OFF */
|
||||
31, /* 40 SONYPI_EVENT_HELP_PRESSED */
|
||||
32, /* 41 SONYPI_EVENT_FNKEY_ONLY */
|
||||
33, /* 42 SONYPI_EVENT_JOGDIAL_FAST_DOWN */
|
||||
34, /* 43 SONYPI_EVENT_JOGDIAL_FAST_UP */
|
||||
35, /* 44 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
|
||||
36, /* 45 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
|
||||
37, /* 46 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
|
||||
38, /* 47 SONYPI_EVENT_JOGDIAL_VFAST_UP */
|
||||
39, /* 48 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
|
||||
40, /* 49 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
|
||||
41, /* 50 SONYPI_EVENT_ZOOM_PRESSED */
|
||||
42, /* 51 SONYPI_EVENT_THUMBPHRASE_PRESSED */
|
||||
43, /* 52 SONYPI_EVENT_MEYE_FACE */
|
||||
44, /* 53 SONYPI_EVENT_MEYE_OPPOSITE */
|
||||
45, /* 54 SONYPI_EVENT_MEMORYSTICK_INSERT */
|
||||
46, /* 55 SONYPI_EVENT_MEMORYSTICK_EJECT */
|
||||
-1, /* 56 SONYPI_EVENT_ANYBUTTON_RELEASED */
|
||||
-1, /* 57 SONYPI_EVENT_BATTERY_INSERT */
|
||||
-1, /* 58 SONYPI_EVENT_BATTERY_REMOVE */
|
||||
-1, /* 59 SONYPI_EVENT_FNKEY_RELEASED */
|
||||
47, /* 60 SONYPI_EVENT_WIRELESS_ON */
|
||||
48, /* 61 SONYPI_EVENT_WIRELESS_OFF */
|
||||
49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
|
||||
50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
|
||||
};
|
||||
|
||||
static int sony_laptop_input_keycode_map[] = {
|
||||
@ -260,6 +262,8 @@ static int sony_laptop_input_keycode_map[] = {
|
||||
KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */
|
||||
KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
|
||||
KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
|
||||
KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
|
||||
KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
|
||||
};
|
||||
|
||||
/* release buttons after a short delay if pressed */
|
||||
@ -311,7 +315,7 @@ static void sony_laptop_report_input_event(u8 event)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) {
|
||||
if (event > ARRAY_SIZE(sony_laptop_input_index)) {
|
||||
dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
|
||||
break;
|
||||
}
|
||||
@ -875,6 +879,15 @@ static const struct dmi_system_id sony_nc_ids[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Sony Vaio N Series",
|
||||
.callback = sony_nc_C_enable,
|
||||
.driver_data = sony_C_events,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -1169,10 +1182,12 @@ static struct acpi_driver sony_nc_driver = {
|
||||
#define SONYPI_DEVICE_TYPE1 0x00000001
|
||||
#define SONYPI_DEVICE_TYPE2 0x00000002
|
||||
#define SONYPI_DEVICE_TYPE3 0x00000004
|
||||
#define SONYPI_DEVICE_TYPE4 0x00000008
|
||||
|
||||
#define SONYPI_TYPE1_OFFSET 0x04
|
||||
#define SONYPI_TYPE2_OFFSET 0x12
|
||||
#define SONYPI_TYPE3_OFFSET 0x12
|
||||
#define SONYPI_TYPE4_OFFSET 0x12
|
||||
|
||||
struct sony_pic_ioport {
|
||||
struct acpi_resource_io io1;
|
||||
@ -1185,18 +1200,33 @@ struct sony_pic_irq {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct sonypi_eventtypes {
|
||||
u8 data;
|
||||
unsigned long mask;
|
||||
struct sonypi_event *events;
|
||||
};
|
||||
|
||||
struct device_ctrl {
|
||||
int model;
|
||||
int (*handle_irq)(const u8, const u8);
|
||||
u16 evport_offset;
|
||||
u8 has_camera;
|
||||
u8 has_bluetooth;
|
||||
u8 has_wwan;
|
||||
struct sonypi_eventtypes *event_types;
|
||||
};
|
||||
|
||||
struct sony_pic_dev {
|
||||
int model;
|
||||
u16 evport_offset;
|
||||
u8 camera_power;
|
||||
u8 bluetooth_power;
|
||||
u8 wwan_power;
|
||||
struct device_ctrl *control;
|
||||
struct acpi_device *acpi_dev;
|
||||
struct sony_pic_irq *cur_irq;
|
||||
struct sony_pic_ioport *cur_ioport;
|
||||
struct list_head interrupts;
|
||||
struct list_head ioports;
|
||||
struct mutex lock;
|
||||
u8 camera_power;
|
||||
u8 bluetooth_power;
|
||||
u8 wwan_power;
|
||||
};
|
||||
|
||||
static struct sony_pic_dev spic_dev = {
|
||||
@ -1253,6 +1283,7 @@ static struct sonypi_event sonypi_joggerev[] = {
|
||||
static struct sonypi_event sonypi_captureev[] = {
|
||||
{ 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
|
||||
{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
|
||||
{ 0x40, SONYPI_EVENT_CAPTURE_PRESSED },
|
||||
{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
|
||||
{ 0, 0 }
|
||||
};
|
||||
@ -1289,7 +1320,6 @@ static struct sonypi_event sonypi_pkeyev[] = {
|
||||
{ 0x01, SONYPI_EVENT_PKEY_P1 },
|
||||
{ 0x02, SONYPI_EVENT_PKEY_P2 },
|
||||
{ 0x04, SONYPI_EVENT_PKEY_P3 },
|
||||
{ 0x5c, SONYPI_EVENT_PKEY_P1 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -1331,6 +1361,8 @@ static struct sonypi_event sonypi_lidev[] = {
|
||||
/* The set of possible zoom events */
|
||||
static struct sonypi_event sonypi_zoomev[] = {
|
||||
{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
|
||||
{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
|
||||
{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -1361,76 +1393,58 @@ static struct sonypi_event sonypi_batteryev[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static struct sonypi_eventtypes {
|
||||
int model;
|
||||
u8 data;
|
||||
unsigned long mask;
|
||||
struct sonypi_event * events;
|
||||
} sony_pic_eventtypes[] = {
|
||||
{ SONYPI_DEVICE_TYPE1, 0, 0xffffffff, sonypi_releaseev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ SONYPI_DEVICE_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
|
||||
{ SONYPI_DEVICE_TYPE2, 0, 0xffffffff, sonypi_releaseev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ SONYPI_DEVICE_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
|
||||
{ SONYPI_DEVICE_TYPE3, 0, 0xffffffff, sonypi_releaseev },
|
||||
{ SONYPI_DEVICE_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
|
||||
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ SONYPI_DEVICE_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ SONYPI_DEVICE_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0 }
|
||||
static struct sonypi_eventtypes type1_events[] = {
|
||||
{ 0, 0xffffffff, sonypi_releaseev },
|
||||
{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
|
||||
{ 0x30, SONYPI_LID_MASK, sonypi_lidev },
|
||||
{ 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
|
||||
{ 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
|
||||
{ 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
|
||||
{ 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ 0 },
|
||||
};
|
||||
static struct sonypi_eventtypes type2_events[] = {
|
||||
{ 0, 0xffffffff, sonypi_releaseev },
|
||||
{ 0x38, SONYPI_LID_MASK, sonypi_lidev },
|
||||
{ 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
|
||||
{ 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
|
||||
{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
|
||||
{ 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0x11, SONYPI_BACK_MASK, sonypi_backev },
|
||||
{ 0x21, SONYPI_HELP_MASK, sonypi_helpev },
|
||||
{ 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
|
||||
{ 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
|
||||
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0 },
|
||||
};
|
||||
static struct sonypi_eventtypes type3_events[] = {
|
||||
{ 0, 0xffffffff, sonypi_releaseev },
|
||||
{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
|
||||
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0 },
|
||||
};
|
||||
static struct sonypi_eventtypes type4_events[] = {
|
||||
{ 0, 0xffffffff, sonypi_releaseev },
|
||||
{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
|
||||
{ 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
|
||||
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
|
||||
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
|
||||
{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
|
||||
{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
|
||||
{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static int sony_pic_detect_device_type(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
int model = 0;
|
||||
|
||||
if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
|
||||
model = SONYPI_DEVICE_TYPE1;
|
||||
|
||||
else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
|
||||
model = SONYPI_DEVICE_TYPE3;
|
||||
|
||||
else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
|
||||
model = SONYPI_DEVICE_TYPE3;
|
||||
|
||||
else
|
||||
model = SONYPI_DEVICE_TYPE2;
|
||||
|
||||
if (pcidev)
|
||||
pci_dev_put(pcidev);
|
||||
|
||||
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
|
||||
model == SONYPI_DEVICE_TYPE1 ? 1 :
|
||||
model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
|
||||
return model;
|
||||
}
|
||||
|
||||
/* low level spic calls */
|
||||
#define ITERATIONS_LONG 10000
|
||||
#define ITERATIONS_SHORT 10
|
||||
#define wait_on_command(command, iterations) { \
|
||||
@ -1451,7 +1465,7 @@ static u8 sony_pic_call1(u8 dev)
|
||||
outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
|
||||
v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
|
||||
v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
|
||||
dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1);
|
||||
dprintk("sony_pic_call1(0x%.2x): 0x%.4x\n", dev, (v2 << 8) | v1);
|
||||
return v2;
|
||||
}
|
||||
|
||||
@ -1466,7 +1480,7 @@ static u8 sony_pic_call2(u8 dev, u8 fn)
|
||||
ITERATIONS_LONG);
|
||||
outb(fn, spic_dev.cur_ioport->io1.minimum);
|
||||
v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
|
||||
dprintk("sony_pic_call2: 0x%.4x\n", v1);
|
||||
dprintk("sony_pic_call2(0x%.2x - 0x%.2x): 0x%.4x\n", dev, fn, v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
@ -1481,10 +1495,105 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
|
||||
wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
|
||||
outb(v, spic_dev.cur_ioport->io1.minimum);
|
||||
v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
|
||||
dprintk("sony_pic_call3: 0x%.4x\n", v1);
|
||||
dprintk("sony_pic_call3(0x%.2x - 0x%.2x - 0x%.2x): 0x%.4x\n",
|
||||
dev, fn, v, v1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/*
|
||||
* minidrivers for SPIC models
|
||||
*/
|
||||
static int type4_handle_irq(const u8 data_mask, const u8 ev)
|
||||
{
|
||||
/*
|
||||
* 0x31 could mean we have to take some extra action and wait for
|
||||
* the next irq for some Type4 models, it will generate a new
|
||||
* irq and we can read new data from the device:
|
||||
* - 0x5c and 0x5f requires 0xA0
|
||||
* - 0x61 requires 0xB3
|
||||
*/
|
||||
if (data_mask == 0x31) {
|
||||
if (ev == 0x5c || ev == 0x5f)
|
||||
sony_pic_call1(0xA0);
|
||||
else if (ev == 0x61)
|
||||
sony_pic_call1(0xB3);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct device_ctrl spic_types[] = {
|
||||
{
|
||||
.model = SONYPI_DEVICE_TYPE1,
|
||||
.handle_irq = NULL,
|
||||
.evport_offset = SONYPI_TYPE1_OFFSET,
|
||||
.event_types = type1_events,
|
||||
},
|
||||
{
|
||||
.model = SONYPI_DEVICE_TYPE2,
|
||||
.handle_irq = NULL,
|
||||
.evport_offset = SONYPI_TYPE2_OFFSET,
|
||||
.event_types = type2_events,
|
||||
},
|
||||
{
|
||||
.model = SONYPI_DEVICE_TYPE3,
|
||||
.handle_irq = NULL,
|
||||
.evport_offset = SONYPI_TYPE3_OFFSET,
|
||||
.event_types = type3_events,
|
||||
},
|
||||
{
|
||||
.model = SONYPI_DEVICE_TYPE4,
|
||||
.handle_irq = type4_handle_irq,
|
||||
.evport_offset = SONYPI_TYPE4_OFFSET,
|
||||
.event_types = type4_events,
|
||||
},
|
||||
};
|
||||
|
||||
static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
|
||||
if (pcidev) {
|
||||
dev->control = &spic_types[0];
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
|
||||
if (pcidev) {
|
||||
dev->control = &spic_types[2];
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
|
||||
if (pcidev) {
|
||||
dev->control = &spic_types[3];
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
|
||||
if (pcidev) {
|
||||
dev->control = &spic_types[3];
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* default */
|
||||
dev->control = &spic_types[1];
|
||||
|
||||
out:
|
||||
if (pcidev)
|
||||
pci_dev_put(pcidev);
|
||||
|
||||
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
|
||||
dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
|
||||
dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
|
||||
dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
|
||||
}
|
||||
|
||||
/* camera tests and poweron/poweroff */
|
||||
#define SONYPI_CAMERA_PICTURE 5
|
||||
#define SONYPI_CAMERA_CONTROL 0x10
|
||||
@ -2253,7 +2362,7 @@ static int sony_pic_enable(struct acpi_device *device,
|
||||
buffer.pointer = resource;
|
||||
|
||||
/* setup Type 1 resources */
|
||||
if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
|
||||
if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) {
|
||||
|
||||
/* setup io resources */
|
||||
resource->res1.type = ACPI_RESOURCE_TYPE_IO;
|
||||
@ -2335,39 +2444,49 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
|
||||
if (dev->cur_ioport->io2.minimum)
|
||||
data_mask = inb_p(dev->cur_ioport->io2.minimum);
|
||||
else
|
||||
data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
|
||||
data_mask = inb_p(dev->cur_ioport->io1.minimum +
|
||||
dev->control->evport_offset);
|
||||
|
||||
dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
|
||||
ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
|
||||
ev, data_mask, dev->cur_ioport->io1.minimum,
|
||||
dev->control->evport_offset);
|
||||
|
||||
if (ev == 0x00 || ev == 0xff)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
for (i = 0; sony_pic_eventtypes[i].model; i++) {
|
||||
for (i = 0; dev->control->event_types[i].mask; i++) {
|
||||
|
||||
if (spic_dev.model != sony_pic_eventtypes[i].model)
|
||||
if ((data_mask & dev->control->event_types[i].data) !=
|
||||
dev->control->event_types[i].data)
|
||||
continue;
|
||||
|
||||
if ((data_mask & sony_pic_eventtypes[i].data) !=
|
||||
sony_pic_eventtypes[i].data)
|
||||
if (!(mask & dev->control->event_types[i].mask))
|
||||
continue;
|
||||
|
||||
if (!(mask & sony_pic_eventtypes[i].mask))
|
||||
continue;
|
||||
|
||||
for (j = 0; sony_pic_eventtypes[i].events[j].event; j++) {
|
||||
if (ev == sony_pic_eventtypes[i].events[j].data) {
|
||||
for (j = 0; dev->control->event_types[i].events[j].event; j++) {
|
||||
if (ev == dev->control->event_types[i].events[j].data) {
|
||||
device_event =
|
||||
sony_pic_eventtypes[i].events[j].event;
|
||||
dev->control->
|
||||
event_types[i].events[j].event;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Still not able to decode the event try to pass
|
||||
* it over to the minidriver
|
||||
*/
|
||||
if (dev->control->handle_irq &&
|
||||
dev->control->handle_irq(data_mask, ev) == 0)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
|
||||
ev, data_mask, dev->cur_ioport->io1.minimum,
|
||||
dev->control->evport_offset);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
found:
|
||||
sony_laptop_report_input_event(device_event);
|
||||
acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event);
|
||||
acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
|
||||
sonypi_compat_report_event(device_event);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@ -2429,23 +2548,9 @@ static int sony_pic_add(struct acpi_device *device)
|
||||
|
||||
spic_dev.acpi_dev = device;
|
||||
strcpy(acpi_device_class(device), "sony/hotkey");
|
||||
spic_dev.model = sony_pic_detect_device_type();
|
||||
sony_pic_detect_device_type(&spic_dev);
|
||||
mutex_init(&spic_dev.lock);
|
||||
|
||||
/* model specific characteristics */
|
||||
switch(spic_dev.model) {
|
||||
case SONYPI_DEVICE_TYPE1:
|
||||
spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
|
||||
break;
|
||||
case SONYPI_DEVICE_TYPE3:
|
||||
spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
|
||||
break;
|
||||
case SONYPI_DEVICE_TYPE2:
|
||||
default:
|
||||
spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
/* read _PRS resources */
|
||||
result = sony_pic_possible_resources(device);
|
||||
if (result) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,606 +0,0 @@
|
||||
/*
|
||||
* thinkpad_acpi.h - ThinkPad ACPI Extras
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
|
||||
* Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __THINKPAD_ACPI_H__
|
||||
#define __THINKPAD_ACPI_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <linux/nvram.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/input.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <acpi/acnamesp.h>
|
||||
|
||||
#include <linux/pci_ids.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Main driver
|
||||
*/
|
||||
|
||||
#define IBM_NAME "thinkpad"
|
||||
#define IBM_DESC "ThinkPad ACPI Extras"
|
||||
#define IBM_FILE IBM_NAME "_acpi"
|
||||
#define IBM_URL "http://ibm-acpi.sf.net/"
|
||||
#define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
|
||||
|
||||
#define IBM_PROC_DIR "ibm"
|
||||
#define IBM_ACPI_EVENT_PREFIX "ibm"
|
||||
#define IBM_DRVR_NAME IBM_FILE
|
||||
#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"
|
||||
|
||||
#define IBM_LOG IBM_FILE ": "
|
||||
#define IBM_ERR KERN_ERR IBM_LOG
|
||||
#define IBM_NOTICE KERN_NOTICE IBM_LOG
|
||||
#define IBM_INFO KERN_INFO IBM_LOG
|
||||
#define IBM_DEBUG KERN_DEBUG IBM_LOG
|
||||
|
||||
#define IBM_MAX_ACPI_ARGS 3
|
||||
|
||||
/* ThinkPad CMOS commands */
|
||||
#define TP_CMOS_VOLUME_DOWN 0
|
||||
#define TP_CMOS_VOLUME_UP 1
|
||||
#define TP_CMOS_VOLUME_MUTE 2
|
||||
#define TP_CMOS_BRIGHTNESS_UP 4
|
||||
#define TP_CMOS_BRIGHTNESS_DOWN 5
|
||||
|
||||
/* ThinkPad CMOS NVRAM constants */
|
||||
#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e
|
||||
#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x0f
|
||||
#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
|
||||
|
||||
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
|
||||
#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
|
||||
#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
|
||||
|
||||
/* Debugging */
|
||||
#define TPACPI_DBG_ALL 0xffff
|
||||
#define TPACPI_DBG_ALL 0xffff
|
||||
#define TPACPI_DBG_INIT 0x0001
|
||||
#define TPACPI_DBG_EXIT 0x0002
|
||||
#define dbg_printk(a_dbg_level, format, arg...) \
|
||||
do { if (dbg_level & a_dbg_level) \
|
||||
printk(IBM_DEBUG "%s: " format, __func__ , ## arg); } while (0)
|
||||
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
|
||||
#define vdbg_printk(a_dbg_level, format, arg...) \
|
||||
dbg_printk(a_dbg_level, format, ## arg)
|
||||
static const char *str_supported(int is_supported);
|
||||
#else
|
||||
#define vdbg_printk(a_dbg_level, format, arg...)
|
||||
#endif
|
||||
|
||||
/* Input IDs */
|
||||
#define TPACPI_HKEY_INPUT_VENDOR PCI_VENDOR_ID_IBM
|
||||
#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
|
||||
#define TPACPI_HKEY_INPUT_VERSION 0x4101
|
||||
|
||||
/* ACPI HIDs */
|
||||
#define IBM_HKEY_HID "IBM0068"
|
||||
|
||||
/* ACPI helpers */
|
||||
static int __must_check acpi_evalf(acpi_handle handle,
|
||||
void *res, char *method, char *fmt, ...);
|
||||
static int __must_check acpi_ec_read(int i, u8 * p);
|
||||
static int __must_check acpi_ec_write(int i, u8 v);
|
||||
static int __must_check _sta(acpi_handle handle);
|
||||
|
||||
/* ACPI handles */
|
||||
static acpi_handle root_handle; /* root namespace */
|
||||
static acpi_handle ec_handle; /* EC */
|
||||
static acpi_handle ecrd_handle, ecwr_handle; /* 570 EC access */
|
||||
static acpi_handle cmos_handle, hkey_handle; /* basic thinkpad handles */
|
||||
|
||||
static void drv_acpi_handle_init(char *name,
|
||||
acpi_handle *handle, acpi_handle parent,
|
||||
char **paths, int num_paths, char **path);
|
||||
#define IBM_ACPIHANDLE_INIT(object) \
|
||||
drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
|
||||
object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
|
||||
|
||||
/* ThinkPad ACPI helpers */
|
||||
static int issue_thinkpad_cmos_command(int cmos_cmd);
|
||||
|
||||
/* procfs support */
|
||||
static struct proc_dir_entry *proc_dir;
|
||||
|
||||
/* procfs helpers */
|
||||
static int dispatch_procfs_read(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data);
|
||||
static int dispatch_procfs_write(struct file *file,
|
||||
const char __user * userbuf,
|
||||
unsigned long count, void *data);
|
||||
static char *next_cmd(char **cmds);
|
||||
|
||||
/* sysfs support */
|
||||
struct attribute_set {
|
||||
unsigned int members, max_members;
|
||||
struct attribute_group group;
|
||||
};
|
||||
|
||||
static struct attribute_set *create_attr_set(unsigned int max_members,
|
||||
const char* name);
|
||||
#define destroy_attr_set(_set) \
|
||||
kfree(_set);
|
||||
static int add_to_attr_set(struct attribute_set* s, struct attribute *attr);
|
||||
static int add_many_to_attr_set(struct attribute_set* s,
|
||||
struct attribute **attr,
|
||||
unsigned int count);
|
||||
#define register_attr_set_with_sysfs(_attr_set, _kobj) \
|
||||
sysfs_create_group(_kobj, &_attr_set->group)
|
||||
static void delete_attr_set(struct attribute_set* s, struct kobject *kobj);
|
||||
|
||||
static int parse_strtoul(const char *buf, unsigned long max,
|
||||
unsigned long *value);
|
||||
|
||||
/* Device model */
|
||||
static struct platform_device *tpacpi_pdev;
|
||||
static struct platform_device *tpacpi_sensors_pdev;
|
||||
static struct device *tpacpi_hwmon;
|
||||
static struct platform_driver tpacpi_pdriver;
|
||||
static struct input_dev *tpacpi_inputdev;
|
||||
static int tpacpi_create_driver_attributes(struct device_driver *drv);
|
||||
static void tpacpi_remove_driver_attributes(struct device_driver *drv);
|
||||
|
||||
/* Module */
|
||||
static int experimental;
|
||||
static u32 dbg_level;
|
||||
static int force_load;
|
||||
static unsigned int hotkey_report_mode;
|
||||
|
||||
static int thinkpad_acpi_module_init(void);
|
||||
static void thinkpad_acpi_module_exit(void);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Subdrivers
|
||||
*/
|
||||
|
||||
struct ibm_struct;
|
||||
|
||||
struct tp_acpi_drv_struct {
|
||||
const struct acpi_device_id *hid;
|
||||
struct acpi_driver *driver;
|
||||
|
||||
void (*notify) (struct ibm_struct *, u32);
|
||||
acpi_handle *handle;
|
||||
u32 type;
|
||||
struct acpi_device *device;
|
||||
};
|
||||
|
||||
struct ibm_struct {
|
||||
char *name;
|
||||
|
||||
int (*read) (char *);
|
||||
int (*write) (char *);
|
||||
void (*exit) (void);
|
||||
void (*resume) (void);
|
||||
|
||||
struct list_head all_drivers;
|
||||
|
||||
struct tp_acpi_drv_struct *acpi;
|
||||
|
||||
struct {
|
||||
u8 acpi_driver_registered:1;
|
||||
u8 acpi_notify_installed:1;
|
||||
u8 proc_created:1;
|
||||
u8 init_called:1;
|
||||
u8 experimental:1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
struct ibm_init_struct {
|
||||
char param[32];
|
||||
|
||||
int (*init) (struct ibm_init_struct *);
|
||||
struct ibm_struct *data;
|
||||
};
|
||||
|
||||
static struct {
|
||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
||||
u32 bay_status:1;
|
||||
u32 bay_eject:1;
|
||||
u32 bay_status2:1;
|
||||
u32 bay_eject2:1;
|
||||
#endif
|
||||
u32 bluetooth:1;
|
||||
u32 hotkey:1;
|
||||
u32 hotkey_mask:1;
|
||||
u32 hotkey_wlsw:1;
|
||||
u32 light:1;
|
||||
u32 light_status:1;
|
||||
u32 bright_16levels:1;
|
||||
u32 wan:1;
|
||||
u32 fan_ctrl_status_undef:1;
|
||||
u32 input_device_registered:1;
|
||||
u32 platform_drv_registered:1;
|
||||
u32 platform_drv_attrs_registered:1;
|
||||
u32 sensors_pdrv_registered:1;
|
||||
u32 sensors_pdrv_attrs_registered:1;
|
||||
u32 sensors_pdev_attrs_registered:1;
|
||||
} tp_features;
|
||||
|
||||
struct thinkpad_id_data {
|
||||
unsigned int vendor; /* ThinkPad vendor:
|
||||
* PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
|
||||
|
||||
char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
|
||||
char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
|
||||
|
||||
u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
|
||||
u16 ec_model;
|
||||
|
||||
char *model_str;
|
||||
};
|
||||
|
||||
static struct thinkpad_id_data thinkpad_id;
|
||||
|
||||
static struct list_head tpacpi_all_drivers;
|
||||
|
||||
static struct ibm_init_struct ibms_init[];
|
||||
static int set_ibm_param(const char *val, struct kernel_param *kp);
|
||||
static int ibm_init(struct ibm_init_struct *iibm);
|
||||
static void ibm_exit(struct ibm_struct *ibm);
|
||||
|
||||
|
||||
/*
|
||||
* procfs master subdriver
|
||||
*/
|
||||
static int thinkpad_acpi_driver_init(struct ibm_init_struct *iibm);
|
||||
static int thinkpad_acpi_driver_read(char *p);
|
||||
|
||||
|
||||
/*
|
||||
* Bay subdriver
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_THINKPAD_ACPI_BAY
|
||||
static acpi_handle bay_handle, bay_ej_handle;
|
||||
static acpi_handle bay2_handle, bay2_ej_handle;
|
||||
|
||||
static int bay_init(struct ibm_init_struct *iibm);
|
||||
static void bay_notify(struct ibm_struct *ibm, u32 event);
|
||||
static int bay_read(char *p);
|
||||
static int bay_write(char *buf);
|
||||
#endif /* CONFIG_THINKPAD_ACPI_BAY */
|
||||
|
||||
|
||||
/*
|
||||
* Beep subdriver
|
||||
*/
|
||||
|
||||
static acpi_handle beep_handle;
|
||||
|
||||
static int beep_read(char *p);
|
||||
static int beep_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Bluetooth subdriver
|
||||
*/
|
||||
|
||||
enum {
|
||||
/* ACPI GBDC/SBDC bits */
|
||||
TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
|
||||
TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
|
||||
TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */
|
||||
};
|
||||
|
||||
static int bluetooth_init(struct ibm_init_struct *iibm);
|
||||
static int bluetooth_get_radiosw(void);
|
||||
static int bluetooth_set_radiosw(int radio_on);
|
||||
static int bluetooth_read(char *p);
|
||||
static int bluetooth_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Brightness (backlight) subdriver
|
||||
*/
|
||||
|
||||
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
|
||||
|
||||
static struct backlight_device *ibm_backlight_device;
|
||||
static int brightness_offset = 0x31;
|
||||
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 void brightness_exit(void);
|
||||
static int brightness_get(struct backlight_device *bd);
|
||||
static int brightness_set(int value);
|
||||
static int brightness_update_status(struct backlight_device *bd);
|
||||
static int brightness_read(char *p);
|
||||
static int brightness_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* CMOS subdriver
|
||||
*/
|
||||
|
||||
static int cmos_read(char *p);
|
||||
static int cmos_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Dock subdriver
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_THINKPAD_ACPI_DOCK
|
||||
static acpi_handle pci_handle;
|
||||
static acpi_handle dock_handle;
|
||||
|
||||
static void dock_notify(struct ibm_struct *ibm, u32 event);
|
||||
static int dock_read(char *p);
|
||||
static int dock_write(char *buf);
|
||||
#endif /* CONFIG_THINKPAD_ACPI_DOCK */
|
||||
|
||||
|
||||
/*
|
||||
* EC dump subdriver
|
||||
*/
|
||||
|
||||
static int ecdump_read(char *p) ;
|
||||
static int ecdump_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Fan subdriver
|
||||
*/
|
||||
|
||||
enum { /* Fan control constants */
|
||||
fan_status_offset = 0x2f, /* EC register 0x2f */
|
||||
fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
|
||||
* 0x84 must be read before 0x85 */
|
||||
|
||||
TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */
|
||||
TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */
|
||||
|
||||
TPACPI_FAN_LAST_LEVEL = 0x100, /* Use cached last-seen fan level */
|
||||
};
|
||||
|
||||
enum fan_status_access_mode {
|
||||
TPACPI_FAN_NONE = 0, /* No fan status or control */
|
||||
TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */
|
||||
TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */
|
||||
};
|
||||
|
||||
enum fan_control_access_mode {
|
||||
TPACPI_FAN_WR_NONE = 0, /* No fan control */
|
||||
TPACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */
|
||||
TPACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */
|
||||
TPACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */
|
||||
};
|
||||
|
||||
enum fan_control_commands {
|
||||
TPACPI_FAN_CMD_SPEED = 0x0001, /* speed command */
|
||||
TPACPI_FAN_CMD_LEVEL = 0x0002, /* level command */
|
||||
TPACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd,
|
||||
* and also watchdog cmd */
|
||||
};
|
||||
|
||||
static int fan_control_allowed;
|
||||
|
||||
static enum fan_status_access_mode fan_status_access_mode;
|
||||
static enum fan_control_access_mode fan_control_access_mode;
|
||||
static enum fan_control_commands fan_control_commands;
|
||||
static u8 fan_control_initial_status;
|
||||
static u8 fan_control_desired_level;
|
||||
static int fan_watchdog_maxinterval;
|
||||
|
||||
static struct mutex fan_mutex;
|
||||
|
||||
static acpi_handle fans_handle, gfan_handle, sfan_handle;
|
||||
|
||||
static int fan_init(struct ibm_init_struct *iibm);
|
||||
static void fan_exit(void);
|
||||
static int fan_get_status(u8 *status);
|
||||
static int fan_get_status_safe(u8 *status);
|
||||
static int fan_get_speed(unsigned int *speed);
|
||||
static void fan_update_desired_level(u8 status);
|
||||
static void fan_watchdog_fire(struct work_struct *ignored);
|
||||
static void fan_watchdog_reset(void);
|
||||
static int fan_set_level(int level);
|
||||
static int fan_set_level_safe(int level);
|
||||
static int fan_set_enable(void);
|
||||
static int fan_set_disable(void);
|
||||
static int fan_set_speed(int speed);
|
||||
static int fan_read(char *p);
|
||||
static int fan_write(char *buf);
|
||||
static int fan_write_cmd_level(const char *cmd, int *rc);
|
||||
static int fan_write_cmd_enable(const char *cmd, int *rc);
|
||||
static int fan_write_cmd_disable(const char *cmd, int *rc);
|
||||
static int fan_write_cmd_speed(const char *cmd, int *rc);
|
||||
static int fan_write_cmd_watchdog(const char *cmd, int *rc);
|
||||
|
||||
|
||||
/*
|
||||
* Hotkey subdriver
|
||||
*/
|
||||
|
||||
static int hotkey_orig_status;
|
||||
static u32 hotkey_orig_mask;
|
||||
|
||||
static struct mutex hotkey_mutex;
|
||||
|
||||
static int hotkey_init(struct ibm_init_struct *iibm);
|
||||
static void hotkey_exit(void);
|
||||
static int hotkey_get(int *status, u32 *mask);
|
||||
static int hotkey_set(int status, u32 mask);
|
||||
static void hotkey_notify(struct ibm_struct *ibm, u32 event);
|
||||
static int hotkey_read(char *p);
|
||||
static int hotkey_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* LED subdriver
|
||||
*/
|
||||
|
||||
enum led_access_mode {
|
||||
TPACPI_LED_NONE = 0,
|
||||
TPACPI_LED_570, /* 570 */
|
||||
TPACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
|
||||
TPACPI_LED_NEW, /* all others */
|
||||
};
|
||||
|
||||
enum { /* For TPACPI_LED_OLD */
|
||||
TPACPI_LED_EC_HLCL = 0x0c, /* EC reg to get led to power on */
|
||||
TPACPI_LED_EC_HLBL = 0x0d, /* EC reg to blink a lit led */
|
||||
TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
|
||||
};
|
||||
|
||||
static enum led_access_mode led_supported;
|
||||
static acpi_handle led_handle;
|
||||
|
||||
static int led_init(struct ibm_init_struct *iibm);
|
||||
static int led_read(char *p);
|
||||
static int led_write(char *buf);
|
||||
|
||||
/*
|
||||
* Light (thinklight) subdriver
|
||||
*/
|
||||
|
||||
static acpi_handle lght_handle, ledb_handle;
|
||||
|
||||
static int light_init(struct ibm_init_struct *iibm);
|
||||
static int light_read(char *p);
|
||||
static int light_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Thermal subdriver
|
||||
*/
|
||||
|
||||
enum thermal_access_mode {
|
||||
TPACPI_THERMAL_NONE = 0, /* No thermal support */
|
||||
TPACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */
|
||||
TPACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */
|
||||
TPACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */
|
||||
TPACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */
|
||||
};
|
||||
|
||||
enum { /* TPACPI_THERMAL_TPEC_* */
|
||||
TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */
|
||||
TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */
|
||||
TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */
|
||||
};
|
||||
|
||||
#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
|
||||
struct ibm_thermal_sensors_struct {
|
||||
s32 temp[TPACPI_MAX_THERMAL_SENSORS];
|
||||
};
|
||||
|
||||
static enum thermal_access_mode thermal_read_mode;
|
||||
|
||||
static int thermal_init(struct ibm_init_struct *iibm);
|
||||
static int thermal_get_sensor(int idx, s32 *value);
|
||||
static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s);
|
||||
static int thermal_read(char *p);
|
||||
|
||||
|
||||
/*
|
||||
* Video subdriver
|
||||
*/
|
||||
|
||||
enum video_access_mode {
|
||||
TPACPI_VIDEO_NONE = 0,
|
||||
TPACPI_VIDEO_570, /* 570 */
|
||||
TPACPI_VIDEO_770, /* 600e/x, 770e, 770x */
|
||||
TPACPI_VIDEO_NEW, /* all others */
|
||||
};
|
||||
|
||||
enum { /* video status flags, based on VIDEO_570 */
|
||||
TP_ACPI_VIDEO_S_LCD = 0x01, /* LCD output enabled */
|
||||
TP_ACPI_VIDEO_S_CRT = 0x02, /* CRT output enabled */
|
||||
TP_ACPI_VIDEO_S_DVI = 0x08, /* DVI output enabled */
|
||||
};
|
||||
|
||||
enum { /* TPACPI_VIDEO_570 constants */
|
||||
TP_ACPI_VIDEO_570_PHSCMD = 0x87, /* unknown magic constant :( */
|
||||
TP_ACPI_VIDEO_570_PHSMASK = 0x03, /* PHS bits that map to
|
||||
* video_status_flags */
|
||||
TP_ACPI_VIDEO_570_PHS2CMD = 0x8b, /* unknown magic constant :( */
|
||||
TP_ACPI_VIDEO_570_PHS2SET = 0x80, /* unknown magic constant :( */
|
||||
};
|
||||
|
||||
static enum video_access_mode video_supported;
|
||||
static int video_orig_autosw;
|
||||
static acpi_handle vid_handle, vid2_handle;
|
||||
|
||||
static int video_init(struct ibm_init_struct *iibm);
|
||||
static void video_exit(void);
|
||||
static int video_outputsw_get(void);
|
||||
static int video_outputsw_set(int status);
|
||||
static int video_autosw_get(void);
|
||||
static int video_autosw_set(int enable);
|
||||
static int video_outputsw_cycle(void);
|
||||
static int video_expand_toggle(void);
|
||||
static int video_read(char *p);
|
||||
static int video_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Volume subdriver
|
||||
*/
|
||||
|
||||
static int volume_offset = 0x30;
|
||||
|
||||
static int volume_read(char *p);
|
||||
static int volume_write(char *buf);
|
||||
|
||||
|
||||
/*
|
||||
* Wan subdriver
|
||||
*/
|
||||
|
||||
enum {
|
||||
/* ACPI GWAN/SWAN bits */
|
||||
TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
|
||||
TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
|
||||
TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */
|
||||
};
|
||||
|
||||
static int wan_init(struct ibm_init_struct *iibm);
|
||||
static int wan_get_radiosw(void);
|
||||
static int wan_set_radiosw(int radio_on);
|
||||
static int wan_read(char *p);
|
||||
static int wan_write(char *buf);
|
||||
|
||||
|
||||
#endif /* __THINKPAD_ACPI_H */
|
@ -101,6 +101,8 @@
|
||||
#define SONYPI_EVENT_FNKEY_RELEASED 59
|
||||
#define SONYPI_EVENT_WIRELESS_ON 60
|
||||
#define SONYPI_EVENT_WIRELESS_OFF 61
|
||||
#define SONYPI_EVENT_ZOOM_IN_PRESSED 62
|
||||
#define SONYPI_EVENT_ZOOM_OUT_PRESSED 63
|
||||
|
||||
/* get/set brightness */
|
||||
#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
|
||||
|
Loading…
Reference in New Issue
Block a user