aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/thinkpad_acpi.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/platform/x86/thinkpad_acpi.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c1313
1 files changed, 1003 insertions, 310 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a848c7e20aeb..63290b33c879 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:
@@ -58,9 +58,11 @@
58#include <linux/kthread.h> 58#include <linux/kthread.h>
59#include <linux/freezer.h> 59#include <linux/freezer.h>
60#include <linux/delay.h> 60#include <linux/delay.h>
61#include <linux/slab.h>
61 62
62#include <linux/nvram.h> 63#include <linux/nvram.h>
63#include <linux/proc_fs.h> 64#include <linux/proc_fs.h>
65#include <linux/seq_file.h>
64#include <linux/sysfs.h> 66#include <linux/sysfs.h>
65#include <linux/backlight.h> 67#include <linux/backlight.h>
66#include <linux/fb.h> 68#include <linux/fb.h>
@@ -76,6 +78,10 @@
76#include <linux/jiffies.h> 78#include <linux/jiffies.h>
77#include <linux/workqueue.h> 79#include <linux/workqueue.h>
78 80
81#include <sound/core.h>
82#include <sound/control.h>
83#include <sound/initval.h>
84
79#include <acpi/acpi_drivers.h> 85#include <acpi/acpi_drivers.h>
80 86
81#include <linux/pci_ids.h> 87#include <linux/pci_ids.h>
@@ -231,6 +237,7 @@ enum tpacpi_hkey_event_t {
231#define TPACPI_DBG_HKEY 0x0008 237#define TPACPI_DBG_HKEY 0x0008
232#define TPACPI_DBG_FAN 0x0010 238#define TPACPI_DBG_FAN 0x0010
233#define TPACPI_DBG_BRGHT 0x0020 239#define TPACPI_DBG_BRGHT 0x0020
240#define TPACPI_DBG_MIXER 0x0040
234 241
235#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") 242#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
236#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 243#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -256,7 +263,7 @@ struct tp_acpi_drv_struct {
256struct ibm_struct { 263struct ibm_struct {
257 char *name; 264 char *name;
258 265
259 int (*read) (char *); 266 int (*read) (struct seq_file *);
260 int (*write) (char *); 267 int (*write) (char *);
261 void (*exit) (void); 268 void (*exit) (void);
262 void (*resume) (void); 269 void (*resume) (void);
@@ -280,6 +287,7 @@ struct ibm_init_struct {
280 char param[32]; 287 char param[32];
281 288
282 int (*init) (struct ibm_init_struct *); 289 int (*init) (struct ibm_init_struct *);
290 mode_t base_procfs_mode;
283 struct ibm_struct *data; 291 struct ibm_struct *data;
284}; 292};
285 293
@@ -298,6 +306,7 @@ static struct {
298 u32 fan_ctrl_status_undef:1; 306 u32 fan_ctrl_status_undef:1;
299 u32 second_fan:1; 307 u32 second_fan:1;
300 u32 beep_needs_two_args:1; 308 u32 beep_needs_two_args:1;
309 u32 mixer_no_level_control:1;
301 u32 input_device_registered:1; 310 u32 input_device_registered:1;
302 u32 platform_drv_registered:1; 311 u32 platform_drv_registered:1;
303 u32 platform_drv_attrs_registered:1; 312 u32 platform_drv_attrs_registered:1;
@@ -309,6 +318,7 @@ static struct {
309 318
310static struct { 319static struct {
311 u16 hotkey_mask_ff:1; 320 u16 hotkey_mask_ff:1;
321 u16 volume_ctrl_forbidden:1;
312} tp_warned; 322} tp_warned;
313 323
314struct thinkpad_id_data { 324struct thinkpad_id_data {
@@ -425,6 +435,12 @@ static void tpacpi_log_usertask(const char * const what)
425 .ec = TPACPI_MATCH_ANY, \ 435 .ec = TPACPI_MATCH_ANY, \
426 .quirks = (__quirk) } 436 .quirks = (__quirk) }
427 437
438#define TPACPI_QEC_LNV(__id1, __id2, __quirk) \
439 { .vendor = PCI_VENDOR_ID_LENOVO, \
440 .bios = TPACPI_MATCH_ANY, \
441 .ec = TPID(__id1, __id2), \
442 .quirks = (__quirk) }
443
428struct tpacpi_quirk { 444struct tpacpi_quirk {
429 unsigned int vendor; 445 unsigned int vendor;
430 u16 bios; 446 u16 bios;
@@ -776,36 +792,25 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
776 **************************************************************************** 792 ****************************************************************************
777 ****************************************************************************/ 793 ****************************************************************************/
778 794
779static int dispatch_procfs_read(char *page, char **start, off_t off, 795static int dispatch_proc_show(struct seq_file *m, void *v)
780 int count, int *eof, void *data)
781{ 796{
782 struct ibm_struct *ibm = data; 797 struct ibm_struct *ibm = m->private;
783 int len;
784 798
785 if (!ibm || !ibm->read) 799 if (!ibm || !ibm->read)
786 return -EINVAL; 800 return -EINVAL;
801 return ibm->read(m);
802}
787 803
788 len = ibm->read(page); 804static int dispatch_proc_open(struct inode *inode, struct file *file)
789 if (len < 0) 805{
790 return len; 806 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} 807}
803 808
804static int dispatch_procfs_write(struct file *file, 809static ssize_t dispatch_proc_write(struct file *file,
805 const char __user *userbuf, 810 const char __user *userbuf,
806 unsigned long count, void *data) 811 size_t count, loff_t *pos)
807{ 812{
808 struct ibm_struct *ibm = data; 813 struct ibm_struct *ibm = PDE(file->f_path.dentry->d_inode)->data;
809 char *kernbuf; 814 char *kernbuf;
810 int ret; 815 int ret;
811 816
@@ -834,6 +839,15 @@ static int dispatch_procfs_write(struct file *file,
834 return ret; 839 return ret;
835} 840}
836 841
842static const struct file_operations dispatch_proc_fops = {
843 .owner = THIS_MODULE,
844 .open = dispatch_proc_open,
845 .read = seq_read,
846 .llseek = seq_lseek,
847 .release = single_release,
848 .write = dispatch_proc_write,
849};
850
837static char *next_cmd(char **cmds) 851static char *next_cmd(char **cmds)
838{ 852{
839 char *start = *cmds; 853 char *start = *cmds;
@@ -1006,11 +1020,8 @@ static int parse_strtoul(const char *buf,
1006{ 1020{
1007 char *endp; 1021 char *endp;
1008 1022
1009 while (*buf && isspace(*buf)) 1023 *value = simple_strtoul(skip_spaces(buf), &endp, 0);
1010 buf++; 1024 endp = skip_spaces(endp);
1011 *value = simple_strtoul(buf, &endp, 0);
1012 while (*endp && isspace(*endp))
1013 endp++;
1014 if (*endp || *value > max) 1025 if (*endp || *value > max)
1015 return -EINVAL; 1026 return -EINVAL;
1016 1027
@@ -1087,7 +1098,7 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
1087 */ 1098 */
1088 1099
1089 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, 1100 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
1090 tpacpi_acpi_walk_find_bcl, NULL, 1101 tpacpi_acpi_walk_find_bcl, NULL, NULL,
1091 &bcl_ptr); 1102 &bcl_ptr);
1092 1103
1093 if (ACPI_SUCCESS(status) && bcl_levels > 2) { 1104 if (ACPI_SUCCESS(status) && bcl_levels > 2) {
@@ -1264,6 +1275,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1264 struct tpacpi_rfk *atp_rfk; 1275 struct tpacpi_rfk *atp_rfk;
1265 int res; 1276 int res;
1266 bool sw_state = false; 1277 bool sw_state = false;
1278 bool hw_state;
1267 int sw_status; 1279 int sw_status;
1268 1280
1269 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); 1281 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
@@ -1298,7 +1310,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1298 rfkill_init_sw_state(atp_rfk->rfkill, sw_state); 1310 rfkill_init_sw_state(atp_rfk->rfkill, sw_state);
1299 } 1311 }
1300 } 1312 }
1301 rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); 1313 hw_state = tpacpi_rfk_check_hwblock_state();
1314 rfkill_set_hw_state(atp_rfk->rfkill, hw_state);
1302 1315
1303 res = rfkill_register(atp_rfk->rfkill); 1316 res = rfkill_register(atp_rfk->rfkill);
1304 if (res < 0) { 1317 if (res < 0) {
@@ -1311,6 +1324,9 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1311 } 1324 }
1312 1325
1313 tpacpi_rfkill_switches[id] = atp_rfk; 1326 tpacpi_rfkill_switches[id] = atp_rfk;
1327
1328 printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n",
1329 name, (sw_state || hw_state) ? "" : "un");
1314 return 0; 1330 return 0;
1315} 1331}
1316 1332
@@ -1383,12 +1399,10 @@ static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1383} 1399}
1384 1400
1385/* procfs -------------------------------------------------------------- */ 1401/* procfs -------------------------------------------------------------- */
1386static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p) 1402static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)
1387{ 1403{
1388 int len = 0;
1389
1390 if (id >= TPACPI_RFK_SW_MAX) 1404 if (id >= TPACPI_RFK_SW_MAX)
1391 len += sprintf(p + len, "status:\t\tnot supported\n"); 1405 seq_printf(m, "status:\t\tnot supported\n");
1392 else { 1406 else {
1393 int status; 1407 int status;
1394 1408
@@ -1402,13 +1416,13 @@ static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
1402 return status; 1416 return status;
1403 } 1417 }
1404 1418
1405 len += sprintf(p + len, "status:\t\t%s\n", 1419 seq_printf(m, "status:\t\t%s\n",
1406 (status == TPACPI_RFK_RADIO_ON) ? 1420 (status == TPACPI_RFK_RADIO_ON) ?
1407 "enabled" : "disabled"); 1421 "enabled" : "disabled");
1408 len += sprintf(p + len, "commands:\tenable, disable\n"); 1422 seq_printf(m, "commands:\tenable, disable\n");
1409 } 1423 }
1410 1424
1411 return len; 1425 return 0;
1412} 1426}
1413 1427
1414static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf) 1428static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
@@ -1655,7 +1669,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
1655 * Table of recommended minimum BIOS versions 1669 * Table of recommended minimum BIOS versions
1656 * 1670 *
1657 * Reasons for listing: 1671 * Reasons for listing:
1658 * 1. Stable BIOS, listed because the unknown ammount of 1672 * 1. Stable BIOS, listed because the unknown amount of
1659 * bugs and bad ACPI behaviour on older versions 1673 * bugs and bad ACPI behaviour on older versions
1660 * 1674 *
1661 * 2. BIOS or EC fw with known bugs that trigger on Linux 1675 * 2. BIOS or EC fw with known bugs that trigger on Linux
@@ -1779,7 +1793,7 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1779 1793
1780 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */ 1794 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */
1781 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */ 1795 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */
1782 TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */ 1796 TPV_QL1('7', 'E', 'D', '0', '1', '5'), /* R60e, R60i */
1783 1797
1784 /* BIOS FW BIOS VERS EC FW EC VERS */ 1798 /* BIOS FW BIOS VERS EC FW EC VERS */
1785 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */ 1799 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */
@@ -1795,8 +1809,8 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1795 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */ 1809 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */
1796 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */ 1810 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */
1797 1811
1798 TPV_QL0('7', 'B', 'D', '7'), /* X60/s */ 1812 TPV_QL1('7', 'B', 'D', '7', '4', '0'), /* X60/s */
1799 TPV_QL0('7', 'J', '3', '0'), /* X60t */ 1813 TPV_QL1('7', 'J', '3', '0', '1', '3'), /* X60t */
1800 1814
1801 /* (0) - older versions lack DMI EC fw string and functionality */ 1815 /* (0) - older versions lack DMI EC fw string and functionality */
1802 /* (1) - older versions known to lack functionality */ 1816 /* (1) - older versions known to lack functionality */
@@ -1886,14 +1900,11 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
1886 return 0; 1900 return 0;
1887} 1901}
1888 1902
1889static int thinkpad_acpi_driver_read(char *p) 1903static int thinkpad_acpi_driver_read(struct seq_file *m)
1890{ 1904{
1891 int len = 0; 1905 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);
1892 1906 seq_printf(m, "version:\t%s\n", TPACPI_VERSION);
1893 len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC); 1907 return 0;
1894 len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION);
1895
1896 return len;
1897} 1908}
1898 1909
1899static struct ibm_struct thinkpad_acpi_driver_data = { 1910static struct ibm_struct thinkpad_acpi_driver_data = {
@@ -2073,6 +2084,7 @@ static struct attribute_set *hotkey_dev_attributes;
2073 2084
2074static void tpacpi_driver_event(const unsigned int hkey_event); 2085static void tpacpi_driver_event(const unsigned int hkey_event);
2075static void hotkey_driver_event(const unsigned int scancode); 2086static void hotkey_driver_event(const unsigned int scancode);
2087static void hotkey_poll_setup(const bool may_warn);
2076 2088
2077/* HKEY.MHKG() return bits */ 2089/* HKEY.MHKG() return bits */
2078#define TP_HOTKEY_TABLET_MASK (1 << 3) 2090#define TP_HOTKEY_TABLET_MASK (1 << 3)
@@ -2189,7 +2201,8 @@ static int hotkey_mask_set(u32 mask)
2189 fwmask, hotkey_acpi_mask); 2201 fwmask, hotkey_acpi_mask);
2190 } 2202 }
2191 2203
2192 hotkey_mask_warn_incomplete_mask(); 2204 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)
2205 hotkey_mask_warn_incomplete_mask();
2193 2206
2194 return rc; 2207 return rc;
2195} 2208}
@@ -2254,6 +2267,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask)
2254 2267
2255 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & 2268 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
2256 ~hotkey_source_mask); 2269 ~hotkey_source_mask);
2270 hotkey_poll_setup(true);
2271
2257 mutex_unlock(&hotkey_mutex); 2272 mutex_unlock(&hotkey_mutex);
2258 2273
2259 return rc; 2274 return rc;
@@ -2538,7 +2553,7 @@ static void hotkey_poll_stop_sync(void)
2538} 2553}
2539 2554
2540/* call with hotkey_mutex held */ 2555/* call with hotkey_mutex held */
2541static void hotkey_poll_setup(bool may_warn) 2556static void hotkey_poll_setup(const bool may_warn)
2542{ 2557{
2543 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; 2558 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2544 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; 2559 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
@@ -2569,7 +2584,7 @@ static void hotkey_poll_setup(bool may_warn)
2569 } 2584 }
2570} 2585}
2571 2586
2572static void hotkey_poll_setup_safe(bool may_warn) 2587static void hotkey_poll_setup_safe(const bool may_warn)
2573{ 2588{
2574 mutex_lock(&hotkey_mutex); 2589 mutex_lock(&hotkey_mutex);
2575 hotkey_poll_setup(may_warn); 2590 hotkey_poll_setup(may_warn);
@@ -2587,7 +2602,11 @@ static void hotkey_poll_set_freq(unsigned int freq)
2587 2602
2588#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2603#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
2589 2604
2590static void hotkey_poll_setup_safe(bool __unused) 2605static void hotkey_poll_setup(const bool __unused)
2606{
2607}
2608
2609static void hotkey_poll_setup_safe(const bool __unused)
2591{ 2610{
2592} 2611}
2593 2612
@@ -2597,16 +2616,11 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2597{ 2616{
2598 switch (tpacpi_lifecycle) { 2617 switch (tpacpi_lifecycle) {
2599 case TPACPI_LIFE_INIT: 2618 case TPACPI_LIFE_INIT:
2600 /*
2601 * hotkey_init will call hotkey_poll_setup_safe
2602 * at the appropriate moment
2603 */
2604 return 0;
2605 case TPACPI_LIFE_EXITING:
2606 return -EBUSY;
2607 case TPACPI_LIFE_RUNNING: 2619 case TPACPI_LIFE_RUNNING:
2608 hotkey_poll_setup_safe(false); 2620 hotkey_poll_setup_safe(false);
2609 return 0; 2621 return 0;
2622 case TPACPI_LIFE_EXITING:
2623 return -EBUSY;
2610 } 2624 }
2611 2625
2612 /* Should only happen if tpacpi_lifecycle is corrupt */ 2626 /* Should only happen if tpacpi_lifecycle is corrupt */
@@ -2617,7 +2631,7 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2617static void hotkey_inputdev_close(struct input_dev *dev) 2631static void hotkey_inputdev_close(struct input_dev *dev)
2618{ 2632{
2619 /* disable hotkey polling when possible */ 2633 /* disable hotkey polling when possible */
2620 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && 2634 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
2621 !(hotkey_source_mask & hotkey_driver_mask)) 2635 !(hotkey_source_mask & hotkey_driver_mask))
2622 hotkey_poll_setup_safe(false); 2636 hotkey_poll_setup_safe(false);
2623} 2637}
@@ -3185,6 +3199,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3185 int res, i; 3199 int res, i;
3186 int status; 3200 int status;
3187 int hkeyv; 3201 int hkeyv;
3202 bool radiosw_state = false;
3203 bool tabletsw_state = false;
3188 3204
3189 unsigned long quirks; 3205 unsigned long quirks;
3190 3206
@@ -3290,6 +3306,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3290#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3306#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3291 if (dbg_wlswemul) { 3307 if (dbg_wlswemul) {
3292 tp_features.hotkey_wlsw = 1; 3308 tp_features.hotkey_wlsw = 1;
3309 radiosw_state = !!tpacpi_wlsw_emulstate;
3293 printk(TPACPI_INFO 3310 printk(TPACPI_INFO
3294 "radio switch emulation enabled\n"); 3311 "radio switch emulation enabled\n");
3295 } else 3312 } else
@@ -3297,6 +3314,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3297 /* Not all thinkpads have a hardware radio switch */ 3314 /* Not all thinkpads have a hardware radio switch */
3298 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 3315 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
3299 tp_features.hotkey_wlsw = 1; 3316 tp_features.hotkey_wlsw = 1;
3317 radiosw_state = !!status;
3300 printk(TPACPI_INFO 3318 printk(TPACPI_INFO
3301 "radio switch found; radios are %s\n", 3319 "radio switch found; radios are %s\n",
3302 enabled(status, 0)); 3320 enabled(status, 0));
@@ -3308,11 +3326,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3308 /* For X41t, X60t, X61t Tablets... */ 3326 /* For X41t, X60t, X61t Tablets... */
3309 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { 3327 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
3310 tp_features.hotkey_tablet = 1; 3328 tp_features.hotkey_tablet = 1;
3329 tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
3311 printk(TPACPI_INFO 3330 printk(TPACPI_INFO
3312 "possible tablet mode switch found; " 3331 "possible tablet mode switch found; "
3313 "ThinkPad in %s mode\n", 3332 "ThinkPad in %s mode\n",
3314 (status & TP_HOTKEY_TABLET_MASK)? 3333 (tabletsw_state) ? "tablet" : "laptop");
3315 "tablet" : "laptop");
3316 res = add_to_attr_set(hotkey_dev_attributes, 3334 res = add_to_attr_set(hotkey_dev_attributes,
3317 &dev_attr_hotkey_tablet_mode.attr); 3335 &dev_attr_hotkey_tablet_mode.attr);
3318 } 3336 }
@@ -3347,16 +3365,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3347 TPACPI_HOTKEY_MAP_SIZE); 3365 TPACPI_HOTKEY_MAP_SIZE);
3348 } 3366 }
3349 3367
3350 set_bit(EV_KEY, tpacpi_inputdev->evbit); 3368 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
3351 set_bit(EV_MSC, tpacpi_inputdev->evbit);
3352 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
3353 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 3369 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
3354 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; 3370 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
3355 tpacpi_inputdev->keycode = hotkey_keycode_map; 3371 tpacpi_inputdev->keycode = hotkey_keycode_map;
3356 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { 3372 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
3357 if (hotkey_keycode_map[i] != KEY_RESERVED) { 3373 if (hotkey_keycode_map[i] != KEY_RESERVED) {
3358 set_bit(hotkey_keycode_map[i], 3374 input_set_capability(tpacpi_inputdev, EV_KEY,
3359 tpacpi_inputdev->keybit); 3375 hotkey_keycode_map[i]);
3360 } else { 3376 } else {
3361 if (i < sizeof(hotkey_reserved_mask)*8) 3377 if (i < sizeof(hotkey_reserved_mask)*8)
3362 hotkey_reserved_mask |= 1 << i; 3378 hotkey_reserved_mask |= 1 << i;
@@ -3364,12 +3380,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3364 } 3380 }
3365 3381
3366 if (tp_features.hotkey_wlsw) { 3382 if (tp_features.hotkey_wlsw) {
3367 set_bit(EV_SW, tpacpi_inputdev->evbit); 3383 input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);
3368 set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); 3384 input_report_switch(tpacpi_inputdev,
3385 SW_RFKILL_ALL, radiosw_state);
3369 } 3386 }
3370 if (tp_features.hotkey_tablet) { 3387 if (tp_features.hotkey_tablet) {
3371 set_bit(EV_SW, tpacpi_inputdev->evbit); 3388 input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);
3372 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); 3389 input_report_switch(tpacpi_inputdev,
3390 SW_TABLET_MODE, tabletsw_state);
3373 } 3391 }
3374 3392
3375 /* Do not issue duplicate brightness change events to 3393 /* Do not issue duplicate brightness change events to
@@ -3436,8 +3454,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3436 tpacpi_inputdev->close = &hotkey_inputdev_close; 3454 tpacpi_inputdev->close = &hotkey_inputdev_close;
3437 3455
3438 hotkey_poll_setup_safe(true); 3456 hotkey_poll_setup_safe(true);
3439 tpacpi_send_radiosw_update();
3440 tpacpi_input_send_tabletsw();
3441 3457
3442 return 0; 3458 return 0;
3443 3459
@@ -3545,49 +3561,57 @@ static bool hotkey_notify_usrevent(const u32 hkey,
3545 } 3561 }
3546} 3562}
3547 3563
3564static void thermal_dump_all_sensors(void);
3565
3548static bool hotkey_notify_thermal(const u32 hkey, 3566static bool hotkey_notify_thermal(const u32 hkey,
3549 bool *send_acpi_ev, 3567 bool *send_acpi_ev,
3550 bool *ignore_acpi_ev) 3568 bool *ignore_acpi_ev)
3551{ 3569{
3570 bool known = true;
3571
3552 /* 0x6000-0x6FFF: thermal alarms */ 3572 /* 0x6000-0x6FFF: thermal alarms */
3553 *send_acpi_ev = true; 3573 *send_acpi_ev = true;
3554 *ignore_acpi_ev = false; 3574 *ignore_acpi_ev = false;
3555 3575
3556 switch (hkey) { 3576 switch (hkey) {
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;
3557 case TP_HKEY_EV_ALARM_BAT_HOT: 3583 case TP_HKEY_EV_ALARM_BAT_HOT:
3558 printk(TPACPI_CRIT 3584 printk(TPACPI_CRIT
3559 "THERMAL ALARM: battery is too hot!\n"); 3585 "THERMAL ALARM: battery is too hot!\n");
3560 /* recommended action: warn user through gui */ 3586 /* recommended action: warn user through gui */
3561 return true; 3587 break;
3562 case TP_HKEY_EV_ALARM_BAT_XHOT: 3588 case TP_HKEY_EV_ALARM_BAT_XHOT:
3563 printk(TPACPI_ALERT 3589 printk(TPACPI_ALERT
3564 "THERMAL EMERGENCY: battery is extremely hot!\n"); 3590 "THERMAL EMERGENCY: battery is extremely hot!\n");
3565 /* recommended action: immediate sleep/hibernate */ 3591 /* recommended action: immediate sleep/hibernate */
3566 return true; 3592 break;
3567 case TP_HKEY_EV_ALARM_SENSOR_HOT: 3593 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3568 printk(TPACPI_CRIT 3594 printk(TPACPI_CRIT
3569 "THERMAL ALARM: " 3595 "THERMAL ALARM: "
3570 "a sensor reports something is too hot!\n"); 3596 "a sensor reports something is too hot!\n");
3571 /* recommended action: warn user through gui, that */ 3597 /* recommended action: warn user through gui, that */
3572 /* some internal component is too hot */ 3598 /* some internal component is too hot */
3573 return true; 3599 break;
3574 case TP_HKEY_EV_ALARM_SENSOR_XHOT: 3600 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3575 printk(TPACPI_ALERT 3601 printk(TPACPI_ALERT
3576 "THERMAL EMERGENCY: " 3602 "THERMAL EMERGENCY: "
3577 "a sensor reports something is extremely hot!\n"); 3603 "a sensor reports something is extremely hot!\n");
3578 /* recommended action: immediate sleep/hibernate */ 3604 /* recommended action: immediate sleep/hibernate */
3579 return true; 3605 break;
3580 case TP_HKEY_EV_THM_TABLE_CHANGED:
3581 printk(TPACPI_INFO
3582 "EC reports that Thermal Table has changed\n");
3583 /* recommended action: do nothing, we don't have
3584 * Lenovo ATM information */
3585 return true;
3586 default: 3606 default:
3587 printk(TPACPI_ALERT 3607 printk(TPACPI_ALERT
3588 "THERMAL ALERT: unknown thermal alarm received\n"); 3608 "THERMAL ALERT: unknown thermal alarm received\n");
3589 return false; 3609 known = false;
3590 } 3610 }
3611
3612 thermal_dump_all_sensors();
3613
3614 return known;
3591} 3615}
3592 3616
3593static void hotkey_notify(struct ibm_struct *ibm, u32 event) 3617static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -3635,13 +3659,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3635 break; 3659 break;
3636 case 3: 3660 case 3:
3637 /* 0x3000-0x3FFF: bay-related wakeups */ 3661 /* 0x3000-0x3FFF: bay-related wakeups */
3638 if (hkey == TP_HKEY_EV_BAYEJ_ACK) { 3662 switch (hkey) {
3663 case TP_HKEY_EV_BAYEJ_ACK:
3639 hotkey_autosleep_ack = 1; 3664 hotkey_autosleep_ack = 1;
3640 printk(TPACPI_INFO 3665 printk(TPACPI_INFO
3641 "bay ejected\n"); 3666 "bay ejected\n");
3642 hotkey_wakeup_hotunplug_complete_notify_change(); 3667 hotkey_wakeup_hotunplug_complete_notify_change();
3643 known_ev = true; 3668 known_ev = true;
3644 } else { 3669 break;
3670 case TP_HKEY_EV_OPTDRV_EJ:
3671 /* FIXME: kick libata if SATA link offline */
3672 known_ev = true;
3673 break;
3674 default:
3645 known_ev = false; 3675 known_ev = false;
3646 } 3676 }
3647 break; 3677 break;
@@ -3730,14 +3760,13 @@ static void hotkey_resume(void)
3730} 3760}
3731 3761
3732/* procfs -------------------------------------------------------------- */ 3762/* procfs -------------------------------------------------------------- */
3733static int hotkey_read(char *p) 3763static int hotkey_read(struct seq_file *m)
3734{ 3764{
3735 int res, status; 3765 int res, status;
3736 int len = 0;
3737 3766
3738 if (!tp_features.hotkey) { 3767 if (!tp_features.hotkey) {
3739 len += sprintf(p + len, "status:\t\tnot supported\n"); 3768 seq_printf(m, "status:\t\tnot supported\n");
3740 return len; 3769 return 0;
3741 } 3770 }
3742 3771
3743 if (mutex_lock_killable(&hotkey_mutex)) 3772 if (mutex_lock_killable(&hotkey_mutex))
@@ -3749,17 +3778,16 @@ static int hotkey_read(char *p)
3749 if (res) 3778 if (res)
3750 return res; 3779 return res;
3751 3780
3752 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 3781 seq_printf(m, "status:\t\t%s\n", enabled(status, 0));
3753 if (hotkey_all_mask) { 3782 if (hotkey_all_mask) {
3754 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask); 3783 seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);
3755 len += sprintf(p + len, 3784 seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");
3756 "commands:\tenable, disable, reset, <mask>\n");
3757 } else { 3785 } else {
3758 len += sprintf(p + len, "mask:\t\tnot supported\n"); 3786 seq_printf(m, "mask:\t\tnot supported\n");
3759 len += sprintf(p + len, "commands:\tenable, disable, reset\n"); 3787 seq_printf(m, "commands:\tenable, disable, reset\n");
3760 } 3788 }
3761 3789
3762 return len; 3790 return 0;
3763} 3791}
3764 3792
3765static void hotkey_enabledisable_warn(bool enable) 3793static void hotkey_enabledisable_warn(bool enable)
@@ -3852,7 +3880,7 @@ enum {
3852 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ 3880 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
3853 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ 3881 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
3854 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: 3882 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
3855 off / last state */ 3883 0 = disable, 1 = enable */
3856}; 3884};
3857 3885
3858enum { 3886enum {
@@ -3866,15 +3894,6 @@ enum {
3866 3894
3867#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3895#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3868 3896
3869static void bluetooth_suspend(pm_message_t state)
3870{
3871 /* Try to make sure radio will resume powered off */
3872 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
3873 TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
3874 vdbg_printk(TPACPI_DBG_RFKILL,
3875 "bluetooth power down on resume request failed\n");
3876}
3877
3878static int bluetooth_get_status(void) 3897static int bluetooth_get_status(void)
3879{ 3898{
3880 int status; 3899 int status;
@@ -3907,9 +3926,9 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3907 } 3926 }
3908#endif 3927#endif
3909 3928
3910 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3911 if (state == TPACPI_RFK_RADIO_ON) 3929 if (state == TPACPI_RFK_RADIO_ON)
3912 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3930 status = TP_ACPI_BLUETOOTH_RADIOSSW
3931 | TP_ACPI_BLUETOOTH_RESUMECTRL;
3913 else 3932 else
3914 status = 0; 3933 status = 0;
3915 3934
@@ -4035,9 +4054,9 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
4035} 4054}
4036 4055
4037/* procfs -------------------------------------------------------------- */ 4056/* procfs -------------------------------------------------------------- */
4038static int bluetooth_read(char *p) 4057static int bluetooth_read(struct seq_file *m)
4039{ 4058{
4040 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p); 4059 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);
4041} 4060}
4042 4061
4043static int bluetooth_write(char *buf) 4062static int bluetooth_write(char *buf)
@@ -4050,7 +4069,6 @@ static struct ibm_struct bluetooth_driver_data = {
4050 .read = bluetooth_read, 4069 .read = bluetooth_read,
4051 .write = bluetooth_write, 4070 .write = bluetooth_write,
4052 .exit = bluetooth_exit, 4071 .exit = bluetooth_exit,
4053 .suspend = bluetooth_suspend,
4054 .shutdown = bluetooth_shutdown, 4072 .shutdown = bluetooth_shutdown,
4055}; 4073};
4056 4074
@@ -4063,20 +4081,11 @@ enum {
4063 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ 4081 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
4064 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ 4082 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
4065 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: 4083 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
4066 off / last state */ 4084 0 = disable, 1 = enable */
4067}; 4085};
4068 4086
4069#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 4087#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
4070 4088
4071static void wan_suspend(pm_message_t state)
4072{
4073 /* Try to make sure radio will resume powered off */
4074 if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
4075 TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
4076 vdbg_printk(TPACPI_DBG_RFKILL,
4077 "WWAN power down on resume request failed\n");
4078}
4079
4080static int wan_get_status(void) 4089static int wan_get_status(void)
4081{ 4090{
4082 int status; 4091 int status;
@@ -4109,9 +4118,9 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
4109 } 4118 }
4110#endif 4119#endif
4111 4120
4112 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
4113 if (state == TPACPI_RFK_RADIO_ON) 4121 if (state == TPACPI_RFK_RADIO_ON)
4114 status = TP_ACPI_WANCARD_RADIOSSW; 4122 status = TP_ACPI_WANCARD_RADIOSSW
4123 | TP_ACPI_WANCARD_RESUMECTRL;
4115 else 4124 else
4116 status = 0; 4125 status = 0;
4117 4126
@@ -4236,9 +4245,9 @@ static int __init wan_init(struct ibm_init_struct *iibm)
4236} 4245}
4237 4246
4238/* procfs -------------------------------------------------------------- */ 4247/* procfs -------------------------------------------------------------- */
4239static int wan_read(char *p) 4248static int wan_read(struct seq_file *m)
4240{ 4249{
4241 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p); 4250 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);
4242} 4251}
4243 4252
4244static int wan_write(char *buf) 4253static int wan_write(char *buf)
@@ -4251,7 +4260,6 @@ static struct ibm_struct wan_driver_data = {
4251 .read = wan_read, 4260 .read = wan_read,
4252 .write = wan_write, 4261 .write = wan_write,
4253 .exit = wan_exit, 4262 .exit = wan_exit,
4254 .suspend = wan_suspend,
4255 .shutdown = wan_shutdown, 4263 .shutdown = wan_shutdown,
4256}; 4264};
4257 4265
@@ -4614,16 +4622,19 @@ static int video_expand_toggle(void)
4614 /* not reached */ 4622 /* not reached */
4615} 4623}
4616 4624
4617static int video_read(char *p) 4625static int video_read(struct seq_file *m)
4618{ 4626{
4619 int status, autosw; 4627 int status, autosw;
4620 int len = 0;
4621 4628
4622 if (video_supported == TPACPI_VIDEO_NONE) { 4629 if (video_supported == TPACPI_VIDEO_NONE) {
4623 len += sprintf(p + len, "status:\t\tnot supported\n"); 4630 seq_printf(m, "status:\t\tnot supported\n");
4624 return len; 4631 return 0;
4625 } 4632 }
4626 4633
4634 /* Even reads can crash X.org, so... */
4635 if (!capable(CAP_SYS_ADMIN))
4636 return -EPERM;
4637
4627 status = video_outputsw_get(); 4638 status = video_outputsw_get();
4628 if (status < 0) 4639 if (status < 0)
4629 return status; 4640 return status;
@@ -4632,20 +4643,20 @@ static int video_read(char *p)
4632 if (autosw < 0) 4643 if (autosw < 0)
4633 return autosw; 4644 return autosw;
4634 4645
4635 len += sprintf(p + len, "status:\t\tsupported\n"); 4646 seq_printf(m, "status:\t\tsupported\n");
4636 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 4647 seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0));
4637 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 4648 seq_printf(m, "crt:\t\t%s\n", enabled(status, 1));
4638 if (video_supported == TPACPI_VIDEO_NEW) 4649 if (video_supported == TPACPI_VIDEO_NEW)
4639 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 4650 seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3));
4640 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 4651 seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0));
4641 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 4652 seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");
4642 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 4653 seq_printf(m, "commands:\tcrt_enable, crt_disable\n");
4643 if (video_supported == TPACPI_VIDEO_NEW) 4654 if (video_supported == TPACPI_VIDEO_NEW)
4644 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 4655 seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");
4645 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 4656 seq_printf(m, "commands:\tauto_enable, auto_disable\n");
4646 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 4657 seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");
4647 4658
4648 return len; 4659 return 0;
4649} 4660}
4650 4661
4651static int video_write(char *buf) 4662static int video_write(char *buf)
@@ -4657,6 +4668,10 @@ static int video_write(char *buf)
4657 if (video_supported == TPACPI_VIDEO_NONE) 4668 if (video_supported == TPACPI_VIDEO_NONE)
4658 return -ENODEV; 4669 return -ENODEV;
4659 4670
4671 /* Even reads can crash X.org, let alone writes... */
4672 if (!capable(CAP_SYS_ADMIN))
4673 return -EPERM;
4674
4660 enable = 0; 4675 enable = 0;
4661 disable = 0; 4676 disable = 0;
4662 4677
@@ -4837,25 +4852,24 @@ static void light_exit(void)
4837 flush_workqueue(tpacpi_wq); 4852 flush_workqueue(tpacpi_wq);
4838} 4853}
4839 4854
4840static int light_read(char *p) 4855static int light_read(struct seq_file *m)
4841{ 4856{
4842 int len = 0;
4843 int status; 4857 int status;
4844 4858
4845 if (!tp_features.light) { 4859 if (!tp_features.light) {
4846 len += sprintf(p + len, "status:\t\tnot supported\n"); 4860 seq_printf(m, "status:\t\tnot supported\n");
4847 } else if (!tp_features.light_status) { 4861 } else if (!tp_features.light_status) {
4848 len += sprintf(p + len, "status:\t\tunknown\n"); 4862 seq_printf(m, "status:\t\tunknown\n");
4849 len += sprintf(p + len, "commands:\ton, off\n"); 4863 seq_printf(m, "commands:\ton, off\n");
4850 } else { 4864 } else {
4851 status = light_get_status(); 4865 status = light_get_status();
4852 if (status < 0) 4866 if (status < 0)
4853 return status; 4867 return status;
4854 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 4868 seq_printf(m, "status:\t\t%s\n", onoff(status, 0));
4855 len += sprintf(p + len, "commands:\ton, off\n"); 4869 seq_printf(m, "commands:\ton, off\n");
4856 } 4870 }
4857 4871
4858 return len; 4872 return 0;
4859} 4873}
4860 4874
4861static int light_write(char *buf) 4875static int light_write(char *buf)
@@ -4933,20 +4947,18 @@ static void cmos_exit(void)
4933 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 4947 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4934} 4948}
4935 4949
4936static int cmos_read(char *p) 4950static int cmos_read(struct seq_file *m)
4937{ 4951{
4938 int len = 0;
4939
4940 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 4952 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
4941 R30, R31, T20-22, X20-21 */ 4953 R30, R31, T20-22, X20-21 */
4942 if (!cmos_handle) 4954 if (!cmos_handle)
4943 len += sprintf(p + len, "status:\t\tnot supported\n"); 4955 seq_printf(m, "status:\t\tnot supported\n");
4944 else { 4956 else {
4945 len += sprintf(p + len, "status:\t\tsupported\n"); 4957 seq_printf(m, "status:\t\tsupported\n");
4946 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n"); 4958 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");
4947 } 4959 }
4948 4960
4949 return len; 4961 return 0;
4950} 4962}
4951 4963
4952static int cmos_write(char *buf) 4964static int cmos_write(char *buf)
@@ -5321,15 +5333,13 @@ static int __init led_init(struct ibm_init_struct *iibm)
5321 ((s) == TPACPI_LED_OFF ? "off" : \ 5333 ((s) == TPACPI_LED_OFF ? "off" : \
5322 ((s) == TPACPI_LED_ON ? "on" : "blinking")) 5334 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
5323 5335
5324static int led_read(char *p) 5336static int led_read(struct seq_file *m)
5325{ 5337{
5326 int len = 0;
5327
5328 if (!led_supported) { 5338 if (!led_supported) {
5329 len += sprintf(p + len, "status:\t\tnot supported\n"); 5339 seq_printf(m, "status:\t\tnot supported\n");
5330 return len; 5340 return 0;
5331 } 5341 }
5332 len += sprintf(p + len, "status:\t\tsupported\n"); 5342 seq_printf(m, "status:\t\tsupported\n");
5333 5343
5334 if (led_supported == TPACPI_LED_570) { 5344 if (led_supported == TPACPI_LED_570) {
5335 /* 570 */ 5345 /* 570 */
@@ -5338,15 +5348,15 @@ static int led_read(char *p)
5338 status = led_get_status(i); 5348 status = led_get_status(i);
5339 if (status < 0) 5349 if (status < 0)
5340 return -EIO; 5350 return -EIO;
5341 len += sprintf(p + len, "%d:\t\t%s\n", 5351 seq_printf(m, "%d:\t\t%s\n",
5342 i, str_led_status(status)); 5352 i, str_led_status(status));
5343 } 5353 }
5344 } 5354 }
5345 5355
5346 len += sprintf(p + len, "commands:\t" 5356 seq_printf(m, "commands:\t"
5347 "<led> on, <led> off, <led> blink (<led> is 0-15)\n"); 5357 "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
5348 5358
5349 return len; 5359 return 0;
5350} 5360}
5351 5361
5352static int led_write(char *buf) 5362static int led_write(char *buf)
@@ -5419,18 +5429,16 @@ static int __init beep_init(struct ibm_init_struct *iibm)
5419 return (beep_handle)? 0 : 1; 5429 return (beep_handle)? 0 : 1;
5420} 5430}
5421 5431
5422static int beep_read(char *p) 5432static int beep_read(struct seq_file *m)
5423{ 5433{
5424 int len = 0;
5425
5426 if (!beep_handle) 5434 if (!beep_handle)
5427 len += sprintf(p + len, "status:\t\tnot supported\n"); 5435 seq_printf(m, "status:\t\tnot supported\n");
5428 else { 5436 else {
5429 len += sprintf(p + len, "status:\t\tsupported\n"); 5437 seq_printf(m, "status:\t\tsupported\n");
5430 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n"); 5438 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");
5431 } 5439 }
5432 5440
5433 return len; 5441 return 0;
5434} 5442}
5435 5443
5436static int beep_write(char *buf) 5444static int beep_write(char *buf)
@@ -5483,8 +5491,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */
5483 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ 5491 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */
5484 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ 5492 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */
5485 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ 5493 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */
5494
5495 TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */
5486}; 5496};
5487 5497
5498
5488#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ 5499#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
5489struct ibm_thermal_sensors_struct { 5500struct ibm_thermal_sensors_struct {
5490 s32 temp[TPACPI_MAX_THERMAL_SENSORS]; 5501 s32 temp[TPACPI_MAX_THERMAL_SENSORS];
@@ -5574,6 +5585,28 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
5574 return n; 5585 return n;
5575} 5586}
5576 5587
5588static void thermal_dump_all_sensors(void)
5589{
5590 int n, i;
5591 struct ibm_thermal_sensors_struct t;
5592
5593 n = thermal_get_sensors(&t);
5594 if (n <= 0)
5595 return;
5596
5597 printk(TPACPI_NOTICE
5598 "temperatures (Celsius):");
5599
5600 for (i = 0; i < n; i++) {
5601 if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
5602 printk(KERN_CONT " %d", (int)(t.temp[i] / 1000));
5603 else
5604 printk(KERN_CONT " N/A");
5605 }
5606
5607 printk(KERN_CONT "\n");
5608}
5609
5577/* sysfs temp##_input -------------------------------------------------- */ 5610/* sysfs temp##_input -------------------------------------------------- */
5578 5611
5579static ssize_t thermal_temp_input_show(struct device *dev, 5612static ssize_t thermal_temp_input_show(struct device *dev,
@@ -5589,7 +5622,7 @@ static ssize_t thermal_temp_input_show(struct device *dev,
5589 res = thermal_get_sensor(idx, &value); 5622 res = thermal_get_sensor(idx, &value);
5590 if (res) 5623 if (res)
5591 return res; 5624 return res;
5592 if (value == TP_EC_THERMAL_TMP_NA * 1000) 5625 if (value == TPACPI_THERMAL_SENSOR_NA)
5593 return -ENXIO; 5626 return -ENXIO;
5594 5627
5595 return snprintf(buf, PAGE_SIZE, "%d\n", value); 5628 return snprintf(buf, PAGE_SIZE, "%d\n", value);
@@ -5758,7 +5791,7 @@ static void thermal_exit(void)
5758 case TPACPI_THERMAL_ACPI_TMP07: 5791 case TPACPI_THERMAL_ACPI_TMP07:
5759 case TPACPI_THERMAL_ACPI_UPDT: 5792 case TPACPI_THERMAL_ACPI_UPDT:
5760 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 5793 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5761 &thermal_temp_input16_group); 5794 &thermal_temp_input8_group);
5762 break; 5795 break;
5763 case TPACPI_THERMAL_NONE: 5796 case TPACPI_THERMAL_NONE:
5764 default: 5797 default:
@@ -5766,9 +5799,8 @@ static void thermal_exit(void)
5766 } 5799 }
5767} 5800}
5768 5801
5769static int thermal_read(char *p) 5802static int thermal_read(struct seq_file *m)
5770{ 5803{
5771 int len = 0;
5772 int n, i; 5804 int n, i;
5773 struct ibm_thermal_sensors_struct t; 5805 struct ibm_thermal_sensors_struct t;
5774 5806
@@ -5776,16 +5808,16 @@ static int thermal_read(char *p)
5776 if (unlikely(n < 0)) 5808 if (unlikely(n < 0))
5777 return n; 5809 return n;
5778 5810
5779 len += sprintf(p + len, "temperatures:\t"); 5811 seq_printf(m, "temperatures:\t");
5780 5812
5781 if (n > 0) { 5813 if (n > 0) {
5782 for (i = 0; i < (n - 1); i++) 5814 for (i = 0; i < (n - 1); i++)
5783 len += sprintf(p + len, "%d ", t.temp[i] / 1000); 5815 seq_printf(m, "%d ", t.temp[i] / 1000);
5784 len += sprintf(p + len, "%d\n", t.temp[i] / 1000); 5816 seq_printf(m, "%d\n", t.temp[i] / 1000);
5785 } else 5817 } else
5786 len += sprintf(p + len, "not supported\n"); 5818 seq_printf(m, "not supported\n");
5787 5819
5788 return len; 5820 return 0;
5789} 5821}
5790 5822
5791static struct ibm_struct thermal_driver_data = { 5823static struct ibm_struct thermal_driver_data = {
@@ -5800,39 +5832,38 @@ static struct ibm_struct thermal_driver_data = {
5800 5832
5801static u8 ecdump_regs[256]; 5833static u8 ecdump_regs[256];
5802 5834
5803static int ecdump_read(char *p) 5835static int ecdump_read(struct seq_file *m)
5804{ 5836{
5805 int len = 0;
5806 int i, j; 5837 int i, j;
5807 u8 v; 5838 u8 v;
5808 5839
5809 len += sprintf(p + len, "EC " 5840 seq_printf(m, "EC "
5810 " +00 +01 +02 +03 +04 +05 +06 +07" 5841 " +00 +01 +02 +03 +04 +05 +06 +07"
5811 " +08 +09 +0a +0b +0c +0d +0e +0f\n"); 5842 " +08 +09 +0a +0b +0c +0d +0e +0f\n");
5812 for (i = 0; i < 256; i += 16) { 5843 for (i = 0; i < 256; i += 16) {
5813 len += sprintf(p + len, "EC 0x%02x:", i); 5844 seq_printf(m, "EC 0x%02x:", i);
5814 for (j = 0; j < 16; j++) { 5845 for (j = 0; j < 16; j++) {
5815 if (!acpi_ec_read(i + j, &v)) 5846 if (!acpi_ec_read(i + j, &v))
5816 break; 5847 break;
5817 if (v != ecdump_regs[i + j]) 5848 if (v != ecdump_regs[i + j])
5818 len += sprintf(p + len, " *%02x", v); 5849 seq_printf(m, " *%02x", v);
5819 else 5850 else
5820 len += sprintf(p + len, " %02x", v); 5851 seq_printf(m, " %02x", v);
5821 ecdump_regs[i + j] = v; 5852 ecdump_regs[i + j] = v;
5822 } 5853 }
5823 len += sprintf(p + len, "\n"); 5854 seq_putc(m, '\n');
5824 if (j != 16) 5855 if (j != 16)
5825 break; 5856 break;
5826 } 5857 }
5827 5858
5828 /* These are way too dangerous to advertise openly... */ 5859 /* These are way too dangerous to advertise openly... */
5829#if 0 5860#if 0
5830 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>" 5861 seq_printf(m, "commands:\t0x<offset> 0x<value>"
5831 " (<offset> is 00-ff, <value> is 00-ff)\n"); 5862 " (<offset> is 00-ff, <value> is 00-ff)\n");
5832 len += sprintf(p + len, "commands:\t0x<offset> <value> " 5863 seq_printf(m, "commands:\t0x<offset> <value> "
5833 " (<offset> is 00-ff, <value> is 0-255)\n"); 5864 " (<offset> is 00-ff, <value> is 0-255)\n");
5834#endif 5865#endif
5835 return len; 5866 return 0;
5836} 5867}
5837 5868
5838static int ecdump_write(char *buf) 5869static int ecdump_write(char *buf)
@@ -6095,6 +6126,12 @@ static int brightness_get(struct backlight_device *bd)
6095 return status & TP_EC_BACKLIGHT_LVLMSK; 6126 return status & TP_EC_BACKLIGHT_LVLMSK;
6096} 6127}
6097 6128
6129static void tpacpi_brightness_notify_change(void)
6130{
6131 backlight_force_update(ibm_backlight_device,
6132 BACKLIGHT_UPDATE_HOTKEY);
6133}
6134
6098static struct backlight_ops ibm_backlight_data = { 6135static struct backlight_ops ibm_backlight_data = {
6099 .get_brightness = brightness_get, 6136 .get_brightness = brightness_get,
6100 .update_status = brightness_update_status, 6137 .update_status = brightness_update_status,
@@ -6116,15 +6153,15 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6116 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ 6153 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
6117 6154
6118 /* Models with ATI GPUs that can use ECNVRAM */ 6155 /* Models with ATI GPUs that can use ECNVRAM */
6119 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), 6156 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */
6120 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 6157 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6121 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 6158 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */
6122 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 6159 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6123 6160
6124 /* Models with Intel Extreme Graphics 2 */ 6161 /* Models with Intel Extreme Graphics 2 */
6125 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), 6162 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */
6126 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 6163 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6127 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 6164 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6128 6165
6129 /* Models with Intel GMA900 */ 6166 /* Models with Intel GMA900 */
6130 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ 6167 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
@@ -6134,6 +6171,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6134 6171
6135static int __init brightness_init(struct ibm_init_struct *iibm) 6172static int __init brightness_init(struct ibm_init_struct *iibm)
6136{ 6173{
6174 struct backlight_properties props;
6137 int b; 6175 int b;
6138 unsigned long quirks; 6176 unsigned long quirks;
6139 6177
@@ -6223,9 +6261,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6223 printk(TPACPI_INFO 6261 printk(TPACPI_INFO
6224 "detected a 16-level brightness capable ThinkPad\n"); 6262 "detected a 16-level brightness capable ThinkPad\n");
6225 6263
6226 ibm_backlight_device = backlight_device_register( 6264 memset(&props, 0, sizeof(struct backlight_properties));
6227 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 6265 props.max_brightness = (tp_features.bright_16levels) ? 15 : 7;
6228 &ibm_backlight_data); 6266 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
6267 NULL, NULL,
6268 &ibm_backlight_data,
6269 &props);
6229 if (IS_ERR(ibm_backlight_device)) { 6270 if (IS_ERR(ibm_backlight_device)) {
6230 int rc = PTR_ERR(ibm_backlight_device); 6271 int rc = PTR_ERR(ibm_backlight_device);
6231 ibm_backlight_device = NULL; 6272 ibm_backlight_device = NULL;
@@ -6244,11 +6285,15 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6244 "or not on your ThinkPad\n", TPACPI_MAIL); 6285 "or not on your ThinkPad\n", TPACPI_MAIL);
6245 } 6286 }
6246 6287
6247 ibm_backlight_device->props.max_brightness =
6248 (tp_features.bright_16levels)? 15 : 7;
6249 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 6288 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
6250 backlight_update_status(ibm_backlight_device); 6289 backlight_update_status(ibm_backlight_device);
6251 6290
6291 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6292 "brightness: registering brightness hotkeys "
6293 "as change notification\n");
6294 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6295 | TP_ACPI_HKEY_BRGHTUP_MASK
6296 | TP_ACPI_HKEY_BRGHTDWN_MASK);;
6252 return 0; 6297 return 0;
6253} 6298}
6254 6299
@@ -6273,23 +6318,22 @@ static void brightness_exit(void)
6273 tpacpi_brightness_checkpoint_nvram(); 6318 tpacpi_brightness_checkpoint_nvram();
6274} 6319}
6275 6320
6276static int brightness_read(char *p) 6321static int brightness_read(struct seq_file *m)
6277{ 6322{
6278 int len = 0;
6279 int level; 6323 int level;
6280 6324
6281 level = brightness_get(NULL); 6325 level = brightness_get(NULL);
6282 if (level < 0) { 6326 if (level < 0) {
6283 len += sprintf(p + len, "level:\t\tunreadable\n"); 6327 seq_printf(m, "level:\t\tunreadable\n");
6284 } else { 6328 } else {
6285 len += sprintf(p + len, "level:\t\t%d\n", level); 6329 seq_printf(m, "level:\t\t%d\n", level);
6286 len += sprintf(p + len, "commands:\tup, down\n"); 6330 seq_printf(m, "commands:\tup, down\n");
6287 len += sprintf(p + len, "commands:\tlevel <level>" 6331 seq_printf(m, "commands:\tlevel <level>"
6288 " (<level> is 0-%d)\n", 6332 " (<level> is 0-%d)\n",
6289 (tp_features.bright_16levels) ? 15 : 7); 6333 (tp_features.bright_16levels) ? 15 : 7);
6290 } 6334 }
6291 6335
6292 return len; 6336 return 0;
6293} 6337}
6294 6338
6295static int brightness_write(char *buf) 6339static int brightness_write(char *buf)
@@ -6325,6 +6369,9 @@ static int brightness_write(char *buf)
6325 * Doing it this way makes the syscall restartable in case of EINTR 6369 * Doing it this way makes the syscall restartable in case of EINTR
6326 */ 6370 */
6327 rc = brightness_set(level); 6371 rc = brightness_set(level);
6372 if (!rc && ibm_backlight_device)
6373 backlight_force_update(ibm_backlight_device,
6374 BACKLIGHT_UPDATE_SYSFS);
6328 return (rc == -EINTR)? -ERESTARTSYS : rc; 6375 return (rc == -EINTR)? -ERESTARTSYS : rc;
6329} 6376}
6330 6377
@@ -6341,101 +6388,704 @@ static struct ibm_struct brightness_driver_data = {
6341 * Volume subdriver 6388 * Volume subdriver
6342 */ 6389 */
6343 6390
6344static int volume_offset = 0x30; 6391/*
6392 * IBM ThinkPads have a simple volume controller with MUTE gating.
6393 * Very early Lenovo ThinkPads follow the IBM ThinkPad spec.
6394 *
6395 * Since the *61 series (and probably also the later *60 series), Lenovo
6396 * ThinkPads only implement the MUTE gate.
6397 *
6398 * EC register 0x30
6399 * Bit 6: MUTE (1 mutes sound)
6400 * Bit 3-0: Volume
6401 * Other bits should be zero as far as we know.
6402 *
6403 * This is also stored in CMOS NVRAM, byte 0x60, bit 6 (MUTE), and
6404 * bits 3-0 (volume). Other bits in NVRAM may have other functions,
6405 * such as bit 7 which is used to detect repeated presses of MUTE,
6406 * and we leave them unchanged.
6407 */
6408
6409#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
6410
6411#define TPACPI_ALSA_DRVNAME "ThinkPad EC"
6412#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
6413#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
6345 6414
6346static int volume_read(char *p) 6415static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
6416static char *alsa_id = "ThinkPadEC";
6417static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
6418
6419struct tpacpi_alsa_data {
6420 struct snd_card *card;
6421 struct snd_ctl_elem_id *ctl_mute_id;
6422 struct snd_ctl_elem_id *ctl_vol_id;
6423};
6424
6425static struct snd_card *alsa_card;
6426
6427enum {
6428 TP_EC_AUDIO = 0x30,
6429
6430 /* TP_EC_AUDIO bits */
6431 TP_EC_AUDIO_MUTESW = 6,
6432
6433 /* TP_EC_AUDIO bitmasks */
6434 TP_EC_AUDIO_LVL_MSK = 0x0F,
6435 TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),
6436
6437 /* Maximum volume */
6438 TP_EC_VOLUME_MAX = 14,
6439};
6440
6441enum tpacpi_volume_access_mode {
6442 TPACPI_VOL_MODE_AUTO = 0, /* Not implemented yet */
6443 TPACPI_VOL_MODE_EC, /* Pure EC control */
6444 TPACPI_VOL_MODE_UCMS_STEP, /* UCMS step-based control: N/A */
6445 TPACPI_VOL_MODE_ECNVRAM, /* EC control w/ NVRAM store */
6446 TPACPI_VOL_MODE_MAX
6447};
6448
6449enum tpacpi_volume_capabilities {
6450 TPACPI_VOL_CAP_AUTO = 0, /* Use white/blacklist */
6451 TPACPI_VOL_CAP_VOLMUTE, /* Output vol and mute */
6452 TPACPI_VOL_CAP_MUTEONLY, /* Output mute only */
6453 TPACPI_VOL_CAP_MAX
6454};
6455
6456static enum tpacpi_volume_access_mode volume_mode =
6457 TPACPI_VOL_MODE_MAX;
6458
6459static enum tpacpi_volume_capabilities volume_capabilities;
6460static int volume_control_allowed;
6461
6462/*
6463 * Used to syncronize writers to TP_EC_AUDIO and
6464 * TP_NVRAM_ADDR_MIXER, as we need to do read-modify-write
6465 */
6466static struct mutex volume_mutex;
6467
6468static void tpacpi_volume_checkpoint_nvram(void)
6347{ 6469{
6348 int len = 0; 6470 u8 lec = 0;
6349 u8 level; 6471 u8 b_nvram;
6472 u8 ec_mask;
6473
6474 if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
6475 return;
6476 if (!volume_control_allowed)
6477 return;
6478
6479 vdbg_printk(TPACPI_DBG_MIXER,
6480 "trying to checkpoint mixer state to NVRAM...\n");
6481
6482 if (tp_features.mixer_no_level_control)
6483 ec_mask = TP_EC_AUDIO_MUTESW_MSK;
6484 else
6485 ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;
6486
6487 if (mutex_lock_killable(&volume_mutex) < 0)
6488 return;
6350 6489
6351 if (!acpi_ec_read(volume_offset, &level)) { 6490 if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
6352 len += sprintf(p + len, "level:\t\tunreadable\n"); 6491 goto unlock;
6492 lec &= ec_mask;
6493 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
6494
6495 if (lec != (b_nvram & ec_mask)) {
6496 /* NVRAM needs update */
6497 b_nvram &= ~ec_mask;
6498 b_nvram |= lec;
6499 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
6500 dbg_printk(TPACPI_DBG_MIXER,
6501 "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
6502 (unsigned int) lec, (unsigned int) b_nvram);
6353 } else { 6503 } else {
6354 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); 6504 vdbg_printk(TPACPI_DBG_MIXER,
6355 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); 6505 "NVRAM mixer status already is 0x%02x (0x%02x)\n",
6356 len += sprintf(p + len, "commands:\tup, down, mute\n"); 6506 (unsigned int) lec, (unsigned int) b_nvram);
6357 len += sprintf(p + len, "commands:\tlevel <level>"
6358 " (<level> is 0-15)\n");
6359 } 6507 }
6360 6508
6361 return len; 6509unlock:
6510 mutex_unlock(&volume_mutex);
6362} 6511}
6363 6512
6364static int volume_write(char *buf) 6513static int volume_get_status_ec(u8 *status)
6365{ 6514{
6366 int cmos_cmd, inc, i; 6515 u8 s;
6367 u8 level, mute;
6368 int new_level, new_mute;
6369 char *cmd;
6370 6516
6371 while ((cmd = next_cmd(&buf))) { 6517 if (!acpi_ec_read(TP_EC_AUDIO, &s))
6372 if (!acpi_ec_read(volume_offset, &level)) 6518 return -EIO;
6373 return -EIO;
6374 new_mute = mute = level & 0x40;
6375 new_level = level = level & 0xf;
6376 6519
6377 if (strlencmp(cmd, "up") == 0) { 6520 *status = s;
6378 if (mute)
6379 new_mute = 0;
6380 else
6381 new_level = level == 15 ? 15 : level + 1;
6382 } else if (strlencmp(cmd, "down") == 0) {
6383 if (mute)
6384 new_mute = 0;
6385 else
6386 new_level = level == 0 ? 0 : level - 1;
6387 } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
6388 new_level >= 0 && new_level <= 15) {
6389 /* new_level set */
6390 } else if (strlencmp(cmd, "mute") == 0) {
6391 new_mute = 0x40;
6392 } else
6393 return -EINVAL;
6394 6521
6395 if (new_level != level) { 6522 dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);
6396 /* mute doesn't change */
6397 6523
6398 cmos_cmd = (new_level > level) ? 6524 return 0;
6399 TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN; 6525}
6400 inc = new_level > level ? 1 : -1;
6401 6526
6402 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) || 6527static int volume_get_status(u8 *status)
6403 !acpi_ec_write(volume_offset, level))) 6528{
6404 return -EIO; 6529 return volume_get_status_ec(status);
6530}
6405 6531
6406 for (i = level; i != new_level; i += inc) 6532static int volume_set_status_ec(const u8 status)
6407 if (issue_thinkpad_cmos_command(cmos_cmd) || 6533{
6408 !acpi_ec_write(volume_offset, i + inc)) 6534 if (!acpi_ec_write(TP_EC_AUDIO, status))
6409 return -EIO; 6535 return -EIO;
6410 6536
6411 if (mute && 6537 dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
6412 (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) || 6538
6413 !acpi_ec_write(volume_offset, new_level + mute))) { 6539 return 0;
6414 return -EIO; 6540}
6415 } 6541
6542static int volume_set_status(const u8 status)
6543{
6544 return volume_set_status_ec(status);
6545}
6546
6547/* returns < 0 on error, 0 on no change, 1 on change */
6548static int __volume_set_mute_ec(const bool mute)
6549{
6550 int rc;
6551 u8 s, n;
6552
6553 if (mutex_lock_killable(&volume_mutex) < 0)
6554 return -EINTR;
6555
6556 rc = volume_get_status_ec(&s);
6557 if (rc)
6558 goto unlock;
6559
6560 n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
6561 s & ~TP_EC_AUDIO_MUTESW_MSK;
6562
6563 if (n != s) {
6564 rc = volume_set_status_ec(n);
6565 if (!rc)
6566 rc = 1;
6567 }
6568
6569unlock:
6570 mutex_unlock(&volume_mutex);
6571 return rc;
6572}
6573
6574static int volume_alsa_set_mute(const bool mute)
6575{
6576 dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
6577 (mute) ? "" : "un");
6578 return __volume_set_mute_ec(mute);
6579}
6580
6581static int volume_set_mute(const bool mute)
6582{
6583 int rc;
6584
6585 dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
6586 (mute) ? "" : "un");
6587
6588 rc = __volume_set_mute_ec(mute);
6589 return (rc < 0) ? rc : 0;
6590}
6591
6592/* returns < 0 on error, 0 on no change, 1 on change */
6593static int __volume_set_volume_ec(const u8 vol)
6594{
6595 int rc;
6596 u8 s, n;
6597
6598 if (vol > TP_EC_VOLUME_MAX)
6599 return -EINVAL;
6600
6601 if (mutex_lock_killable(&volume_mutex) < 0)
6602 return -EINTR;
6603
6604 rc = volume_get_status_ec(&s);
6605 if (rc)
6606 goto unlock;
6607
6608 n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
6609
6610 if (n != s) {
6611 rc = volume_set_status_ec(n);
6612 if (!rc)
6613 rc = 1;
6614 }
6615
6616unlock:
6617 mutex_unlock(&volume_mutex);
6618 return rc;
6619}
6620
6621static int volume_alsa_set_volume(const u8 vol)
6622{
6623 dbg_printk(TPACPI_DBG_MIXER,
6624 "ALSA: trying to set volume level to %hu\n", vol);
6625 return __volume_set_volume_ec(vol);
6626}
6627
6628static void volume_alsa_notify_change(void)
6629{
6630 struct tpacpi_alsa_data *d;
6631
6632 if (alsa_card && alsa_card->private_data) {
6633 d = alsa_card->private_data;
6634 if (d->ctl_mute_id)
6635 snd_ctl_notify(alsa_card,
6636 SNDRV_CTL_EVENT_MASK_VALUE,
6637 d->ctl_mute_id);
6638 if (d->ctl_vol_id)
6639 snd_ctl_notify(alsa_card,
6640 SNDRV_CTL_EVENT_MASK_VALUE,
6641 d->ctl_vol_id);
6642 }
6643}
6644
6645static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
6646 struct snd_ctl_elem_info *uinfo)
6647{
6648 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
6649 uinfo->count = 1;
6650 uinfo->value.integer.min = 0;
6651 uinfo->value.integer.max = TP_EC_VOLUME_MAX;
6652 return 0;
6653}
6654
6655static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
6656 struct snd_ctl_elem_value *ucontrol)
6657{
6658 u8 s;
6659 int rc;
6660
6661 rc = volume_get_status(&s);
6662 if (rc < 0)
6663 return rc;
6664
6665 ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;
6666 return 0;
6667}
6668
6669static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
6670 struct snd_ctl_elem_value *ucontrol)
6671{
6672 return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
6673}
6674
6675#define volume_alsa_mute_info snd_ctl_boolean_mono_info
6676
6677static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
6678 struct snd_ctl_elem_value *ucontrol)
6679{
6680 u8 s;
6681 int rc;
6682
6683 rc = volume_get_status(&s);
6684 if (rc < 0)
6685 return rc;
6686
6687 ucontrol->value.integer.value[0] =
6688 (s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;
6689 return 0;
6690}
6691
6692static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6693 struct snd_ctl_elem_value *ucontrol)
6694{
6695 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
6696}
6697
6698static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
6699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6700 .name = "Console Playback Volume",
6701 .index = 0,
6702 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6703 .info = volume_alsa_vol_info,
6704 .get = volume_alsa_vol_get,
6705};
6706
6707static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = {
6708 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6709 .name = "Console Playback Switch",
6710 .index = 0,
6711 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6712 .info = volume_alsa_mute_info,
6713 .get = volume_alsa_mute_get,
6714};
6715
6716static void volume_suspend(pm_message_t state)
6717{
6718 tpacpi_volume_checkpoint_nvram();
6719}
6720
6721static void volume_resume(void)
6722{
6723 volume_alsa_notify_change();
6724}
6725
6726static void volume_shutdown(void)
6727{
6728 tpacpi_volume_checkpoint_nvram();
6729}
6730
6731static void volume_exit(void)
6732{
6733 if (alsa_card) {
6734 snd_card_free(alsa_card);
6735 alsa_card = NULL;
6736 }
6737
6738 tpacpi_volume_checkpoint_nvram();
6739}
6740
6741static int __init volume_create_alsa_mixer(void)
6742{
6743 struct snd_card *card;
6744 struct tpacpi_alsa_data *data;
6745 struct snd_kcontrol *ctl_vol;
6746 struct snd_kcontrol *ctl_mute;
6747 int rc;
6748
6749 rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
6750 sizeof(struct tpacpi_alsa_data), &card);
6751 if (rc < 0 || !card) {
6752 printk(TPACPI_ERR
6753 "Failed to create ALSA card structures: %d\n", rc);
6754 return 1;
6755 }
6756
6757 BUG_ON(!card->private_data);
6758 data = card->private_data;
6759 data->card = card;
6760
6761 strlcpy(card->driver, TPACPI_ALSA_DRVNAME,
6762 sizeof(card->driver));
6763 strlcpy(card->shortname, TPACPI_ALSA_SHRTNAME,
6764 sizeof(card->shortname));
6765 snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",
6766 (thinkpad_id.ec_version_str) ?
6767 thinkpad_id.ec_version_str : "(unknown)");
6768 snprintf(card->longname, sizeof(card->longname),
6769 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,
6770 (thinkpad_id.ec_version_str) ?
6771 thinkpad_id.ec_version_str : "unknown");
6772
6773 if (volume_control_allowed) {
6774 volume_alsa_control_vol.put = volume_alsa_vol_put;
6775 volume_alsa_control_vol.access =
6776 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6777
6778 volume_alsa_control_mute.put = volume_alsa_mute_put;
6779 volume_alsa_control_mute.access =
6780 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6781 }
6782
6783 if (!tp_features.mixer_no_level_control) {
6784 ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
6785 rc = snd_ctl_add(card, ctl_vol);
6786 if (rc < 0) {
6787 printk(TPACPI_ERR
6788 "Failed to create ALSA volume control: %d\n",
6789 rc);
6790 goto err_exit;
6416 } 6791 }
6792 data->ctl_vol_id = &ctl_vol->id;
6793 }
6417 6794
6418 if (new_mute != mute) { 6795 ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
6419 /* level doesn't change */ 6796 rc = snd_ctl_add(card, ctl_mute);
6797 if (rc < 0) {
6798 printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n",
6799 rc);
6800 goto err_exit;
6801 }
6802 data->ctl_mute_id = &ctl_mute->id;
6420 6803
6421 cmos_cmd = (new_mute) ? 6804 snd_card_set_dev(card, &tpacpi_pdev->dev);
6422 TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP; 6805 rc = snd_card_register(card);
6806 if (rc < 0) {
6807 printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc);
6808 goto err_exit;
6809 }
6423 6810
6424 if (issue_thinkpad_cmos_command(cmos_cmd) || 6811 alsa_card = card;
6425 !acpi_ec_write(volume_offset, level + new_mute)) 6812 return 0;
6426 return -EIO; 6813
6814err_exit:
6815 snd_card_free(card);
6816 return 1;
6817}
6818
6819#define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */
6820#define TPACPI_VOL_Q_LEVEL 0x0002 /* Volume control available */
6821
6822static const struct tpacpi_quirk volume_quirk_table[] __initconst = {
6823 /* Whitelist volume level on all IBM by default */
6824 { .vendor = PCI_VENDOR_ID_IBM,
6825 .bios = TPACPI_MATCH_ANY,
6826 .ec = TPACPI_MATCH_ANY,
6827 .quirks = TPACPI_VOL_Q_LEVEL },
6828
6829 /* Lenovo models with volume control (needs confirmation) */
6830 TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL), /* R60/i */
6831 TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL), /* R60e/i */
6832 TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL), /* T60/p */
6833 TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL), /* X60/s */
6834 TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL), /* X60t */
6835 TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL), /* Z60 */
6836 TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL), /* Z61 */
6837
6838 /* Whitelist mute-only on all Lenovo by default */
6839 { .vendor = PCI_VENDOR_ID_LENOVO,
6840 .bios = TPACPI_MATCH_ANY,
6841 .ec = TPACPI_MATCH_ANY,
6842 .quirks = TPACPI_VOL_Q_MUTEONLY }
6843};
6844
6845static int __init volume_init(struct ibm_init_struct *iibm)
6846{
6847 unsigned long quirks;
6848 int rc;
6849
6850 vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");
6851
6852 mutex_init(&volume_mutex);
6853
6854 /*
6855 * Check for module parameter bogosity, note that we
6856 * init volume_mode to TPACPI_VOL_MODE_MAX in order to be
6857 * able to detect "unspecified"
6858 */
6859 if (volume_mode > TPACPI_VOL_MODE_MAX)
6860 return -EINVAL;
6861
6862 if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
6863 printk(TPACPI_ERR
6864 "UCMS step volume mode not implemented, "
6865 "please contact %s\n", TPACPI_MAIL);
6866 return 1;
6867 }
6868
6869 if (volume_capabilities >= TPACPI_VOL_CAP_MAX)
6870 return -EINVAL;
6871
6872 /*
6873 * The ALSA mixer is our primary interface.
6874 * When disabled, don't install the subdriver at all
6875 */
6876 if (!alsa_enable) {
6877 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6878 "ALSA mixer disabled by parameter, "
6879 "not loading volume subdriver...\n");
6880 return 1;
6881 }
6882
6883 quirks = tpacpi_check_quirks(volume_quirk_table,
6884 ARRAY_SIZE(volume_quirk_table));
6885
6886 switch (volume_capabilities) {
6887 case TPACPI_VOL_CAP_AUTO:
6888 if (quirks & TPACPI_VOL_Q_MUTEONLY)
6889 tp_features.mixer_no_level_control = 1;
6890 else if (quirks & TPACPI_VOL_Q_LEVEL)
6891 tp_features.mixer_no_level_control = 0;
6892 else
6893 return 1; /* no mixer */
6894 break;
6895 case TPACPI_VOL_CAP_VOLMUTE:
6896 tp_features.mixer_no_level_control = 0;
6897 break;
6898 case TPACPI_VOL_CAP_MUTEONLY:
6899 tp_features.mixer_no_level_control = 1;
6900 break;
6901 default:
6902 return 1;
6903 }
6904
6905 if (volume_capabilities != TPACPI_VOL_CAP_AUTO)
6906 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6907 "using user-supplied volume_capabilities=%d\n",
6908 volume_capabilities);
6909
6910 if (volume_mode == TPACPI_VOL_MODE_AUTO ||
6911 volume_mode == TPACPI_VOL_MODE_MAX) {
6912 volume_mode = TPACPI_VOL_MODE_ECNVRAM;
6913
6914 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6915 "driver auto-selected volume_mode=%d\n",
6916 volume_mode);
6917 } else {
6918 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6919 "using user-supplied volume_mode=%d\n",
6920 volume_mode);
6921 }
6922
6923 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6924 "mute is supported, volume control is %s\n",
6925 str_supported(!tp_features.mixer_no_level_control));
6926
6927 rc = volume_create_alsa_mixer();
6928 if (rc) {
6929 printk(TPACPI_ERR
6930 "Could not create the ALSA mixer interface\n");
6931 return rc;
6932 }
6933
6934 printk(TPACPI_INFO
6935 "Console audio control enabled, mode: %s\n",
6936 (volume_control_allowed) ?
6937 "override (read/write)" :
6938 "monitor (read only)");
6939
6940 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6941 "registering volume hotkeys as change notification\n");
6942 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6943 | TP_ACPI_HKEY_VOLUP_MASK
6944 | TP_ACPI_HKEY_VOLDWN_MASK
6945 | TP_ACPI_HKEY_MUTE_MASK);
6946
6947 return 0;
6948}
6949
6950static int volume_read(struct seq_file *m)
6951{
6952 u8 status;
6953
6954 if (volume_get_status(&status) < 0) {
6955 seq_printf(m, "level:\t\tunreadable\n");
6956 } else {
6957 if (tp_features.mixer_no_level_control)
6958 seq_printf(m, "level:\t\tunsupported\n");
6959 else
6960 seq_printf(m, "level:\t\t%d\n",
6961 status & TP_EC_AUDIO_LVL_MSK);
6962
6963 seq_printf(m, "mute:\t\t%s\n",
6964 onoff(status, TP_EC_AUDIO_MUTESW));
6965
6966 if (volume_control_allowed) {
6967 seq_printf(m, "commands:\tunmute, mute\n");
6968 if (!tp_features.mixer_no_level_control) {
6969 seq_printf(m,
6970 "commands:\tup, down\n");
6971 seq_printf(m,
6972 "commands:\tlevel <level>"
6973 " (<level> is 0-%d)\n",
6974 TP_EC_VOLUME_MAX);
6975 }
6427 } 6976 }
6428 } 6977 }
6429 6978
6430 return 0; 6979 return 0;
6431} 6980}
6432 6981
6982static int volume_write(char *buf)
6983{
6984 u8 s;
6985 u8 new_level, new_mute;
6986 int l;
6987 char *cmd;
6988 int rc;
6989
6990 /*
6991 * We do allow volume control at driver startup, so that the
6992 * user can set initial state through the volume=... parameter hack.
6993 */
6994 if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
6995 if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
6996 tp_warned.volume_ctrl_forbidden = 1;
6997 printk(TPACPI_NOTICE
6998 "Console audio control in monitor mode, "
6999 "changes are not allowed.\n");
7000 printk(TPACPI_NOTICE
7001 "Use the volume_control=1 module parameter "
7002 "to enable volume control\n");
7003 }
7004 return -EPERM;
7005 }
7006
7007 rc = volume_get_status(&s);
7008 if (rc < 0)
7009 return rc;
7010
7011 new_level = s & TP_EC_AUDIO_LVL_MSK;
7012 new_mute = s & TP_EC_AUDIO_MUTESW_MSK;
7013
7014 while ((cmd = next_cmd(&buf))) {
7015 if (!tp_features.mixer_no_level_control) {
7016 if (strlencmp(cmd, "up") == 0) {
7017 if (new_mute)
7018 new_mute = 0;
7019 else if (new_level < TP_EC_VOLUME_MAX)
7020 new_level++;
7021 continue;
7022 } else if (strlencmp(cmd, "down") == 0) {
7023 if (new_mute)
7024 new_mute = 0;
7025 else if (new_level > 0)
7026 new_level--;
7027 continue;
7028 } else if (sscanf(cmd, "level %u", &l) == 1 &&
7029 l >= 0 && l <= TP_EC_VOLUME_MAX) {
7030 new_level = l;
7031 continue;
7032 }
7033 }
7034 if (strlencmp(cmd, "mute") == 0)
7035 new_mute = TP_EC_AUDIO_MUTESW_MSK;
7036 else if (strlencmp(cmd, "unmute") == 0)
7037 new_mute = 0;
7038 else
7039 return -EINVAL;
7040 }
7041
7042 if (tp_features.mixer_no_level_control) {
7043 tpacpi_disclose_usertask("procfs volume", "%smute\n",
7044 new_mute ? "" : "un");
7045 rc = volume_set_mute(!!new_mute);
7046 } else {
7047 tpacpi_disclose_usertask("procfs volume",
7048 "%smute and set level to %d\n",
7049 new_mute ? "" : "un", new_level);
7050 rc = volume_set_status(new_mute | new_level);
7051 }
7052 volume_alsa_notify_change();
7053
7054 return (rc == -EINTR) ? -ERESTARTSYS : rc;
7055}
7056
6433static struct ibm_struct volume_driver_data = { 7057static struct ibm_struct volume_driver_data = {
6434 .name = "volume", 7058 .name = "volume",
6435 .read = volume_read, 7059 .read = volume_read,
6436 .write = volume_write, 7060 .write = volume_write,
7061 .exit = volume_exit,
7062 .suspend = volume_suspend,
7063 .resume = volume_resume,
7064 .shutdown = volume_shutdown,
7065};
7066
7067#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
7068
7069#define alsa_card NULL
7070
7071static void inline volume_alsa_notify_change(void)
7072{
7073}
7074
7075static int __init volume_init(struct ibm_init_struct *iibm)
7076{
7077 printk(TPACPI_INFO
7078 "volume: disabled as there is no ALSA support in this kernel\n");
7079
7080 return 1;
7081}
7082
7083static struct ibm_struct volume_driver_data = {
7084 .name = "volume",
6437}; 7085};
6438 7086
7087#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
7088
6439/************************************************************************* 7089/*************************************************************************
6440 * Fan subdriver 7090 * Fan subdriver
6441 */ 7091 */
@@ -6461,7 +7111,7 @@ static struct ibm_struct volume_driver_data = {
6461 * 7111 *
6462 * Fan speed changes of any sort (including those caused by the 7112 * Fan speed changes of any sort (including those caused by the
6463 * disengaged mode) are usually done slowly by the firmware as the 7113 * disengaged mode) are usually done slowly by the firmware as the
6464 * maximum ammount of fan duty cycle change per second seems to be 7114 * maximum amount of fan duty cycle change per second seems to be
6465 * limited. 7115 * limited.
6466 * 7116 *
6467 * Reading is not available if GFAN exists. 7117 * Reading is not available if GFAN exists.
@@ -6545,7 +7195,7 @@ static struct ibm_struct volume_driver_data = {
6545 * The speeds are stored on handles 7195 * The speeds are stored on handles
6546 * (FANA:FAN9), (FANC:FANB), (FANE:FAND). 7196 * (FANA:FAN9), (FANC:FANB), (FANE:FAND).
6547 * 7197 *
6548 * There are three default speed sets, acessible as handles: 7198 * There are three default speed sets, accessible as handles:
6549 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H 7199 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
6550 * 7200 *
6551 * ACPI DSDT switches which set is in use depending on various 7201 * ACPI DSDT switches which set is in use depending on various
@@ -7510,9 +8160,8 @@ static void fan_resume(void)
7510 } 8160 }
7511} 8161}
7512 8162
7513static int fan_read(char *p) 8163static int fan_read(struct seq_file *m)
7514{ 8164{
7515 int len = 0;
7516 int rc; 8165 int rc;
7517 u8 status; 8166 u8 status;
7518 unsigned int speed = 0; 8167 unsigned int speed = 0;
@@ -7524,7 +8173,7 @@ static int fan_read(char *p)
7524 if (rc < 0) 8173 if (rc < 0)
7525 return rc; 8174 return rc;
7526 8175
7527 len += sprintf(p + len, "status:\t\t%s\n" 8176 seq_printf(m, "status:\t\t%s\n"
7528 "level:\t\t%d\n", 8177 "level:\t\t%d\n",
7529 (status != 0) ? "enabled" : "disabled", status); 8178 (status != 0) ? "enabled" : "disabled", status);
7530 break; 8179 break;
@@ -7535,54 +8184,54 @@ static int fan_read(char *p)
7535 if (rc < 0) 8184 if (rc < 0)
7536 return rc; 8185 return rc;
7537 8186
7538 len += sprintf(p + len, "status:\t\t%s\n", 8187 seq_printf(m, "status:\t\t%s\n",
7539 (status != 0) ? "enabled" : "disabled"); 8188 (status != 0) ? "enabled" : "disabled");
7540 8189
7541 rc = fan_get_speed(&speed); 8190 rc = fan_get_speed(&speed);
7542 if (rc < 0) 8191 if (rc < 0)
7543 return rc; 8192 return rc;
7544 8193
7545 len += sprintf(p + len, "speed:\t\t%d\n", speed); 8194 seq_printf(m, "speed:\t\t%d\n", speed);
7546 8195
7547 if (status & TP_EC_FAN_FULLSPEED) 8196 if (status & TP_EC_FAN_FULLSPEED)
7548 /* Disengaged mode takes precedence */ 8197 /* Disengaged mode takes precedence */
7549 len += sprintf(p + len, "level:\t\tdisengaged\n"); 8198 seq_printf(m, "level:\t\tdisengaged\n");
7550 else if (status & TP_EC_FAN_AUTO) 8199 else if (status & TP_EC_FAN_AUTO)
7551 len += sprintf(p + len, "level:\t\tauto\n"); 8200 seq_printf(m, "level:\t\tauto\n");
7552 else 8201 else
7553 len += sprintf(p + len, "level:\t\t%d\n", status); 8202 seq_printf(m, "level:\t\t%d\n", status);
7554 break; 8203 break;
7555 8204
7556 case TPACPI_FAN_NONE: 8205 case TPACPI_FAN_NONE:
7557 default: 8206 default:
7558 len += sprintf(p + len, "status:\t\tnot supported\n"); 8207 seq_printf(m, "status:\t\tnot supported\n");
7559 } 8208 }
7560 8209
7561 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { 8210 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
7562 len += sprintf(p + len, "commands:\tlevel <level>"); 8211 seq_printf(m, "commands:\tlevel <level>");
7563 8212
7564 switch (fan_control_access_mode) { 8213 switch (fan_control_access_mode) {
7565 case TPACPI_FAN_WR_ACPI_SFAN: 8214 case TPACPI_FAN_WR_ACPI_SFAN:
7566 len += sprintf(p + len, " (<level> is 0-7)\n"); 8215 seq_printf(m, " (<level> is 0-7)\n");
7567 break; 8216 break;
7568 8217
7569 default: 8218 default:
7570 len += sprintf(p + len, " (<level> is 0-7, " 8219 seq_printf(m, " (<level> is 0-7, "
7571 "auto, disengaged, full-speed)\n"); 8220 "auto, disengaged, full-speed)\n");
7572 break; 8221 break;
7573 } 8222 }
7574 } 8223 }
7575 8224
7576 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) 8225 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
7577 len += sprintf(p + len, "commands:\tenable, disable\n" 8226 seq_printf(m, "commands:\tenable, disable\n"
7578 "commands:\twatchdog <timeout> (<timeout> " 8227 "commands:\twatchdog <timeout> (<timeout> "
7579 "is 0 (off), 1-120 (seconds))\n"); 8228 "is 0 (off), 1-120 (seconds))\n");
7580 8229
7581 if (fan_control_commands & TPACPI_FAN_CMD_SPEED) 8230 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
7582 len += sprintf(p + len, "commands:\tspeed <speed>" 8231 seq_printf(m, "commands:\tspeed <speed>"
7583 " (<speed> is 0-65535)\n"); 8232 " (<speed> is 0-65535)\n");
7584 8233
7585 return len; 8234 return 0;
7586} 8235}
7587 8236
7588static int fan_write_cmd_level(const char *cmd, int *rc) 8237static int fan_write_cmd_level(const char *cmd, int *rc)
@@ -7724,10 +8373,23 @@ static struct ibm_struct fan_driver_data = {
7724 */ 8373 */
7725static void tpacpi_driver_event(const unsigned int hkey_event) 8374static void tpacpi_driver_event(const unsigned int hkey_event)
7726{ 8375{
8376 if (ibm_backlight_device) {
8377 switch (hkey_event) {
8378 case TP_HKEY_EV_BRGHT_UP:
8379 case TP_HKEY_EV_BRGHT_DOWN:
8380 tpacpi_brightness_notify_change();
8381 }
8382 }
8383 if (alsa_card) {
8384 switch (hkey_event) {
8385 case TP_HKEY_EV_VOL_UP:
8386 case TP_HKEY_EV_VOL_DOWN:
8387 case TP_HKEY_EV_VOL_MUTE:
8388 volume_alsa_notify_change();
8389 }
8390 }
7727} 8391}
7728 8392
7729
7730
7731static void hotkey_driver_event(const unsigned int scancode) 8393static void hotkey_driver_event(const unsigned int scancode)
7732{ 8394{
7733 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode); 8395 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
@@ -7856,19 +8518,20 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
7856 "%s installed\n", ibm->name); 8518 "%s installed\n", ibm->name);
7857 8519
7858 if (ibm->read) { 8520 if (ibm->read) {
7859 entry = create_proc_entry(ibm->name, 8521 mode_t mode = iibm->base_procfs_mode;
7860 S_IFREG | S_IRUGO | S_IWUSR, 8522
7861 proc_dir); 8523 if (!mode)
8524 mode = S_IRUGO;
8525 if (ibm->write)
8526 mode |= S_IWUSR;
8527 entry = proc_create_data(ibm->name, mode, proc_dir,
8528 &dispatch_proc_fops, ibm);
7862 if (!entry) { 8529 if (!entry) {
7863 printk(TPACPI_ERR "unable to create proc entry %s\n", 8530 printk(TPACPI_ERR "unable to create proc entry %s\n",
7864 ibm->name); 8531 ibm->name);
7865 ret = -ENODEV; 8532 ret = -ENODEV;
7866 goto err_out; 8533 goto err_out;
7867 } 8534 }
7868 entry->data = ibm;
7869 entry->read_proc = &dispatch_procfs_read;
7870 if (ibm->write)
7871 entry->write_proc = &dispatch_procfs_write;
7872 ibm->flags.proc_created = 1; 8535 ibm->flags.proc_created = 1;
7873 } 8536 }
7874 8537
@@ -8049,6 +8712,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
8049#ifdef CONFIG_THINKPAD_ACPI_VIDEO 8712#ifdef CONFIG_THINKPAD_ACPI_VIDEO
8050 { 8713 {
8051 .init = video_init, 8714 .init = video_init,
8715 .base_procfs_mode = S_IRUSR,
8052 .data = &video_driver_data, 8716 .data = &video_driver_data,
8053 }, 8717 },
8054#endif 8718#endif
@@ -8080,6 +8744,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
8080 .data = &brightness_driver_data, 8744 .data = &brightness_driver_data,
8081 }, 8745 },
8082 { 8746 {
8747 .init = volume_init,
8083 .data = &volume_driver_data, 8748 .data = &volume_driver_data,
8084 }, 8749 },
8085 { 8750 {
@@ -8115,36 +8780,61 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
8115 return -EINVAL; 8780 return -EINVAL;
8116} 8781}
8117 8782
8118module_param(experimental, int, 0); 8783module_param(experimental, int, 0444);
8119MODULE_PARM_DESC(experimental, 8784MODULE_PARM_DESC(experimental,
8120 "Enables experimental features when non-zero"); 8785 "Enables experimental features when non-zero");
8121 8786
8122module_param_named(debug, dbg_level, uint, 0); 8787module_param_named(debug, dbg_level, uint, 0);
8123MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); 8788MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
8124 8789
8125module_param(force_load, bool, 0); 8790module_param(force_load, bool, 0444);
8126MODULE_PARM_DESC(force_load, 8791MODULE_PARM_DESC(force_load,
8127 "Attempts to load the driver even on a " 8792 "Attempts to load the driver even on a "
8128 "mis-identified ThinkPad when true"); 8793 "mis-identified ThinkPad when true");
8129 8794
8130module_param_named(fan_control, fan_control_allowed, bool, 0); 8795module_param_named(fan_control, fan_control_allowed, bool, 0444);
8131MODULE_PARM_DESC(fan_control, 8796MODULE_PARM_DESC(fan_control,
8132 "Enables setting fan parameters features when true"); 8797 "Enables setting fan parameters features when true");
8133 8798
8134module_param_named(brightness_mode, brightness_mode, uint, 0); 8799module_param_named(brightness_mode, brightness_mode, uint, 0444);
8135MODULE_PARM_DESC(brightness_mode, 8800MODULE_PARM_DESC(brightness_mode,
8136 "Selects brightness control strategy: " 8801 "Selects brightness control strategy: "
8137 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); 8802 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
8138 8803
8139module_param(brightness_enable, uint, 0); 8804module_param(brightness_enable, uint, 0444);
8140MODULE_PARM_DESC(brightness_enable, 8805MODULE_PARM_DESC(brightness_enable,
8141 "Enables backlight control when 1, disables when 0"); 8806 "Enables backlight control when 1, disables when 0");
8142 8807
8143module_param(hotkey_report_mode, uint, 0); 8808module_param(hotkey_report_mode, uint, 0444);
8144MODULE_PARM_DESC(hotkey_report_mode, 8809MODULE_PARM_DESC(hotkey_report_mode,
8145 "used for backwards compatibility with userspace, " 8810 "used for backwards compatibility with userspace, "
8146 "see documentation"); 8811 "see documentation");
8147 8812
8813#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
8814module_param_named(volume_mode, volume_mode, uint, 0444);
8815MODULE_PARM_DESC(volume_mode,
8816 "Selects volume control strategy: "
8817 "0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");
8818
8819module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
8820MODULE_PARM_DESC(volume_capabilities,
8821 "Selects the mixer capabilites: "
8822 "0=auto, 1=volume and mute, 2=mute only");
8823
8824module_param_named(volume_control, volume_control_allowed, bool, 0444);
8825MODULE_PARM_DESC(volume_control,
8826 "Enables software override for the console audio "
8827 "control when true");
8828
8829/* ALSA module API parameters */
8830module_param_named(index, alsa_index, int, 0444);
8831MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
8832module_param_named(id, alsa_id, charp, 0444);
8833MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
8834module_param_named(enable, alsa_enable, bool, 0444);
8835MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
8836#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
8837
8148#define TPACPI_PARAM(feature) \ 8838#define TPACPI_PARAM(feature) \
8149 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ 8839 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
8150 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \ 8840 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
@@ -8163,25 +8853,25 @@ TPACPI_PARAM(volume);
8163TPACPI_PARAM(fan); 8853TPACPI_PARAM(fan);
8164 8854
8165#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 8855#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
8166module_param(dbg_wlswemul, uint, 0); 8856module_param(dbg_wlswemul, uint, 0444);
8167MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); 8857MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
8168module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); 8858module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
8169MODULE_PARM_DESC(wlsw_state, 8859MODULE_PARM_DESC(wlsw_state,
8170 "Initial state of the emulated WLSW switch"); 8860 "Initial state of the emulated WLSW switch");
8171 8861
8172module_param(dbg_bluetoothemul, uint, 0); 8862module_param(dbg_bluetoothemul, uint, 0444);
8173MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); 8863MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
8174module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); 8864module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
8175MODULE_PARM_DESC(bluetooth_state, 8865MODULE_PARM_DESC(bluetooth_state,
8176 "Initial state of the emulated bluetooth switch"); 8866 "Initial state of the emulated bluetooth switch");
8177 8867
8178module_param(dbg_wwanemul, uint, 0); 8868module_param(dbg_wwanemul, uint, 0444);
8179MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); 8869MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
8180module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); 8870module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
8181MODULE_PARM_DESC(wwan_state, 8871MODULE_PARM_DESC(wwan_state,
8182 "Initial state of the emulated WWAN switch"); 8872 "Initial state of the emulated WWAN switch");
8183 8873
8184module_param(dbg_uwbemul, uint, 0); 8874module_param(dbg_uwbemul, uint, 0444);
8185MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); 8875MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
8186module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); 8876module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
8187MODULE_PARM_DESC(uwb_state, 8877MODULE_PARM_DESC(uwb_state,
@@ -8374,6 +9064,7 @@ static int __init thinkpad_acpi_module_init(void)
8374 PCI_VENDOR_ID_IBM; 9064 PCI_VENDOR_ID_IBM;
8375 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 9065 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
8376 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 9066 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
9067 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
8377 } 9068 }
8378 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 9069 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
8379 ret = ibm_init(&ibms_init[i]); 9070 ret = ibm_init(&ibms_init[i]);
@@ -8384,6 +9075,9 @@ static int __init thinkpad_acpi_module_init(void)
8384 return ret; 9075 return ret;
8385 } 9076 }
8386 } 9077 }
9078
9079 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
9080
8387 ret = input_register_device(tpacpi_inputdev); 9081 ret = input_register_device(tpacpi_inputdev);
8388 if (ret < 0) { 9082 if (ret < 0) {
8389 printk(TPACPI_ERR "unable to register input device\n"); 9083 printk(TPACPI_ERR "unable to register input device\n");
@@ -8393,7 +9087,6 @@ static int __init thinkpad_acpi_module_init(void)
8393 tp_features.input_device_registered = 1; 9087 tp_features.input_device_registered = 1;
8394 } 9088 }
8395 9089
8396 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
8397 return 0; 9090 return 0;
8398} 9091}
8399 9092