aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt114
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c1178
2 files changed, 963 insertions, 329 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index aafcaa634191..169091f75e6d 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -1,7 +1,7 @@
1 ThinkPad ACPI Extras Driver 1 ThinkPad ACPI Extras Driver
2 2
3 Version 0.23 3 Version 0.24
4 April 10th, 2009 4 December 11th, 2009
5 5
6 Borislav Deianov <borislav@users.sf.net> 6 Borislav Deianov <borislav@users.sf.net>
7 Henrique de Moraes Holschuh <hmh@hmh.eng.br> 7 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
@@ -460,6 +460,8 @@ event code Key Notes
460 For Lenovo ThinkPads with a new 460 For Lenovo ThinkPads with a new
461 BIOS, it has to be handled either 461 BIOS, it has to be handled either
462 by the ACPI OSI, or by userspace. 462 by the ACPI OSI, or by userspace.
463 The driver does the right thing,
464 never mess with this.
4630x1011 0x10 FN+END Brightness down. See brightness 4650x1011 0x10 FN+END Brightness down. See brightness
464 up for details. 466 up for details.
465 467
@@ -582,46 +584,15 @@ with hotkey_report_mode.
582 584
583Brightness hotkey notes: 585Brightness hotkey notes:
584 586
585These are the current sane choices for brightness key mapping in 587Don't mess with the brightness hotkeys in a Thinkpad. If you want
586thinkpad-acpi: 588notifications for OSD, use the sysfs backlight class event support.
587 589
588For IBM and Lenovo models *without* ACPI backlight control (the ones on 590The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events
589which thinkpad-acpi will autoload its backlight interface by default, 591automatically for the cases were userspace has to do something to
590and on which ACPI video does not export a backlight interface): 592implement brightness changes. When you override these events, you will
591 593either fail to handle properly the ThinkPads that require explicit
5921. Don't enable or map the brightness hotkeys in thinkpad-acpi, as 594action to change backlight brightness, or the ThinkPads that require
593 these older firmware versions unfortunately won't respect the hotkey 595that no action be taken to work properly.
594 mask for brightness keys anyway, and always reacts to them. This
595 usually work fine, unless X.org drivers are doing something to block
596 the BIOS. In that case, use (3) below. This is the default mode of
597 operation.
598
5992. Enable the hotkeys, but map them to something else that is NOT
600 KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause
601 userspace to try to change the backlight level, and use that as an
602 on-screen-display hint.
603
6043. IF AND ONLY IF X.org drivers find a way to block the firmware from
605 automatically changing the brightness, enable the hotkeys and map
606 them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to
607 something that calls xbacklight. thinkpad-acpi will not be able to
608 change brightness in that case either, so you should disable its
609 backlight interface.
610
611For Lenovo models *with* ACPI backlight control:
612
6131. Load up ACPI video and use that. ACPI video will report ACPI
614 events for brightness change keys. Do not mess with thinkpad-acpi
615 defaults in this case. thinkpad-acpi should not have anything to do
616 with backlight events in a scenario where ACPI video is loaded:
617 brightness hotkeys must be disabled, and the backlight interface is
618 to be kept disabled as well. This is the default mode of operation.
619
6202. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi,
621 and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
622 these keys on userspace somehow (e.g. by calling xbacklight).
623 The driver will do this automatically if it detects that ACPI video
624 has been disabled.
625 596
626 597
627Bluetooth 598Bluetooth
@@ -1121,25 +1092,61 @@ WARNING:
1121 its level up and down at every change. 1092 its level up and down at every change.
1122 1093
1123 1094
1124Volume control -- /proc/acpi/ibm/volume 1095Volume control
1125--------------------------------------- 1096--------------
1097
1098procfs: /proc/acpi/ibm/volume
1099ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC"
1100
1101NOTE: by default, the volume control interface operates in read-only
1102mode, as it is supposed to be used for on-screen-display purposes.
1103The read/write mode can be enabled through the use of the
1104"volume_control=1" module parameter.
1126 1105
1127This feature allows volume control on ThinkPad models which don't have 1106NOTE: distros are urged to not enable volume_control by default, this
1128a hardware volume knob. The available commands are: 1107should be done by the local admin only. The ThinkPad UI is for the
1108console audio control to be done through the volume keys only, and for
1109the desktop environment to just provide on-screen-display feedback.
1110Software volume control should be done only in the main AC97/HDA
1111mixer.
1112
1113This feature allows volume control on ThinkPad models with a digital
1114volume knob (when available, not all models have it), as well as
1115mute/unmute control. The available commands are:
1129 1116
1130 echo up >/proc/acpi/ibm/volume 1117 echo up >/proc/acpi/ibm/volume
1131 echo down >/proc/acpi/ibm/volume 1118 echo down >/proc/acpi/ibm/volume
1132 echo mute >/proc/acpi/ibm/volume 1119 echo mute >/proc/acpi/ibm/volume
1120 echo unmute >/proc/acpi/ibm/volume
1133 echo 'level <level>' >/proc/acpi/ibm/volume 1121 echo 'level <level>' >/proc/acpi/ibm/volume
1134 1122
1135The <level> number range is 0 to 15 although not all of them may be 1123The <level> number range is 0 to 14 although not all of them may be
1136distinct. The unmute the volume after the mute command, use either the 1124distinct. The unmute the volume after the mute command, use either the
1137up or down command (the level command will not unmute the volume). 1125up or down command (the level command will not unmute the volume), or
1126the unmute command.
1127
1138The current volume level and mute state is shown in the file. 1128The current volume level and mute state is shown in the file.
1139 1129
1140The ALSA mixer interface to this feature is still missing, but patches 1130You can use the volume_capabilities parameter to tell the driver
1141to add it exist. That problem should be addressed in the not so 1131whether your thinkpad has volume control or mute-only control:
1142distant future. 1132volume_capabilities=1 for mixers with mute and volume control,
1133volume_capabilities=2 for mixers with only mute control.
1134
1135If the driver misdetects the capabilities for your ThinkPad model,
1136please report this to ibm-acpi-devel@lists.sourceforge.net, so that we
1137can update the driver.
1138
1139There are two strategies for volume control. To select which one
1140should be used, use the volume_mode module parameter: volume_mode=1
1141selects EC mode, and volume_mode=3 selects EC mode with NVRAM backing
1142(so that volume/mute changes are remembered across shutdown/reboot).
1143
1144The driver will operate in volume_mode=3 by default. If that does not
1145work well on your ThinkPad model, please report this to
1146ibm-acpi-devel@lists.sourceforge.net.
1147
1148The driver supports the standard ALSA module parameters. If the ALSA
1149mixer is disabled, the driver will disable all volume functionality.
1143 1150
1144 1151
1145Fan control and monitoring: fan speed, fan enable/disable 1152Fan control and monitoring: fan speed, fan enable/disable
@@ -1405,6 +1412,7 @@ to enable more than one output class, just add their values.
1405 0x0008 HKEY event interface, hotkeys 1412 0x0008 HKEY event interface, hotkeys
1406 0x0010 Fan control 1413 0x0010 Fan control
1407 0x0020 Backlight brightness 1414 0x0020 Backlight brightness
1415 0x0040 Audio mixer/volume control
1408 1416
1409There is also a kernel build option to enable more debugging 1417There is also a kernel build option to enable more debugging
1410information, which may be necessary to debug driver problems. 1418information, which may be necessary to debug driver problems.
@@ -1465,3 +1473,9 @@ Sysfs interface changelog:
1465 and it is always able to disable hot keys. Very old 1473 and it is always able to disable hot keys. Very old
1466 thinkpads are properly supported. hotkey_bios_mask 1474 thinkpads are properly supported. hotkey_bios_mask
1467 is deprecated and marked for removal. 1475 is deprecated and marked for removal.
1476
14770x020600: Marker for backlight change event support.
1478
14790x020700: Support for mute-only mixers.
1480 Volume control in read-only mode by default.
1481 Marker for ALSA mixer support.
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index cf61d6a8ef6f..448c8aeb166b 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -21,8 +21,8 @@
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.23" 24#define TPACPI_VERSION "0.24"
25#define TPACPI_SYSFS_VERSION 0x020500 25#define TPACPI_SYSFS_VERSION 0x020700
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -61,6 +61,7 @@
61 61
62#include <linux/nvram.h> 62#include <linux/nvram.h>
63#include <linux/proc_fs.h> 63#include <linux/proc_fs.h>
64#include <linux/seq_file.h>
64#include <linux/sysfs.h> 65#include <linux/sysfs.h>
65#include <linux/backlight.h> 66#include <linux/backlight.h>
66#include <linux/fb.h> 67#include <linux/fb.h>
@@ -76,6 +77,10 @@
76#include <linux/jiffies.h> 77#include <linux/jiffies.h>
77#include <linux/workqueue.h> 78#include <linux/workqueue.h>
78 79
80#include <sound/core.h>
81#include <sound/control.h>
82#include <sound/initval.h>
83
79#include <acpi/acpi_drivers.h> 84#include <acpi/acpi_drivers.h>
80 85
81#include <linux/pci_ids.h> 86#include <linux/pci_ids.h>
@@ -231,6 +236,7 @@ enum tpacpi_hkey_event_t {
231#define TPACPI_DBG_HKEY 0x0008 236#define TPACPI_DBG_HKEY 0x0008
232#define TPACPI_DBG_FAN 0x0010 237#define TPACPI_DBG_FAN 0x0010
233#define TPACPI_DBG_BRGHT 0x0020 238#define TPACPI_DBG_BRGHT 0x0020
239#define TPACPI_DBG_MIXER 0x0040
234 240
235#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") 241#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
236#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 242#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -256,7 +262,7 @@ struct tp_acpi_drv_struct {
256struct ibm_struct { 262struct ibm_struct {
257 char *name; 263 char *name;
258 264
259 int (*read) (char *); 265 int (*read) (struct seq_file *);
260 int (*write) (char *); 266 int (*write) (char *);
261 void (*exit) (void); 267 void (*exit) (void);
262 void (*resume) (void); 268 void (*resume) (void);
@@ -298,6 +304,7 @@ static struct {
298 u32 fan_ctrl_status_undef:1; 304 u32 fan_ctrl_status_undef:1;
299 u32 second_fan:1; 305 u32 second_fan:1;
300 u32 beep_needs_two_args:1; 306 u32 beep_needs_two_args:1;
307 u32 mixer_no_level_control:1;
301 u32 input_device_registered:1; 308 u32 input_device_registered:1;
302 u32 platform_drv_registered:1; 309 u32 platform_drv_registered:1;
303 u32 platform_drv_attrs_registered:1; 310 u32 platform_drv_attrs_registered:1;
@@ -309,6 +316,7 @@ static struct {
309 316
310static struct { 317static struct {
311 u16 hotkey_mask_ff:1; 318 u16 hotkey_mask_ff:1;
319 u16 volume_ctrl_forbidden:1;
312} tp_warned; 320} tp_warned;
313 321
314struct thinkpad_id_data { 322struct thinkpad_id_data {
@@ -425,6 +433,12 @@ static void tpacpi_log_usertask(const char * const what)
425 .ec = TPACPI_MATCH_ANY, \ 433 .ec = TPACPI_MATCH_ANY, \
426 .quirks = (__quirk) } 434 .quirks = (__quirk) }
427 435
436#define TPACPI_QEC_LNV(__id1, __id2, __quirk) \
437 { .vendor = PCI_VENDOR_ID_LENOVO, \
438 .bios = TPACPI_MATCH_ANY, \
439 .ec = TPID(__id1, __id2), \
440 .quirks = (__quirk) }
441
428struct tpacpi_quirk { 442struct tpacpi_quirk {
429 unsigned int vendor; 443 unsigned int vendor;
430 u16 bios; 444 u16 bios;
@@ -776,36 +790,25 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
776 **************************************************************************** 790 ****************************************************************************
777 ****************************************************************************/ 791 ****************************************************************************/
778 792
779static int dispatch_procfs_read(char *page, char **start, off_t off, 793static int dispatch_proc_show(struct seq_file *m, void *v)
780 int count, int *eof, void *data)
781{ 794{
782 struct ibm_struct *ibm = data; 795 struct ibm_struct *ibm = m->private;
783 int len;
784 796
785 if (!ibm || !ibm->read) 797 if (!ibm || !ibm->read)
786 return -EINVAL; 798 return -EINVAL;
799 return ibm->read(m);
800}
787 801
788 len = ibm->read(page); 802static int dispatch_proc_open(struct inode *inode, struct file *file)
789 if (len < 0) 803{
790 return len; 804 return single_open(file, dispatch_proc_show, PDE(inode)->data);
791
792 if (len <= off + count)
793 *eof = 1;
794 *start = page + off;
795 len -= off;
796 if (len > count)
797 len = count;
798 if (len < 0)
799 len = 0;
800
801 return len;
802} 805}
803 806
804static int dispatch_procfs_write(struct file *file, 807static ssize_t dispatch_proc_write(struct file *file,
805 const char __user *userbuf, 808 const char __user *userbuf,
806 unsigned long count, void *data) 809 size_t count, loff_t *pos)
807{ 810{
808 struct ibm_struct *ibm = data; 811 struct ibm_struct *ibm = PDE(file->f_path.dentry->d_inode)->data;
809 char *kernbuf; 812 char *kernbuf;
810 int ret; 813 int ret;
811 814
@@ -834,6 +837,15 @@ static int dispatch_procfs_write(struct file *file,
834 return ret; 837 return ret;
835} 838}
836 839
840static const struct file_operations dispatch_proc_fops = {
841 .owner = THIS_MODULE,
842 .open = dispatch_proc_open,
843 .read = seq_read,
844 .llseek = seq_lseek,
845 .release = single_release,
846 .write = dispatch_proc_write,
847};
848
837static char *next_cmd(char **cmds) 849static char *next_cmd(char **cmds)
838{ 850{
839 char *start = *cmds; 851 char *start = *cmds;
@@ -1261,6 +1273,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1261 struct tpacpi_rfk *atp_rfk; 1273 struct tpacpi_rfk *atp_rfk;
1262 int res; 1274 int res;
1263 bool sw_state = false; 1275 bool sw_state = false;
1276 bool hw_state;
1264 int sw_status; 1277 int sw_status;
1265 1278
1266 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); 1279 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
@@ -1295,7 +1308,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1295 rfkill_init_sw_state(atp_rfk->rfkill, sw_state); 1308 rfkill_init_sw_state(atp_rfk->rfkill, sw_state);
1296 } 1309 }
1297 } 1310 }
1298 rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); 1311 hw_state = tpacpi_rfk_check_hwblock_state();
1312 rfkill_set_hw_state(atp_rfk->rfkill, hw_state);
1299 1313
1300 res = rfkill_register(atp_rfk->rfkill); 1314 res = rfkill_register(atp_rfk->rfkill);
1301 if (res < 0) { 1315 if (res < 0) {
@@ -1308,6 +1322,9 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1308 } 1322 }
1309 1323
1310 tpacpi_rfkill_switches[id] = atp_rfk; 1324 tpacpi_rfkill_switches[id] = atp_rfk;
1325
1326 printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n",
1327 name, (sw_state || hw_state) ? "" : "un");
1311 return 0; 1328 return 0;
1312} 1329}
1313 1330
@@ -1380,12 +1397,10 @@ static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1380} 1397}
1381 1398
1382/* procfs -------------------------------------------------------------- */ 1399/* procfs -------------------------------------------------------------- */
1383static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p) 1400static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)
1384{ 1401{
1385 int len = 0;
1386
1387 if (id >= TPACPI_RFK_SW_MAX) 1402 if (id >= TPACPI_RFK_SW_MAX)
1388 len += sprintf(p + len, "status:\t\tnot supported\n"); 1403 seq_printf(m, "status:\t\tnot supported\n");
1389 else { 1404 else {
1390 int status; 1405 int status;
1391 1406
@@ -1399,13 +1414,13 @@ static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
1399 return status; 1414 return status;
1400 } 1415 }
1401 1416
1402 len += sprintf(p + len, "status:\t\t%s\n", 1417 seq_printf(m, "status:\t\t%s\n",
1403 (status == TPACPI_RFK_RADIO_ON) ? 1418 (status == TPACPI_RFK_RADIO_ON) ?
1404 "enabled" : "disabled"); 1419 "enabled" : "disabled");
1405 len += sprintf(p + len, "commands:\tenable, disable\n"); 1420 seq_printf(m, "commands:\tenable, disable\n");
1406 } 1421 }
1407 1422
1408 return len; 1423 return 0;
1409} 1424}
1410 1425
1411static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf) 1426static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
@@ -1776,7 +1791,7 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1776 1791
1777 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */ 1792 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */
1778 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */ 1793 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */
1779 TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */ 1794 TPV_QL1('7', 'E', 'D', '0', '1', '5'), /* R60e, R60i */
1780 1795
1781 /* BIOS FW BIOS VERS EC FW EC VERS */ 1796 /* BIOS FW BIOS VERS EC FW EC VERS */
1782 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */ 1797 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */
@@ -1792,8 +1807,8 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1792 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */ 1807 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */
1793 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */ 1808 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */
1794 1809
1795 TPV_QL0('7', 'B', 'D', '7'), /* X60/s */ 1810 TPV_QL1('7', 'B', 'D', '7', '4', '0'), /* X60/s */
1796 TPV_QL0('7', 'J', '3', '0'), /* X60t */ 1811 TPV_QL1('7', 'J', '3', '0', '1', '3'), /* X60t */
1797 1812
1798 /* (0) - older versions lack DMI EC fw string and functionality */ 1813 /* (0) - older versions lack DMI EC fw string and functionality */
1799 /* (1) - older versions known to lack functionality */ 1814 /* (1) - older versions known to lack functionality */
@@ -1883,14 +1898,11 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
1883 return 0; 1898 return 0;
1884} 1899}
1885 1900
1886static int thinkpad_acpi_driver_read(char *p) 1901static int thinkpad_acpi_driver_read(struct seq_file *m)
1887{ 1902{
1888 int len = 0; 1903 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);
1889 1904 seq_printf(m, "version:\t%s\n", TPACPI_VERSION);
1890 len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC); 1905 return 0;
1891 len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION);
1892
1893 return len;
1894} 1906}
1895 1907
1896static struct ibm_struct thinkpad_acpi_driver_data = { 1908static struct ibm_struct thinkpad_acpi_driver_data = {
@@ -2186,7 +2198,8 @@ static int hotkey_mask_set(u32 mask)
2186 fwmask, hotkey_acpi_mask); 2198 fwmask, hotkey_acpi_mask);
2187 } 2199 }
2188 2200
2189 hotkey_mask_warn_incomplete_mask(); 2201 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)
2202 hotkey_mask_warn_incomplete_mask();
2190 2203
2191 return rc; 2204 return rc;
2192} 2205}
@@ -3182,6 +3195,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3182 int res, i; 3195 int res, i;
3183 int status; 3196 int status;
3184 int hkeyv; 3197 int hkeyv;
3198 bool radiosw_state = false;
3199 bool tabletsw_state = false;
3185 3200
3186 unsigned long quirks; 3201 unsigned long quirks;
3187 3202
@@ -3287,6 +3302,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3287#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3302#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3288 if (dbg_wlswemul) { 3303 if (dbg_wlswemul) {
3289 tp_features.hotkey_wlsw = 1; 3304 tp_features.hotkey_wlsw = 1;
3305 radiosw_state = !!tpacpi_wlsw_emulstate;
3290 printk(TPACPI_INFO 3306 printk(TPACPI_INFO
3291 "radio switch emulation enabled\n"); 3307 "radio switch emulation enabled\n");
3292 } else 3308 } else
@@ -3294,6 +3310,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3294 /* Not all thinkpads have a hardware radio switch */ 3310 /* Not all thinkpads have a hardware radio switch */
3295 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 3311 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
3296 tp_features.hotkey_wlsw = 1; 3312 tp_features.hotkey_wlsw = 1;
3313 radiosw_state = !!status;
3297 printk(TPACPI_INFO 3314 printk(TPACPI_INFO
3298 "radio switch found; radios are %s\n", 3315 "radio switch found; radios are %s\n",
3299 enabled(status, 0)); 3316 enabled(status, 0));
@@ -3305,11 +3322,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3305 /* For X41t, X60t, X61t Tablets... */ 3322 /* For X41t, X60t, X61t Tablets... */
3306 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { 3323 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
3307 tp_features.hotkey_tablet = 1; 3324 tp_features.hotkey_tablet = 1;
3325 tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
3308 printk(TPACPI_INFO 3326 printk(TPACPI_INFO
3309 "possible tablet mode switch found; " 3327 "possible tablet mode switch found; "
3310 "ThinkPad in %s mode\n", 3328 "ThinkPad in %s mode\n",
3311 (status & TP_HOTKEY_TABLET_MASK)? 3329 (tabletsw_state) ? "tablet" : "laptop");
3312 "tablet" : "laptop");
3313 res = add_to_attr_set(hotkey_dev_attributes, 3330 res = add_to_attr_set(hotkey_dev_attributes,
3314 &dev_attr_hotkey_tablet_mode.attr); 3331 &dev_attr_hotkey_tablet_mode.attr);
3315 } 3332 }
@@ -3344,16 +3361,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3344 TPACPI_HOTKEY_MAP_SIZE); 3361 TPACPI_HOTKEY_MAP_SIZE);
3345 } 3362 }
3346 3363
3347 set_bit(EV_KEY, tpacpi_inputdev->evbit); 3364 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
3348 set_bit(EV_MSC, tpacpi_inputdev->evbit);
3349 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
3350 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 3365 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
3351 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; 3366 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
3352 tpacpi_inputdev->keycode = hotkey_keycode_map; 3367 tpacpi_inputdev->keycode = hotkey_keycode_map;
3353 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { 3368 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
3354 if (hotkey_keycode_map[i] != KEY_RESERVED) { 3369 if (hotkey_keycode_map[i] != KEY_RESERVED) {
3355 set_bit(hotkey_keycode_map[i], 3370 input_set_capability(tpacpi_inputdev, EV_KEY,
3356 tpacpi_inputdev->keybit); 3371 hotkey_keycode_map[i]);
3357 } else { 3372 } else {
3358 if (i < sizeof(hotkey_reserved_mask)*8) 3373 if (i < sizeof(hotkey_reserved_mask)*8)
3359 hotkey_reserved_mask |= 1 << i; 3374 hotkey_reserved_mask |= 1 << i;
@@ -3361,12 +3376,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3361 } 3376 }
3362 3377
3363 if (tp_features.hotkey_wlsw) { 3378 if (tp_features.hotkey_wlsw) {
3364 set_bit(EV_SW, tpacpi_inputdev->evbit); 3379 input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);
3365 set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); 3380 input_report_switch(tpacpi_inputdev,
3381 SW_RFKILL_ALL, radiosw_state);
3366 } 3382 }
3367 if (tp_features.hotkey_tablet) { 3383 if (tp_features.hotkey_tablet) {
3368 set_bit(EV_SW, tpacpi_inputdev->evbit); 3384 input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);
3369 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); 3385 input_report_switch(tpacpi_inputdev,
3386 SW_TABLET_MODE, tabletsw_state);
3370 } 3387 }
3371 3388
3372 /* Do not issue duplicate brightness change events to 3389 /* Do not issue duplicate brightness change events to
@@ -3433,8 +3450,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3433 tpacpi_inputdev->close = &hotkey_inputdev_close; 3450 tpacpi_inputdev->close = &hotkey_inputdev_close;
3434 3451
3435 hotkey_poll_setup_safe(true); 3452 hotkey_poll_setup_safe(true);
3436 tpacpi_send_radiosw_update();
3437 tpacpi_input_send_tabletsw();
3438 3453
3439 return 0; 3454 return 0;
3440 3455
@@ -3542,49 +3557,57 @@ static bool hotkey_notify_usrevent(const u32 hkey,
3542 } 3557 }
3543} 3558}
3544 3559
3560static void thermal_dump_all_sensors(void);
3561
3545static bool hotkey_notify_thermal(const u32 hkey, 3562static bool hotkey_notify_thermal(const u32 hkey,
3546 bool *send_acpi_ev, 3563 bool *send_acpi_ev,
3547 bool *ignore_acpi_ev) 3564 bool *ignore_acpi_ev)
3548{ 3565{
3566 bool known = true;
3567
3549 /* 0x6000-0x6FFF: thermal alarms */ 3568 /* 0x6000-0x6FFF: thermal alarms */
3550 *send_acpi_ev = true; 3569 *send_acpi_ev = true;
3551 *ignore_acpi_ev = false; 3570 *ignore_acpi_ev = false;
3552 3571
3553 switch (hkey) { 3572 switch (hkey) {
3573 case TP_HKEY_EV_THM_TABLE_CHANGED:
3574 printk(TPACPI_INFO
3575 "EC reports that Thermal Table has changed\n");
3576 /* recommended action: do nothing, we don't have
3577 * Lenovo ATM information */
3578 return true;
3554 case TP_HKEY_EV_ALARM_BAT_HOT: 3579 case TP_HKEY_EV_ALARM_BAT_HOT:
3555 printk(TPACPI_CRIT 3580 printk(TPACPI_CRIT
3556 "THERMAL ALARM: battery is too hot!\n"); 3581 "THERMAL ALARM: battery is too hot!\n");
3557 /* recommended action: warn user through gui */ 3582 /* recommended action: warn user through gui */
3558 return true; 3583 break;
3559 case TP_HKEY_EV_ALARM_BAT_XHOT: 3584 case TP_HKEY_EV_ALARM_BAT_XHOT:
3560 printk(TPACPI_ALERT 3585 printk(TPACPI_ALERT
3561 "THERMAL EMERGENCY: battery is extremely hot!\n"); 3586 "THERMAL EMERGENCY: battery is extremely hot!\n");
3562 /* recommended action: immediate sleep/hibernate */ 3587 /* recommended action: immediate sleep/hibernate */
3563 return true; 3588 break;
3564 case TP_HKEY_EV_ALARM_SENSOR_HOT: 3589 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3565 printk(TPACPI_CRIT 3590 printk(TPACPI_CRIT
3566 "THERMAL ALARM: " 3591 "THERMAL ALARM: "
3567 "a sensor reports something is too hot!\n"); 3592 "a sensor reports something is too hot!\n");
3568 /* recommended action: warn user through gui, that */ 3593 /* recommended action: warn user through gui, that */
3569 /* some internal component is too hot */ 3594 /* some internal component is too hot */
3570 return true; 3595 break;
3571 case TP_HKEY_EV_ALARM_SENSOR_XHOT: 3596 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3572 printk(TPACPI_ALERT 3597 printk(TPACPI_ALERT
3573 "THERMAL EMERGENCY: " 3598 "THERMAL EMERGENCY: "
3574 "a sensor reports something is extremely hot!\n"); 3599 "a sensor reports something is extremely hot!\n");
3575 /* recommended action: immediate sleep/hibernate */ 3600 /* recommended action: immediate sleep/hibernate */
3576 return true; 3601 break;
3577 case TP_HKEY_EV_THM_TABLE_CHANGED:
3578 printk(TPACPI_INFO
3579 "EC reports that Thermal Table has changed\n");
3580 /* recommended action: do nothing, we don't have
3581 * Lenovo ATM information */
3582 return true;
3583 default: 3602 default:
3584 printk(TPACPI_ALERT 3603 printk(TPACPI_ALERT
3585 "THERMAL ALERT: unknown thermal alarm received\n"); 3604 "THERMAL ALERT: unknown thermal alarm received\n");
3586 return false; 3605 known = false;
3587 } 3606 }
3607
3608 thermal_dump_all_sensors();
3609
3610 return known;
3588} 3611}
3589 3612
3590static void hotkey_notify(struct ibm_struct *ibm, u32 event) 3613static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -3727,14 +3750,13 @@ static void hotkey_resume(void)
3727} 3750}
3728 3751
3729/* procfs -------------------------------------------------------------- */ 3752/* procfs -------------------------------------------------------------- */
3730static int hotkey_read(char *p) 3753static int hotkey_read(struct seq_file *m)
3731{ 3754{
3732 int res, status; 3755 int res, status;
3733 int len = 0;
3734 3756
3735 if (!tp_features.hotkey) { 3757 if (!tp_features.hotkey) {
3736 len += sprintf(p + len, "status:\t\tnot supported\n"); 3758 seq_printf(m, "status:\t\tnot supported\n");
3737 return len; 3759 return 0;
3738 } 3760 }
3739 3761
3740 if (mutex_lock_killable(&hotkey_mutex)) 3762 if (mutex_lock_killable(&hotkey_mutex))
@@ -3746,17 +3768,16 @@ static int hotkey_read(char *p)
3746 if (res) 3768 if (res)
3747 return res; 3769 return res;
3748 3770
3749 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 3771 seq_printf(m, "status:\t\t%s\n", enabled(status, 0));
3750 if (hotkey_all_mask) { 3772 if (hotkey_all_mask) {
3751 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask); 3773 seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);
3752 len += sprintf(p + len, 3774 seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");
3753 "commands:\tenable, disable, reset, <mask>\n");
3754 } else { 3775 } else {
3755 len += sprintf(p + len, "mask:\t\tnot supported\n"); 3776 seq_printf(m, "mask:\t\tnot supported\n");
3756 len += sprintf(p + len, "commands:\tenable, disable, reset\n"); 3777 seq_printf(m, "commands:\tenable, disable, reset\n");
3757 } 3778 }
3758 3779
3759 return len; 3780 return 0;
3760} 3781}
3761 3782
3762static void hotkey_enabledisable_warn(bool enable) 3783static void hotkey_enabledisable_warn(bool enable)
@@ -3863,15 +3884,6 @@ enum {
3863 3884
3864#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3885#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3865 3886
3866static void bluetooth_suspend(pm_message_t state)
3867{
3868 /* Try to make sure radio will resume powered off */
3869 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
3870 TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
3871 vdbg_printk(TPACPI_DBG_RFKILL,
3872 "bluetooth power down on resume request failed\n");
3873}
3874
3875static int bluetooth_get_status(void) 3887static int bluetooth_get_status(void)
3876{ 3888{
3877 int status; 3889 int status;
@@ -3905,10 +3917,9 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3905#endif 3917#endif
3906 3918
3907 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3919 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3920 status = TP_ACPI_BLUETOOTH_RESUMECTRL;
3908 if (state == TPACPI_RFK_RADIO_ON) 3921 if (state == TPACPI_RFK_RADIO_ON)
3909 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3922 status |= TP_ACPI_BLUETOOTH_RADIOSSW;
3910 else
3911 status = 0;
3912 3923
3913 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3924 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3914 return -EIO; 3925 return -EIO;
@@ -4032,9 +4043,9 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
4032} 4043}
4033 4044
4034/* procfs -------------------------------------------------------------- */ 4045/* procfs -------------------------------------------------------------- */
4035static int bluetooth_read(char *p) 4046static int bluetooth_read(struct seq_file *m)
4036{ 4047{
4037 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p); 4048 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);
4038} 4049}
4039 4050
4040static int bluetooth_write(char *buf) 4051static int bluetooth_write(char *buf)
@@ -4047,7 +4058,6 @@ static struct ibm_struct bluetooth_driver_data = {
4047 .read = bluetooth_read, 4058 .read = bluetooth_read,
4048 .write = bluetooth_write, 4059 .write = bluetooth_write,
4049 .exit = bluetooth_exit, 4060 .exit = bluetooth_exit,
4050 .suspend = bluetooth_suspend,
4051 .shutdown = bluetooth_shutdown, 4061 .shutdown = bluetooth_shutdown,
4052}; 4062};
4053 4063
@@ -4065,15 +4075,6 @@ enum {
4065 4075
4066#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 4076#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
4067 4077
4068static void wan_suspend(pm_message_t state)
4069{
4070 /* Try to make sure radio will resume powered off */
4071 if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
4072 TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
4073 vdbg_printk(TPACPI_DBG_RFKILL,
4074 "WWAN power down on resume request failed\n");
4075}
4076
4077static int wan_get_status(void) 4078static int wan_get_status(void)
4078{ 4079{
4079 int status; 4080 int status;
@@ -4106,11 +4107,10 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
4106 } 4107 }
4107#endif 4108#endif
4108 4109
4109 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 4110 /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
4111 status = TP_ACPI_WANCARD_RESUMECTRL;
4110 if (state == TPACPI_RFK_RADIO_ON) 4112 if (state == TPACPI_RFK_RADIO_ON)
4111 status = TP_ACPI_WANCARD_RADIOSSW; 4113 status |= TP_ACPI_WANCARD_RADIOSSW;
4112 else
4113 status = 0;
4114 4114
4115 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 4115 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
4116 return -EIO; 4116 return -EIO;
@@ -4233,9 +4233,9 @@ static int __init wan_init(struct ibm_init_struct *iibm)
4233} 4233}
4234 4234
4235/* procfs -------------------------------------------------------------- */ 4235/* procfs -------------------------------------------------------------- */
4236static int wan_read(char *p) 4236static int wan_read(struct seq_file *m)
4237{ 4237{
4238 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p); 4238 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);
4239} 4239}
4240 4240
4241static int wan_write(char *buf) 4241static int wan_write(char *buf)
@@ -4248,7 +4248,6 @@ static struct ibm_struct wan_driver_data = {
4248 .read = wan_read, 4248 .read = wan_read,
4249 .write = wan_write, 4249 .write = wan_write,
4250 .exit = wan_exit, 4250 .exit = wan_exit,
4251 .suspend = wan_suspend,
4252 .shutdown = wan_shutdown, 4251 .shutdown = wan_shutdown,
4253}; 4252};
4254 4253
@@ -4611,14 +4610,13 @@ static int video_expand_toggle(void)
4611 /* not reached */ 4610 /* not reached */
4612} 4611}
4613 4612
4614static int video_read(char *p) 4613static int video_read(struct seq_file *m)
4615{ 4614{
4616 int status, autosw; 4615 int status, autosw;
4617 int len = 0;
4618 4616
4619 if (video_supported == TPACPI_VIDEO_NONE) { 4617 if (video_supported == TPACPI_VIDEO_NONE) {
4620 len += sprintf(p + len, "status:\t\tnot supported\n"); 4618 seq_printf(m, "status:\t\tnot supported\n");
4621 return len; 4619 return 0;
4622 } 4620 }
4623 4621
4624 status = video_outputsw_get(); 4622 status = video_outputsw_get();
@@ -4629,20 +4627,20 @@ static int video_read(char *p)
4629 if (autosw < 0) 4627 if (autosw < 0)
4630 return autosw; 4628 return autosw;
4631 4629
4632 len += sprintf(p + len, "status:\t\tsupported\n"); 4630 seq_printf(m, "status:\t\tsupported\n");
4633 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 4631 seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0));
4634 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 4632 seq_printf(m, "crt:\t\t%s\n", enabled(status, 1));
4635 if (video_supported == TPACPI_VIDEO_NEW) 4633 if (video_supported == TPACPI_VIDEO_NEW)
4636 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 4634 seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3));
4637 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 4635 seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0));
4638 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 4636 seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");
4639 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 4637 seq_printf(m, "commands:\tcrt_enable, crt_disable\n");
4640 if (video_supported == TPACPI_VIDEO_NEW) 4638 if (video_supported == TPACPI_VIDEO_NEW)
4641 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 4639 seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");
4642 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 4640 seq_printf(m, "commands:\tauto_enable, auto_disable\n");
4643 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 4641 seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");
4644 4642
4645 return len; 4643 return 0;
4646} 4644}
4647 4645
4648static int video_write(char *buf) 4646static int video_write(char *buf)
@@ -4834,25 +4832,24 @@ static void light_exit(void)
4834 flush_workqueue(tpacpi_wq); 4832 flush_workqueue(tpacpi_wq);
4835} 4833}
4836 4834
4837static int light_read(char *p) 4835static int light_read(struct seq_file *m)
4838{ 4836{
4839 int len = 0;
4840 int status; 4837 int status;
4841 4838
4842 if (!tp_features.light) { 4839 if (!tp_features.light) {
4843 len += sprintf(p + len, "status:\t\tnot supported\n"); 4840 seq_printf(m, "status:\t\tnot supported\n");
4844 } else if (!tp_features.light_status) { 4841 } else if (!tp_features.light_status) {
4845 len += sprintf(p + len, "status:\t\tunknown\n"); 4842 seq_printf(m, "status:\t\tunknown\n");
4846 len += sprintf(p + len, "commands:\ton, off\n"); 4843 seq_printf(m, "commands:\ton, off\n");
4847 } else { 4844 } else {
4848 status = light_get_status(); 4845 status = light_get_status();
4849 if (status < 0) 4846 if (status < 0)
4850 return status; 4847 return status;
4851 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 4848 seq_printf(m, "status:\t\t%s\n", onoff(status, 0));
4852 len += sprintf(p + len, "commands:\ton, off\n"); 4849 seq_printf(m, "commands:\ton, off\n");
4853 } 4850 }
4854 4851
4855 return len; 4852 return 0;
4856} 4853}
4857 4854
4858static int light_write(char *buf) 4855static int light_write(char *buf)
@@ -4930,20 +4927,18 @@ static void cmos_exit(void)
4930 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 4927 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4931} 4928}
4932 4929
4933static int cmos_read(char *p) 4930static int cmos_read(struct seq_file *m)
4934{ 4931{
4935 int len = 0;
4936
4937 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 4932 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
4938 R30, R31, T20-22, X20-21 */ 4933 R30, R31, T20-22, X20-21 */
4939 if (!cmos_handle) 4934 if (!cmos_handle)
4940 len += sprintf(p + len, "status:\t\tnot supported\n"); 4935 seq_printf(m, "status:\t\tnot supported\n");
4941 else { 4936 else {
4942 len += sprintf(p + len, "status:\t\tsupported\n"); 4937 seq_printf(m, "status:\t\tsupported\n");
4943 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n"); 4938 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");
4944 } 4939 }
4945 4940
4946 return len; 4941 return 0;
4947} 4942}
4948 4943
4949static int cmos_write(char *buf) 4944static int cmos_write(char *buf)
@@ -5318,15 +5313,13 @@ static int __init led_init(struct ibm_init_struct *iibm)
5318 ((s) == TPACPI_LED_OFF ? "off" : \ 5313 ((s) == TPACPI_LED_OFF ? "off" : \
5319 ((s) == TPACPI_LED_ON ? "on" : "blinking")) 5314 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
5320 5315
5321static int led_read(char *p) 5316static int led_read(struct seq_file *m)
5322{ 5317{
5323 int len = 0;
5324
5325 if (!led_supported) { 5318 if (!led_supported) {
5326 len += sprintf(p + len, "status:\t\tnot supported\n"); 5319 seq_printf(m, "status:\t\tnot supported\n");
5327 return len; 5320 return 0;
5328 } 5321 }
5329 len += sprintf(p + len, "status:\t\tsupported\n"); 5322 seq_printf(m, "status:\t\tsupported\n");
5330 5323
5331 if (led_supported == TPACPI_LED_570) { 5324 if (led_supported == TPACPI_LED_570) {
5332 /* 570 */ 5325 /* 570 */
@@ -5335,15 +5328,15 @@ static int led_read(char *p)
5335 status = led_get_status(i); 5328 status = led_get_status(i);
5336 if (status < 0) 5329 if (status < 0)
5337 return -EIO; 5330 return -EIO;
5338 len += sprintf(p + len, "%d:\t\t%s\n", 5331 seq_printf(m, "%d:\t\t%s\n",
5339 i, str_led_status(status)); 5332 i, str_led_status(status));
5340 } 5333 }
5341 } 5334 }
5342 5335
5343 len += sprintf(p + len, "commands:\t" 5336 seq_printf(m, "commands:\t"
5344 "<led> on, <led> off, <led> blink (<led> is 0-15)\n"); 5337 "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
5345 5338
5346 return len; 5339 return 0;
5347} 5340}
5348 5341
5349static int led_write(char *buf) 5342static int led_write(char *buf)
@@ -5416,18 +5409,16 @@ static int __init beep_init(struct ibm_init_struct *iibm)
5416 return (beep_handle)? 0 : 1; 5409 return (beep_handle)? 0 : 1;
5417} 5410}
5418 5411
5419static int beep_read(char *p) 5412static int beep_read(struct seq_file *m)
5420{ 5413{
5421 int len = 0;
5422
5423 if (!beep_handle) 5414 if (!beep_handle)
5424 len += sprintf(p + len, "status:\t\tnot supported\n"); 5415 seq_printf(m, "status:\t\tnot supported\n");
5425 else { 5416 else {
5426 len += sprintf(p + len, "status:\t\tsupported\n"); 5417 seq_printf(m, "status:\t\tsupported\n");
5427 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n"); 5418 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");
5428 } 5419 }
5429 5420
5430 return len; 5421 return 0;
5431} 5422}
5432 5423
5433static int beep_write(char *buf) 5424static int beep_write(char *buf)
@@ -5480,8 +5471,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */
5480 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ 5471 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */
5481 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ 5472 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */
5482 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ 5473 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */
5474
5475 TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */
5483}; 5476};
5484 5477
5478
5485#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ 5479#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
5486struct ibm_thermal_sensors_struct { 5480struct ibm_thermal_sensors_struct {
5487 s32 temp[TPACPI_MAX_THERMAL_SENSORS]; 5481 s32 temp[TPACPI_MAX_THERMAL_SENSORS];
@@ -5571,6 +5565,28 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
5571 return n; 5565 return n;
5572} 5566}
5573 5567
5568static void thermal_dump_all_sensors(void)
5569{
5570 int n, i;
5571 struct ibm_thermal_sensors_struct t;
5572
5573 n = thermal_get_sensors(&t);
5574 if (n <= 0)
5575 return;
5576
5577 printk(TPACPI_NOTICE
5578 "temperatures (Celsius):");
5579
5580 for (i = 0; i < n; i++) {
5581 if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
5582 printk(KERN_CONT " %d", (int)(t.temp[i] / 1000));
5583 else
5584 printk(KERN_CONT " N/A");
5585 }
5586
5587 printk(KERN_CONT "\n");
5588}
5589
5574/* sysfs temp##_input -------------------------------------------------- */ 5590/* sysfs temp##_input -------------------------------------------------- */
5575 5591
5576static ssize_t thermal_temp_input_show(struct device *dev, 5592static ssize_t thermal_temp_input_show(struct device *dev,
@@ -5586,7 +5602,7 @@ static ssize_t thermal_temp_input_show(struct device *dev,
5586 res = thermal_get_sensor(idx, &value); 5602 res = thermal_get_sensor(idx, &value);
5587 if (res) 5603 if (res)
5588 return res; 5604 return res;
5589 if (value == TP_EC_THERMAL_TMP_NA * 1000) 5605 if (value == TPACPI_THERMAL_SENSOR_NA)
5590 return -ENXIO; 5606 return -ENXIO;
5591 5607
5592 return snprintf(buf, PAGE_SIZE, "%d\n", value); 5608 return snprintf(buf, PAGE_SIZE, "%d\n", value);
@@ -5763,9 +5779,8 @@ static void thermal_exit(void)
5763 } 5779 }
5764} 5780}
5765 5781
5766static int thermal_read(char *p) 5782static int thermal_read(struct seq_file *m)
5767{ 5783{
5768 int len = 0;
5769 int n, i; 5784 int n, i;
5770 struct ibm_thermal_sensors_struct t; 5785 struct ibm_thermal_sensors_struct t;
5771 5786
@@ -5773,16 +5788,16 @@ static int thermal_read(char *p)
5773 if (unlikely(n < 0)) 5788 if (unlikely(n < 0))
5774 return n; 5789 return n;
5775 5790
5776 len += sprintf(p + len, "temperatures:\t"); 5791 seq_printf(m, "temperatures:\t");
5777 5792
5778 if (n > 0) { 5793 if (n > 0) {
5779 for (i = 0; i < (n - 1); i++) 5794 for (i = 0; i < (n - 1); i++)
5780 len += sprintf(p + len, "%d ", t.temp[i] / 1000); 5795 seq_printf(m, "%d ", t.temp[i] / 1000);
5781 len += sprintf(p + len, "%d\n", t.temp[i] / 1000); 5796 seq_printf(m, "%d\n", t.temp[i] / 1000);
5782 } else 5797 } else
5783 len += sprintf(p + len, "not supported\n"); 5798 seq_printf(m, "not supported\n");
5784 5799
5785 return len; 5800 return 0;
5786} 5801}
5787 5802
5788static struct ibm_struct thermal_driver_data = { 5803static struct ibm_struct thermal_driver_data = {
@@ -5797,39 +5812,38 @@ static struct ibm_struct thermal_driver_data = {
5797 5812
5798static u8 ecdump_regs[256]; 5813static u8 ecdump_regs[256];
5799 5814
5800static int ecdump_read(char *p) 5815static int ecdump_read(struct seq_file *m)
5801{ 5816{
5802 int len = 0;
5803 int i, j; 5817 int i, j;
5804 u8 v; 5818 u8 v;
5805 5819
5806 len += sprintf(p + len, "EC " 5820 seq_printf(m, "EC "
5807 " +00 +01 +02 +03 +04 +05 +06 +07" 5821 " +00 +01 +02 +03 +04 +05 +06 +07"
5808 " +08 +09 +0a +0b +0c +0d +0e +0f\n"); 5822 " +08 +09 +0a +0b +0c +0d +0e +0f\n");
5809 for (i = 0; i < 256; i += 16) { 5823 for (i = 0; i < 256; i += 16) {
5810 len += sprintf(p + len, "EC 0x%02x:", i); 5824 seq_printf(m, "EC 0x%02x:", i);
5811 for (j = 0; j < 16; j++) { 5825 for (j = 0; j < 16; j++) {
5812 if (!acpi_ec_read(i + j, &v)) 5826 if (!acpi_ec_read(i + j, &v))
5813 break; 5827 break;
5814 if (v != ecdump_regs[i + j]) 5828 if (v != ecdump_regs[i + j])
5815 len += sprintf(p + len, " *%02x", v); 5829 seq_printf(m, " *%02x", v);
5816 else 5830 else
5817 len += sprintf(p + len, " %02x", v); 5831 seq_printf(m, " %02x", v);
5818 ecdump_regs[i + j] = v; 5832 ecdump_regs[i + j] = v;
5819 } 5833 }
5820 len += sprintf(p + len, "\n"); 5834 seq_putc(m, '\n');
5821 if (j != 16) 5835 if (j != 16)
5822 break; 5836 break;
5823 } 5837 }
5824 5838
5825 /* These are way too dangerous to advertise openly... */ 5839 /* These are way too dangerous to advertise openly... */
5826#if 0 5840#if 0
5827 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>" 5841 seq_printf(m, "commands:\t0x<offset> 0x<value>"
5828 " (<offset> is 00-ff, <value> is 00-ff)\n"); 5842 " (<offset> is 00-ff, <value> is 00-ff)\n");
5829 len += sprintf(p + len, "commands:\t0x<offset> <value> " 5843 seq_printf(m, "commands:\t0x<offset> <value> "
5830 " (<offset> is 00-ff, <value> is 0-255)\n"); 5844 " (<offset> is 00-ff, <value> is 0-255)\n");
5831#endif 5845#endif
5832 return len; 5846 return 0;
5833} 5847}
5834 5848
5835static int ecdump_write(char *buf) 5849static int ecdump_write(char *buf)
@@ -6092,6 +6106,12 @@ static int brightness_get(struct backlight_device *bd)
6092 return status & TP_EC_BACKLIGHT_LVLMSK; 6106 return status & TP_EC_BACKLIGHT_LVLMSK;
6093} 6107}
6094 6108
6109static void tpacpi_brightness_notify_change(void)
6110{
6111 backlight_force_update(ibm_backlight_device,
6112 BACKLIGHT_UPDATE_HOTKEY);
6113}
6114
6095static struct backlight_ops ibm_backlight_data = { 6115static struct backlight_ops ibm_backlight_data = {
6096 .get_brightness = brightness_get, 6116 .get_brightness = brightness_get,
6097 .update_status = brightness_update_status, 6117 .update_status = brightness_update_status,
@@ -6120,8 +6140,8 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6120 6140
6121 /* Models with Intel Extreme Graphics 2 */ 6141 /* Models with Intel Extreme Graphics 2 */
6122 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), 6142 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
6123 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 6143 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6124 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 6144 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6125 6145
6126 /* Models with Intel GMA900 */ 6146 /* Models with Intel GMA900 */
6127 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ 6147 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
@@ -6246,6 +6266,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6246 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 6266 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
6247 backlight_update_status(ibm_backlight_device); 6267 backlight_update_status(ibm_backlight_device);
6248 6268
6269 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6270 "brightness: registering brightness hotkeys "
6271 "as change notification\n");
6272 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6273 | TP_ACPI_HKEY_BRGHTUP_MASK
6274 | TP_ACPI_HKEY_BRGHTDWN_MASK);;
6249 return 0; 6275 return 0;
6250} 6276}
6251 6277
@@ -6270,23 +6296,22 @@ static void brightness_exit(void)
6270 tpacpi_brightness_checkpoint_nvram(); 6296 tpacpi_brightness_checkpoint_nvram();
6271} 6297}
6272 6298
6273static int brightness_read(char *p) 6299static int brightness_read(struct seq_file *m)
6274{ 6300{
6275 int len = 0;
6276 int level; 6301 int level;
6277 6302
6278 level = brightness_get(NULL); 6303 level = brightness_get(NULL);
6279 if (level < 0) { 6304 if (level < 0) {
6280 len += sprintf(p + len, "level:\t\tunreadable\n"); 6305 seq_printf(m, "level:\t\tunreadable\n");
6281 } else { 6306 } else {
6282 len += sprintf(p + len, "level:\t\t%d\n", level); 6307 seq_printf(m, "level:\t\t%d\n", level);
6283 len += sprintf(p + len, "commands:\tup, down\n"); 6308 seq_printf(m, "commands:\tup, down\n");
6284 len += sprintf(p + len, "commands:\tlevel <level>" 6309 seq_printf(m, "commands:\tlevel <level>"
6285 " (<level> is 0-%d)\n", 6310 " (<level> is 0-%d)\n",
6286 (tp_features.bright_16levels) ? 15 : 7); 6311 (tp_features.bright_16levels) ? 15 : 7);
6287 } 6312 }
6288 6313
6289 return len; 6314 return 0;
6290} 6315}
6291 6316
6292static int brightness_write(char *buf) 6317static int brightness_write(char *buf)
@@ -6322,6 +6347,9 @@ static int brightness_write(char *buf)
6322 * Doing it this way makes the syscall restartable in case of EINTR 6347 * Doing it this way makes the syscall restartable in case of EINTR
6323 */ 6348 */
6324 rc = brightness_set(level); 6349 rc = brightness_set(level);
6350 if (!rc && ibm_backlight_device)
6351 backlight_force_update(ibm_backlight_device,
6352 BACKLIGHT_UPDATE_SYSFS);
6325 return (rc == -EINTR)? -ERESTARTSYS : rc; 6353 return (rc == -EINTR)? -ERESTARTSYS : rc;
6326} 6354}
6327 6355
@@ -6338,99 +6366,654 @@ static struct ibm_struct brightness_driver_data = {
6338 * Volume subdriver 6366 * Volume subdriver
6339 */ 6367 */
6340 6368
6341static int volume_offset = 0x30; 6369/*
6370 * IBM ThinkPads have a simple volume controller with MUTE gating.
6371 * Very early Lenovo ThinkPads follow the IBM ThinkPad spec.
6372 *
6373 * Since the *61 series (and probably also the later *60 series), Lenovo
6374 * ThinkPads only implement the MUTE gate.
6375 *
6376 * EC register 0x30
6377 * Bit 6: MUTE (1 mutes sound)
6378 * Bit 3-0: Volume
6379 * Other bits should be zero as far as we know.
6380 *
6381 * This is also stored in CMOS NVRAM, byte 0x60, bit 6 (MUTE), and
6382 * bits 3-0 (volume). Other bits in NVRAM may have other functions,
6383 * such as bit 7 which is used to detect repeated presses of MUTE,
6384 * and we leave them unchanged.
6385 */
6386
6387#define TPACPI_ALSA_DRVNAME "ThinkPad EC"
6388#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
6389#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
6390
6391static int alsa_index = SNDRV_DEFAULT_IDX1;
6392static char *alsa_id = "ThinkPadEC";
6393static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
6394
6395struct tpacpi_alsa_data {
6396 struct snd_card *card;
6397 struct snd_ctl_elem_id *ctl_mute_id;
6398 struct snd_ctl_elem_id *ctl_vol_id;
6399};
6400
6401static struct snd_card *alsa_card;
6402
6403enum {
6404 TP_EC_AUDIO = 0x30,
6405
6406 /* TP_EC_AUDIO bits */
6407 TP_EC_AUDIO_MUTESW = 6,
6408
6409 /* TP_EC_AUDIO bitmasks */
6410 TP_EC_AUDIO_LVL_MSK = 0x0F,
6411 TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),
6412
6413 /* Maximum volume */
6414 TP_EC_VOLUME_MAX = 14,
6415};
6416
6417enum tpacpi_volume_access_mode {
6418 TPACPI_VOL_MODE_AUTO = 0, /* Not implemented yet */
6419 TPACPI_VOL_MODE_EC, /* Pure EC control */
6420 TPACPI_VOL_MODE_UCMS_STEP, /* UCMS step-based control: N/A */
6421 TPACPI_VOL_MODE_ECNVRAM, /* EC control w/ NVRAM store */
6422 TPACPI_VOL_MODE_MAX
6423};
6424
6425enum tpacpi_volume_capabilities {
6426 TPACPI_VOL_CAP_AUTO = 0, /* Use white/blacklist */
6427 TPACPI_VOL_CAP_VOLMUTE, /* Output vol and mute */
6428 TPACPI_VOL_CAP_MUTEONLY, /* Output mute only */
6429 TPACPI_VOL_CAP_MAX
6430};
6431
6432static enum tpacpi_volume_access_mode volume_mode =
6433 TPACPI_VOL_MODE_MAX;
6434
6435static enum tpacpi_volume_capabilities volume_capabilities;
6436static int volume_control_allowed;
6342 6437
6343static int volume_read(char *p) 6438/*
6439 * Used to syncronize writers to TP_EC_AUDIO and
6440 * TP_NVRAM_ADDR_MIXER, as we need to do read-modify-write
6441 */
6442static struct mutex volume_mutex;
6443
6444static void tpacpi_volume_checkpoint_nvram(void)
6344{ 6445{
6345 int len = 0; 6446 u8 lec = 0;
6346 u8 level; 6447 u8 b_nvram;
6448 u8 ec_mask;
6449
6450 if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
6451 return;
6452 if (!volume_control_allowed)
6453 return;
6454
6455 vdbg_printk(TPACPI_DBG_MIXER,
6456 "trying to checkpoint mixer state to NVRAM...\n");
6347 6457
6348 if (!acpi_ec_read(volume_offset, &level)) { 6458 if (tp_features.mixer_no_level_control)
6349 len += sprintf(p + len, "level:\t\tunreadable\n"); 6459 ec_mask = TP_EC_AUDIO_MUTESW_MSK;
6460 else
6461 ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;
6462
6463 if (mutex_lock_killable(&volume_mutex) < 0)
6464 return;
6465
6466 if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
6467 goto unlock;
6468 lec &= ec_mask;
6469 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
6470
6471 if (lec != (b_nvram & ec_mask)) {
6472 /* NVRAM needs update */
6473 b_nvram &= ~ec_mask;
6474 b_nvram |= lec;
6475 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
6476 dbg_printk(TPACPI_DBG_MIXER,
6477 "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
6478 (unsigned int) lec, (unsigned int) b_nvram);
6350 } else { 6479 } else {
6351 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); 6480 vdbg_printk(TPACPI_DBG_MIXER,
6352 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); 6481 "NVRAM mixer status already is 0x%02x (0x%02x)\n",
6353 len += sprintf(p + len, "commands:\tup, down, mute\n"); 6482 (unsigned int) lec, (unsigned int) b_nvram);
6354 len += sprintf(p + len, "commands:\tlevel <level>"
6355 " (<level> is 0-15)\n");
6356 } 6483 }
6357 6484
6358 return len; 6485unlock:
6486 mutex_unlock(&volume_mutex);
6359} 6487}
6360 6488
6361static int volume_write(char *buf) 6489static int volume_get_status_ec(u8 *status)
6362{ 6490{
6363 int cmos_cmd, inc, i; 6491 u8 s;
6364 u8 level, mute;
6365 int new_level, new_mute;
6366 char *cmd;
6367 6492
6368 while ((cmd = next_cmd(&buf))) { 6493 if (!acpi_ec_read(TP_EC_AUDIO, &s))
6369 if (!acpi_ec_read(volume_offset, &level)) 6494 return -EIO;
6370 return -EIO;
6371 new_mute = mute = level & 0x40;
6372 new_level = level = level & 0xf;
6373 6495
6374 if (strlencmp(cmd, "up") == 0) { 6496 *status = s;
6375 if (mute)
6376 new_mute = 0;
6377 else
6378 new_level = level == 15 ? 15 : level + 1;
6379 } else if (strlencmp(cmd, "down") == 0) {
6380 if (mute)
6381 new_mute = 0;
6382 else
6383 new_level = level == 0 ? 0 : level - 1;
6384 } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
6385 new_level >= 0 && new_level <= 15) {
6386 /* new_level set */
6387 } else if (strlencmp(cmd, "mute") == 0) {
6388 new_mute = 0x40;
6389 } else
6390 return -EINVAL;
6391 6497
6392 if (new_level != level) { 6498 dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);
6393 /* mute doesn't change */
6394 6499
6395 cmos_cmd = (new_level > level) ? 6500 return 0;
6396 TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN; 6501}
6397 inc = new_level > level ? 1 : -1;
6398 6502
6399 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) || 6503static int volume_get_status(u8 *status)
6400 !acpi_ec_write(volume_offset, level))) 6504{
6401 return -EIO; 6505 return volume_get_status_ec(status);
6506}
6402 6507
6403 for (i = level; i != new_level; i += inc) 6508static int volume_set_status_ec(const u8 status)
6404 if (issue_thinkpad_cmos_command(cmos_cmd) || 6509{
6405 !acpi_ec_write(volume_offset, i + inc)) 6510 if (!acpi_ec_write(TP_EC_AUDIO, status))
6406 return -EIO; 6511 return -EIO;
6407 6512
6408 if (mute && 6513 dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
6409 (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) || 6514
6410 !acpi_ec_write(volume_offset, new_level + mute))) { 6515 return 0;
6411 return -EIO; 6516}
6412 } 6517
6518static int volume_set_status(const u8 status)
6519{
6520 return volume_set_status_ec(status);
6521}
6522
6523static int volume_set_mute_ec(const bool mute)
6524{
6525 int rc;
6526 u8 s, n;
6527
6528 if (mutex_lock_killable(&volume_mutex) < 0)
6529 return -EINTR;
6530
6531 rc = volume_get_status_ec(&s);
6532 if (rc)
6533 goto unlock;
6534
6535 n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
6536 s & ~TP_EC_AUDIO_MUTESW_MSK;
6537
6538 if (n != s)
6539 rc = volume_set_status_ec(n);
6540
6541unlock:
6542 mutex_unlock(&volume_mutex);
6543 return rc;
6544}
6545
6546static int volume_set_mute(const bool mute)
6547{
6548 dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
6549 (mute) ? "" : "un");
6550 return volume_set_mute_ec(mute);
6551}
6552
6553static int volume_set_volume_ec(const u8 vol)
6554{
6555 int rc;
6556 u8 s, n;
6557
6558 if (vol > TP_EC_VOLUME_MAX)
6559 return -EINVAL;
6560
6561 if (mutex_lock_killable(&volume_mutex) < 0)
6562 return -EINTR;
6563
6564 rc = volume_get_status_ec(&s);
6565 if (rc)
6566 goto unlock;
6567
6568 n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
6569
6570 if (n != s)
6571 rc = volume_set_status_ec(n);
6572
6573unlock:
6574 mutex_unlock(&volume_mutex);
6575 return rc;
6576}
6577
6578static int volume_set_volume(const u8 vol)
6579{
6580 dbg_printk(TPACPI_DBG_MIXER,
6581 "trying to set volume level to %hu\n", vol);
6582 return volume_set_volume_ec(vol);
6583}
6584
6585static void volume_alsa_notify_change(void)
6586{
6587 struct tpacpi_alsa_data *d;
6588
6589 if (alsa_card && alsa_card->private_data) {
6590 d = alsa_card->private_data;
6591 if (d->ctl_mute_id)
6592 snd_ctl_notify(alsa_card,
6593 SNDRV_CTL_EVENT_MASK_VALUE,
6594 d->ctl_mute_id);
6595 if (d->ctl_vol_id)
6596 snd_ctl_notify(alsa_card,
6597 SNDRV_CTL_EVENT_MASK_VALUE,
6598 d->ctl_vol_id);
6599 }
6600}
6601
6602static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
6603 struct snd_ctl_elem_info *uinfo)
6604{
6605 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
6606 uinfo->count = 1;
6607 uinfo->value.integer.min = 0;
6608 uinfo->value.integer.max = TP_EC_VOLUME_MAX;
6609 return 0;
6610}
6611
6612static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
6613 struct snd_ctl_elem_value *ucontrol)
6614{
6615 u8 s;
6616 int rc;
6617
6618 rc = volume_get_status(&s);
6619 if (rc < 0)
6620 return rc;
6621
6622 ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;
6623 return 0;
6624}
6625
6626static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
6627 struct snd_ctl_elem_value *ucontrol)
6628{
6629 return volume_set_volume(ucontrol->value.integer.value[0]);
6630}
6631
6632#define volume_alsa_mute_info snd_ctl_boolean_mono_info
6633
6634static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
6635 struct snd_ctl_elem_value *ucontrol)
6636{
6637 u8 s;
6638 int rc;
6639
6640 rc = volume_get_status(&s);
6641 if (rc < 0)
6642 return rc;
6643
6644 ucontrol->value.integer.value[0] =
6645 (s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;
6646 return 0;
6647}
6648
6649static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6650 struct snd_ctl_elem_value *ucontrol)
6651{
6652 return volume_set_mute(!ucontrol->value.integer.value[0]);
6653}
6654
6655static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
6656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6657 .name = "Console Playback Volume",
6658 .index = 0,
6659 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6660 .info = volume_alsa_vol_info,
6661 .get = volume_alsa_vol_get,
6662};
6663
6664static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = {
6665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6666 .name = "Console Playback Switch",
6667 .index = 0,
6668 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6669 .info = volume_alsa_mute_info,
6670 .get = volume_alsa_mute_get,
6671};
6672
6673static void volume_suspend(pm_message_t state)
6674{
6675 tpacpi_volume_checkpoint_nvram();
6676}
6677
6678static void volume_resume(void)
6679{
6680 volume_alsa_notify_change();
6681}
6682
6683static void volume_shutdown(void)
6684{
6685 tpacpi_volume_checkpoint_nvram();
6686}
6687
6688static void volume_exit(void)
6689{
6690 if (alsa_card) {
6691 snd_card_free(alsa_card);
6692 alsa_card = NULL;
6693 }
6694
6695 tpacpi_volume_checkpoint_nvram();
6696}
6697
6698static int __init volume_create_alsa_mixer(void)
6699{
6700 struct snd_card *card;
6701 struct tpacpi_alsa_data *data;
6702 struct snd_kcontrol *ctl_vol;
6703 struct snd_kcontrol *ctl_mute;
6704 int rc;
6705
6706 rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
6707 sizeof(struct tpacpi_alsa_data), &card);
6708 if (rc < 0)
6709 return rc;
6710 if (!card)
6711 return -ENOMEM;
6712
6713 BUG_ON(!card->private_data);
6714 data = card->private_data;
6715 data->card = card;
6716
6717 strlcpy(card->driver, TPACPI_ALSA_DRVNAME,
6718 sizeof(card->driver));
6719 strlcpy(card->shortname, TPACPI_ALSA_SHRTNAME,
6720 sizeof(card->shortname));
6721 snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",
6722 (thinkpad_id.ec_version_str) ?
6723 thinkpad_id.ec_version_str : "(unknown)");
6724 snprintf(card->longname, sizeof(card->longname),
6725 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,
6726 (thinkpad_id.ec_version_str) ?
6727 thinkpad_id.ec_version_str : "unknown");
6728
6729 if (volume_control_allowed) {
6730 volume_alsa_control_vol.put = volume_alsa_vol_put;
6731 volume_alsa_control_vol.access =
6732 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6733
6734 volume_alsa_control_mute.put = volume_alsa_mute_put;
6735 volume_alsa_control_mute.access =
6736 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6737 }
6738
6739 if (!tp_features.mixer_no_level_control) {
6740 ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
6741 rc = snd_ctl_add(card, ctl_vol);
6742 if (rc < 0) {
6743 printk(TPACPI_ERR
6744 "Failed to create ALSA volume control\n");
6745 goto err_out;
6413 } 6746 }
6747 data->ctl_vol_id = &ctl_vol->id;
6748 }
6414 6749
6415 if (new_mute != mute) { 6750 ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
6416 /* level doesn't change */ 6751 rc = snd_ctl_add(card, ctl_mute);
6752 if (rc < 0) {
6753 printk(TPACPI_ERR "Failed to create ALSA mute control\n");
6754 goto err_out;
6755 }
6756 data->ctl_mute_id = &ctl_mute->id;
6417 6757
6418 cmos_cmd = (new_mute) ? 6758 snd_card_set_dev(card, &tpacpi_pdev->dev);
6419 TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP; 6759 rc = snd_card_register(card);
6420 6760
6421 if (issue_thinkpad_cmos_command(cmos_cmd) || 6761err_out:
6422 !acpi_ec_write(volume_offset, level + new_mute)) 6762 if (rc < 0) {
6423 return -EIO; 6763 snd_card_free(card);
6764 card = NULL;
6765 }
6766
6767 alsa_card = card;
6768 return rc;
6769}
6770
6771#define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */
6772#define TPACPI_VOL_Q_LEVEL 0x0002 /* Volume control available */
6773
6774static const struct tpacpi_quirk volume_quirk_table[] __initconst = {
6775 /* Whitelist volume level on all IBM by default */
6776 { .vendor = PCI_VENDOR_ID_IBM,
6777 .bios = TPACPI_MATCH_ANY,
6778 .ec = TPACPI_MATCH_ANY,
6779 .quirks = TPACPI_VOL_Q_LEVEL },
6780
6781 /* Lenovo models with volume control (needs confirmation) */
6782 TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL), /* R60/i */
6783 TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL), /* R60e/i */
6784 TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL), /* T60/p */
6785 TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL), /* X60/s */
6786 TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL), /* X60t */
6787 TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL), /* Z60 */
6788 TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL), /* Z61 */
6789
6790 /* Whitelist mute-only on all Lenovo by default */
6791 { .vendor = PCI_VENDOR_ID_LENOVO,
6792 .bios = TPACPI_MATCH_ANY,
6793 .ec = TPACPI_MATCH_ANY,
6794 .quirks = TPACPI_VOL_Q_MUTEONLY }
6795};
6796
6797static int __init volume_init(struct ibm_init_struct *iibm)
6798{
6799 unsigned long quirks;
6800 int rc;
6801
6802 vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");
6803
6804 mutex_init(&volume_mutex);
6805
6806 /*
6807 * Check for module parameter bogosity, note that we
6808 * init volume_mode to TPACPI_VOL_MODE_MAX in order to be
6809 * able to detect "unspecified"
6810 */
6811 if (volume_mode > TPACPI_VOL_MODE_MAX)
6812 return -EINVAL;
6813
6814 if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
6815 printk(TPACPI_ERR
6816 "UCMS step volume mode not implemented, "
6817 "please contact %s\n", TPACPI_MAIL);
6818 return 1;
6819 }
6820
6821 if (volume_capabilities >= TPACPI_VOL_CAP_MAX)
6822 return -EINVAL;
6823
6824 /*
6825 * The ALSA mixer is our primary interface.
6826 * When disabled, don't install the subdriver at all
6827 */
6828 if (!alsa_enable) {
6829 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6830 "ALSA mixer disabled by parameter, "
6831 "not loading volume subdriver...\n");
6832 return 1;
6833 }
6834
6835 quirks = tpacpi_check_quirks(volume_quirk_table,
6836 ARRAY_SIZE(volume_quirk_table));
6837
6838 switch (volume_capabilities) {
6839 case TPACPI_VOL_CAP_AUTO:
6840 if (quirks & TPACPI_VOL_Q_MUTEONLY)
6841 tp_features.mixer_no_level_control = 1;
6842 else if (quirks & TPACPI_VOL_Q_LEVEL)
6843 tp_features.mixer_no_level_control = 0;
6844 else
6845 return 1; /* no mixer */
6846 break;
6847 case TPACPI_VOL_CAP_VOLMUTE:
6848 tp_features.mixer_no_level_control = 0;
6849 break;
6850 case TPACPI_VOL_CAP_MUTEONLY:
6851 tp_features.mixer_no_level_control = 1;
6852 break;
6853 default:
6854 return 1;
6855 }
6856
6857 if (volume_capabilities != TPACPI_VOL_CAP_AUTO)
6858 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6859 "using user-supplied volume_capabilities=%d\n",
6860 volume_capabilities);
6861
6862 if (volume_mode == TPACPI_VOL_MODE_AUTO ||
6863 volume_mode == TPACPI_VOL_MODE_MAX) {
6864 volume_mode = TPACPI_VOL_MODE_ECNVRAM;
6865
6866 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6867 "driver auto-selected volume_mode=%d\n",
6868 volume_mode);
6869 } else {
6870 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6871 "using user-supplied volume_mode=%d\n",
6872 volume_mode);
6873 }
6874
6875 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6876 "mute is supported, volume control is %s\n",
6877 str_supported(!tp_features.mixer_no_level_control));
6878
6879 rc = volume_create_alsa_mixer();
6880 if (rc) {
6881 printk(TPACPI_ERR
6882 "Could not create the ALSA mixer interface\n");
6883 return rc;
6884 }
6885
6886 printk(TPACPI_INFO
6887 "Console audio control enabled, mode: %s\n",
6888 (volume_control_allowed) ?
6889 "override (read/write)" :
6890 "monitor (read only)");
6891
6892 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6893 "registering volume hotkeys as change notification\n");
6894 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6895 | TP_ACPI_HKEY_VOLUP_MASK
6896 | TP_ACPI_HKEY_VOLDWN_MASK
6897 | TP_ACPI_HKEY_MUTE_MASK);
6898
6899 return 0;
6900}
6901
6902static int volume_read(struct seq_file *m)
6903{
6904 u8 status;
6905
6906 if (volume_get_status(&status) < 0) {
6907 seq_printf(m, "level:\t\tunreadable\n");
6908 } else {
6909 if (tp_features.mixer_no_level_control)
6910 seq_printf(m, "level:\t\tunsupported\n");
6911 else
6912 seq_printf(m, "level:\t\t%d\n",
6913 status & TP_EC_AUDIO_LVL_MSK);
6914
6915 seq_printf(m, "mute:\t\t%s\n",
6916 onoff(status, TP_EC_AUDIO_MUTESW));
6917
6918 if (volume_control_allowed) {
6919 seq_printf(m, "commands:\tunmute, mute\n");
6920 if (!tp_features.mixer_no_level_control) {
6921 seq_printf(m,
6922 "commands:\tup, down\n");
6923 seq_printf(m,
6924 "commands:\tlevel <level>"
6925 " (<level> is 0-%d)\n",
6926 TP_EC_VOLUME_MAX);
6927 }
6424 } 6928 }
6425 } 6929 }
6426 6930
6427 return 0; 6931 return 0;
6428} 6932}
6429 6933
6934static int volume_write(char *buf)
6935{
6936 u8 s;
6937 u8 new_level, new_mute;
6938 int l;
6939 char *cmd;
6940 int rc;
6941
6942 /*
6943 * We do allow volume control at driver startup, so that the
6944 * user can set initial state through the volume=... parameter hack.
6945 */
6946 if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
6947 if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
6948 tp_warned.volume_ctrl_forbidden = 1;
6949 printk(TPACPI_NOTICE
6950 "Console audio control in monitor mode, "
6951 "changes are not allowed.\n");
6952 printk(TPACPI_NOTICE
6953 "Use the volume_control=1 module parameter "
6954 "to enable volume control\n");
6955 }
6956 return -EPERM;
6957 }
6958
6959 rc = volume_get_status(&s);
6960 if (rc < 0)
6961 return rc;
6962
6963 new_level = s & TP_EC_AUDIO_LVL_MSK;
6964 new_mute = s & TP_EC_AUDIO_MUTESW_MSK;
6965
6966 while ((cmd = next_cmd(&buf))) {
6967 if (!tp_features.mixer_no_level_control) {
6968 if (strlencmp(cmd, "up") == 0) {
6969 if (new_mute)
6970 new_mute = 0;
6971 else if (new_level < TP_EC_VOLUME_MAX)
6972 new_level++;
6973 continue;
6974 } else if (strlencmp(cmd, "down") == 0) {
6975 if (new_mute)
6976 new_mute = 0;
6977 else if (new_level > 0)
6978 new_level--;
6979 continue;
6980 } else if (sscanf(cmd, "level %u", &l) == 1 &&
6981 l >= 0 && l <= TP_EC_VOLUME_MAX) {
6982 new_level = l;
6983 continue;
6984 }
6985 }
6986 if (strlencmp(cmd, "mute") == 0)
6987 new_mute = TP_EC_AUDIO_MUTESW_MSK;
6988 else if (strlencmp(cmd, "unmute") == 0)
6989 new_mute = 0;
6990 else
6991 return -EINVAL;
6992 }
6993
6994 if (tp_features.mixer_no_level_control) {
6995 tpacpi_disclose_usertask("procfs volume", "%smute\n",
6996 new_mute ? "" : "un");
6997 rc = volume_set_mute(!!new_mute);
6998 } else {
6999 tpacpi_disclose_usertask("procfs volume",
7000 "%smute and set level to %d\n",
7001 new_mute ? "" : "un", new_level);
7002 rc = volume_set_status(new_mute | new_level);
7003 }
7004 volume_alsa_notify_change();
7005
7006 return (rc == -EINTR) ? -ERESTARTSYS : rc;
7007}
7008
6430static struct ibm_struct volume_driver_data = { 7009static struct ibm_struct volume_driver_data = {
6431 .name = "volume", 7010 .name = "volume",
6432 .read = volume_read, 7011 .read = volume_read,
6433 .write = volume_write, 7012 .write = volume_write,
7013 .exit = volume_exit,
7014 .suspend = volume_suspend,
7015 .resume = volume_resume,
7016 .shutdown = volume_shutdown,
6434}; 7017};
6435 7018
6436/************************************************************************* 7019/*************************************************************************
@@ -7507,9 +8090,8 @@ static void fan_resume(void)
7507 } 8090 }
7508} 8091}
7509 8092
7510static int fan_read(char *p) 8093static int fan_read(struct seq_file *m)
7511{ 8094{
7512 int len = 0;
7513 int rc; 8095 int rc;
7514 u8 status; 8096 u8 status;
7515 unsigned int speed = 0; 8097 unsigned int speed = 0;
@@ -7521,7 +8103,7 @@ static int fan_read(char *p)
7521 if (rc < 0) 8103 if (rc < 0)
7522 return rc; 8104 return rc;
7523 8105
7524 len += sprintf(p + len, "status:\t\t%s\n" 8106 seq_printf(m, "status:\t\t%s\n"
7525 "level:\t\t%d\n", 8107 "level:\t\t%d\n",
7526 (status != 0) ? "enabled" : "disabled", status); 8108 (status != 0) ? "enabled" : "disabled", status);
7527 break; 8109 break;
@@ -7532,54 +8114,54 @@ static int fan_read(char *p)
7532 if (rc < 0) 8114 if (rc < 0)
7533 return rc; 8115 return rc;
7534 8116
7535 len += sprintf(p + len, "status:\t\t%s\n", 8117 seq_printf(m, "status:\t\t%s\n",
7536 (status != 0) ? "enabled" : "disabled"); 8118 (status != 0) ? "enabled" : "disabled");
7537 8119
7538 rc = fan_get_speed(&speed); 8120 rc = fan_get_speed(&speed);
7539 if (rc < 0) 8121 if (rc < 0)
7540 return rc; 8122 return rc;
7541 8123
7542 len += sprintf(p + len, "speed:\t\t%d\n", speed); 8124 seq_printf(m, "speed:\t\t%d\n", speed);
7543 8125
7544 if (status & TP_EC_FAN_FULLSPEED) 8126 if (status & TP_EC_FAN_FULLSPEED)
7545 /* Disengaged mode takes precedence */ 8127 /* Disengaged mode takes precedence */
7546 len += sprintf(p + len, "level:\t\tdisengaged\n"); 8128 seq_printf(m, "level:\t\tdisengaged\n");
7547 else if (status & TP_EC_FAN_AUTO) 8129 else if (status & TP_EC_FAN_AUTO)
7548 len += sprintf(p + len, "level:\t\tauto\n"); 8130 seq_printf(m, "level:\t\tauto\n");
7549 else 8131 else
7550 len += sprintf(p + len, "level:\t\t%d\n", status); 8132 seq_printf(m, "level:\t\t%d\n", status);
7551 break; 8133 break;
7552 8134
7553 case TPACPI_FAN_NONE: 8135 case TPACPI_FAN_NONE:
7554 default: 8136 default:
7555 len += sprintf(p + len, "status:\t\tnot supported\n"); 8137 seq_printf(m, "status:\t\tnot supported\n");
7556 } 8138 }
7557 8139
7558 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { 8140 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
7559 len += sprintf(p + len, "commands:\tlevel <level>"); 8141 seq_printf(m, "commands:\tlevel <level>");
7560 8142
7561 switch (fan_control_access_mode) { 8143 switch (fan_control_access_mode) {
7562 case TPACPI_FAN_WR_ACPI_SFAN: 8144 case TPACPI_FAN_WR_ACPI_SFAN:
7563 len += sprintf(p + len, " (<level> is 0-7)\n"); 8145 seq_printf(m, " (<level> is 0-7)\n");
7564 break; 8146 break;
7565 8147
7566 default: 8148 default:
7567 len += sprintf(p + len, " (<level> is 0-7, " 8149 seq_printf(m, " (<level> is 0-7, "
7568 "auto, disengaged, full-speed)\n"); 8150 "auto, disengaged, full-speed)\n");
7569 break; 8151 break;
7570 } 8152 }
7571 } 8153 }
7572 8154
7573 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) 8155 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
7574 len += sprintf(p + len, "commands:\tenable, disable\n" 8156 seq_printf(m, "commands:\tenable, disable\n"
7575 "commands:\twatchdog <timeout> (<timeout> " 8157 "commands:\twatchdog <timeout> (<timeout> "
7576 "is 0 (off), 1-120 (seconds))\n"); 8158 "is 0 (off), 1-120 (seconds))\n");
7577 8159
7578 if (fan_control_commands & TPACPI_FAN_CMD_SPEED) 8160 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
7579 len += sprintf(p + len, "commands:\tspeed <speed>" 8161 seq_printf(m, "commands:\tspeed <speed>"
7580 " (<speed> is 0-65535)\n"); 8162 " (<speed> is 0-65535)\n");
7581 8163
7582 return len; 8164 return 0;
7583} 8165}
7584 8166
7585static int fan_write_cmd_level(const char *cmd, int *rc) 8167static int fan_write_cmd_level(const char *cmd, int *rc)
@@ -7721,10 +8303,23 @@ static struct ibm_struct fan_driver_data = {
7721 */ 8303 */
7722static void tpacpi_driver_event(const unsigned int hkey_event) 8304static void tpacpi_driver_event(const unsigned int hkey_event)
7723{ 8305{
8306 if (ibm_backlight_device) {
8307 switch (hkey_event) {
8308 case TP_HKEY_EV_BRGHT_UP:
8309 case TP_HKEY_EV_BRGHT_DOWN:
8310 tpacpi_brightness_notify_change();
8311 }
8312 }
8313 if (alsa_card) {
8314 switch (hkey_event) {
8315 case TP_HKEY_EV_VOL_UP:
8316 case TP_HKEY_EV_VOL_DOWN:
8317 case TP_HKEY_EV_VOL_MUTE:
8318 volume_alsa_notify_change();
8319 }
8320 }
7724} 8321}
7725 8322
7726
7727
7728static void hotkey_driver_event(const unsigned int scancode) 8323static void hotkey_driver_event(const unsigned int scancode)
7729{ 8324{
7730 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode); 8325 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
@@ -7853,19 +8448,19 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
7853 "%s installed\n", ibm->name); 8448 "%s installed\n", ibm->name);
7854 8449
7855 if (ibm->read) { 8450 if (ibm->read) {
7856 entry = create_proc_entry(ibm->name, 8451 mode_t mode;
7857 S_IFREG | S_IRUGO | S_IWUSR, 8452
7858 proc_dir); 8453 mode = S_IRUGO;
8454 if (ibm->write)
8455 mode |= S_IWUSR;
8456 entry = proc_create_data(ibm->name, mode, proc_dir,
8457 &dispatch_proc_fops, ibm);
7859 if (!entry) { 8458 if (!entry) {
7860 printk(TPACPI_ERR "unable to create proc entry %s\n", 8459 printk(TPACPI_ERR "unable to create proc entry %s\n",
7861 ibm->name); 8460 ibm->name);
7862 ret = -ENODEV; 8461 ret = -ENODEV;
7863 goto err_out; 8462 goto err_out;
7864 } 8463 }
7865 entry->data = ibm;
7866 entry->read_proc = &dispatch_procfs_read;
7867 if (ibm->write)
7868 entry->write_proc = &dispatch_procfs_write;
7869 ibm->flags.proc_created = 1; 8464 ibm->flags.proc_created = 1;
7870 } 8465 }
7871 8466
@@ -8077,6 +8672,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
8077 .data = &brightness_driver_data, 8672 .data = &brightness_driver_data,
8078 }, 8673 },
8079 { 8674 {
8675 .init = volume_init,
8080 .data = &volume_driver_data, 8676 .data = &volume_driver_data,
8081 }, 8677 },
8082 { 8678 {
@@ -8112,36 +8708,59 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
8112 return -EINVAL; 8708 return -EINVAL;
8113} 8709}
8114 8710
8115module_param(experimental, int, 0); 8711module_param(experimental, int, 0444);
8116MODULE_PARM_DESC(experimental, 8712MODULE_PARM_DESC(experimental,
8117 "Enables experimental features when non-zero"); 8713 "Enables experimental features when non-zero");
8118 8714
8119module_param_named(debug, dbg_level, uint, 0); 8715module_param_named(debug, dbg_level, uint, 0);
8120MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); 8716MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
8121 8717
8122module_param(force_load, bool, 0); 8718module_param(force_load, bool, 0444);
8123MODULE_PARM_DESC(force_load, 8719MODULE_PARM_DESC(force_load,
8124 "Attempts to load the driver even on a " 8720 "Attempts to load the driver even on a "
8125 "mis-identified ThinkPad when true"); 8721 "mis-identified ThinkPad when true");
8126 8722
8127module_param_named(fan_control, fan_control_allowed, bool, 0); 8723module_param_named(fan_control, fan_control_allowed, bool, 0444);
8128MODULE_PARM_DESC(fan_control, 8724MODULE_PARM_DESC(fan_control,
8129 "Enables setting fan parameters features when true"); 8725 "Enables setting fan parameters features when true");
8130 8726
8131module_param_named(brightness_mode, brightness_mode, uint, 0); 8727module_param_named(brightness_mode, brightness_mode, uint, 0444);
8132MODULE_PARM_DESC(brightness_mode, 8728MODULE_PARM_DESC(brightness_mode,
8133 "Selects brightness control strategy: " 8729 "Selects brightness control strategy: "
8134 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); 8730 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
8135 8731
8136module_param(brightness_enable, uint, 0); 8732module_param(brightness_enable, uint, 0444);
8137MODULE_PARM_DESC(brightness_enable, 8733MODULE_PARM_DESC(brightness_enable,
8138 "Enables backlight control when 1, disables when 0"); 8734 "Enables backlight control when 1, disables when 0");
8139 8735
8140module_param(hotkey_report_mode, uint, 0); 8736module_param(hotkey_report_mode, uint, 0444);
8141MODULE_PARM_DESC(hotkey_report_mode, 8737MODULE_PARM_DESC(hotkey_report_mode,
8142 "used for backwards compatibility with userspace, " 8738 "used for backwards compatibility with userspace, "
8143 "see documentation"); 8739 "see documentation");
8144 8740
8741module_param_named(volume_mode, volume_mode, uint, 0444);
8742MODULE_PARM_DESC(volume_mode,
8743 "Selects volume control strategy: "
8744 "0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");
8745
8746module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
8747MODULE_PARM_DESC(volume_capabilities,
8748 "Selects the mixer capabilites: "
8749 "0=auto, 1=volume and mute, 2=mute only");
8750
8751module_param_named(volume_control, volume_control_allowed, bool, 0444);
8752MODULE_PARM_DESC(volume_control,
8753 "Enables software override for the console audio "
8754 "control when true");
8755
8756/* ALSA module API parameters */
8757module_param_named(index, alsa_index, int, 0444);
8758MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
8759module_param_named(id, alsa_id, charp, 0444);
8760MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
8761module_param_named(enable, alsa_enable, bool, 0444);
8762MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
8763
8145#define TPACPI_PARAM(feature) \ 8764#define TPACPI_PARAM(feature) \
8146 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ 8765 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
8147 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \ 8766 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
@@ -8160,25 +8779,25 @@ TPACPI_PARAM(volume);
8160TPACPI_PARAM(fan); 8779TPACPI_PARAM(fan);
8161 8780
8162#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 8781#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
8163module_param(dbg_wlswemul, uint, 0); 8782module_param(dbg_wlswemul, uint, 0444);
8164MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); 8783MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
8165module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); 8784module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
8166MODULE_PARM_DESC(wlsw_state, 8785MODULE_PARM_DESC(wlsw_state,
8167 "Initial state of the emulated WLSW switch"); 8786 "Initial state of the emulated WLSW switch");
8168 8787
8169module_param(dbg_bluetoothemul, uint, 0); 8788module_param(dbg_bluetoothemul, uint, 0444);
8170MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); 8789MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
8171module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); 8790module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
8172MODULE_PARM_DESC(bluetooth_state, 8791MODULE_PARM_DESC(bluetooth_state,
8173 "Initial state of the emulated bluetooth switch"); 8792 "Initial state of the emulated bluetooth switch");
8174 8793
8175module_param(dbg_wwanemul, uint, 0); 8794module_param(dbg_wwanemul, uint, 0444);
8176MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); 8795MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
8177module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); 8796module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
8178MODULE_PARM_DESC(wwan_state, 8797MODULE_PARM_DESC(wwan_state,
8179 "Initial state of the emulated WWAN switch"); 8798 "Initial state of the emulated WWAN switch");
8180 8799
8181module_param(dbg_uwbemul, uint, 0); 8800module_param(dbg_uwbemul, uint, 0444);
8182MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); 8801MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
8183module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); 8802module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
8184MODULE_PARM_DESC(uwb_state, 8803MODULE_PARM_DESC(uwb_state,
@@ -8371,6 +8990,7 @@ static int __init thinkpad_acpi_module_init(void)
8371 PCI_VENDOR_ID_IBM; 8990 PCI_VENDOR_ID_IBM;
8372 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 8991 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
8373 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 8992 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
8993 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
8374 } 8994 }
8375 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 8995 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
8376 ret = ibm_init(&ibms_init[i]); 8996 ret = ibm_init(&ibms_init[i]);