aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/debugfs-ideapad19
-rw-r--r--drivers/platform/x86/ideapad-laptop.c152
2 files changed, 171 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/debugfs-ideapad b/Documentation/ABI/testing/debugfs-ideapad
new file mode 100644
index 000000000000..7079c0b21030
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-ideapad
@@ -0,0 +1,19 @@
1What: /sys/kernel/debug/ideapad/cfg
2Date: Sep 2011
3KernelVersion: 3.2
4Contact: Ike Panhc <ike.pan@canonical.com>
5Description:
6
7cfg shows the return value of _CFG method in VPC2004 device. It tells machine
8capability and what graphic component within the machine.
9
10
11What: /sys/kernel/debug/ideapad/status
12Date: Sep 2011
13KernelVersion: 3.2
14Contact: Ike Panhc <ike.pan@canonical.com>
15Description:
16
17status shows infos we can read and tells its meaning and value.
18
19
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 39a72a8aeb8c..1c8b5065f34c 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -34,6 +34,8 @@
34#include <linux/input/sparse-keymap.h> 34#include <linux/input/sparse-keymap.h>
35#include <linux/backlight.h> 35#include <linux/backlight.h>
36#include <linux/fb.h> 36#include <linux/fb.h>
37#include <linux/debugfs.h>
38#include <linux/seq_file.h>
37 39
38#define IDEAPAD_RFKILL_DEV_NUM (3) 40#define IDEAPAD_RFKILL_DEV_NUM (3)
39 41
@@ -71,10 +73,12 @@ struct ideapad_private {
71 struct platform_device *platform_device; 73 struct platform_device *platform_device;
72 struct input_dev *inputdev; 74 struct input_dev *inputdev;
73 struct backlight_device *blightdev; 75 struct backlight_device *blightdev;
76 struct dentry *debug;
74 unsigned long cfg; 77 unsigned long cfg;
75}; 78};
76 79
77static acpi_handle ideapad_handle; 80static acpi_handle ideapad_handle;
81static struct ideapad_private *ideapad_priv;
78static bool no_bt_rfkill; 82static bool no_bt_rfkill;
79module_param(no_bt_rfkill, bool, 0444); 83module_param(no_bt_rfkill, bool, 0444);
80MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); 84MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
@@ -188,6 +192,146 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
188} 192}
189 193
190/* 194/*
195 * debugfs
196 */
197#define DEBUGFS_EVENT_LEN (4096)
198static int debugfs_status_show(struct seq_file *s, void *data)
199{
200 unsigned long value;
201
202 if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value))
203 seq_printf(s, "Backlight max:\t%lu\n", value);
204 if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value))
205 seq_printf(s, "Backlight now:\t%lu\n", value);
206 if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value))
207 seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off");
208 seq_printf(s, "=====================\n");
209
210 if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value))
211 seq_printf(s, "Radio status:\t%s(%lu)\n",
212 value ? "On" : "Off", value);
213 if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value))
214 seq_printf(s, "Wifi status:\t%s(%lu)\n",
215 value ? "On" : "Off", value);
216 if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value))
217 seq_printf(s, "BT status:\t%s(%lu)\n",
218 value ? "On" : "Off", value);
219 if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value))
220 seq_printf(s, "3G status:\t%s(%lu)\n",
221 value ? "On" : "Off", value);
222 seq_printf(s, "=====================\n");
223
224 if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value))
225 seq_printf(s, "Touchpad status:%s(%lu)\n",
226 value ? "On" : "Off", value);
227 if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value))
228 seq_printf(s, "Camera status:\t%s(%lu)\n",
229 value ? "On" : "Off", value);
230
231 return 0;
232}
233
234static int debugfs_status_open(struct inode *inode, struct file *file)
235{
236 return single_open(file, debugfs_status_show, NULL);
237}
238
239static const struct file_operations debugfs_status_fops = {
240 .owner = THIS_MODULE,
241 .open = debugfs_status_open,
242 .read = seq_read,
243 .llseek = seq_lseek,
244 .release = single_release,
245};
246
247static int debugfs_cfg_show(struct seq_file *s, void *data)
248{
249 if (!ideapad_priv) {
250 seq_printf(s, "cfg: N/A\n");
251 } else {
252 seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ",
253 ideapad_priv->cfg);
254 if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg))
255 seq_printf(s, "Bluetooth ");
256 if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg))
257 seq_printf(s, "3G ");
258 if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg))
259 seq_printf(s, "Wireless ");
260 if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg))
261 seq_printf(s, "Camera ");
262 seq_printf(s, "\nGraphic: ");
263 switch ((ideapad_priv->cfg)&0x700) {
264 case 0x100:
265 seq_printf(s, "Intel");
266 break;
267 case 0x200:
268 seq_printf(s, "ATI");
269 break;
270 case 0x300:
271 seq_printf(s, "Nvidia");
272 break;
273 case 0x400:
274 seq_printf(s, "Intel and ATI");
275 break;
276 case 0x500:
277 seq_printf(s, "Intel and Nvidia");
278 break;
279 }
280 seq_printf(s, "\n");
281 }
282 return 0;
283}
284
285static int debugfs_cfg_open(struct inode *inode, struct file *file)
286{
287 return single_open(file, debugfs_cfg_show, NULL);
288}
289
290static const struct file_operations debugfs_cfg_fops = {
291 .owner = THIS_MODULE,
292 .open = debugfs_cfg_open,
293 .read = seq_read,
294 .llseek = seq_lseek,
295 .release = single_release,
296};
297
298static int __devinit ideapad_debugfs_init(struct ideapad_private *priv)
299{
300 struct dentry *node;
301
302 priv->debug = debugfs_create_dir("ideapad", NULL);
303 if (priv->debug == NULL) {
304 pr_err("failed to create debugfs directory");
305 goto errout;
306 }
307
308 node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL,
309 &debugfs_cfg_fops);
310 if (!node) {
311 pr_err("failed to create cfg in debugfs");
312 goto errout;
313 }
314
315 node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL,
316 &debugfs_status_fops);
317 if (!node) {
318 pr_err("failed to create event in debugfs");
319 goto errout;
320 }
321
322 return 0;
323
324errout:
325 return -ENOMEM;
326}
327
328static void ideapad_debugfs_exit(struct ideapad_private *priv)
329{
330 debugfs_remove_recursive(priv->debug);
331 priv->debug = NULL;
332}
333
334/*
191 * sysfs 335 * sysfs
192 */ 336 */
193static ssize_t show_ideapad_cam(struct device *dev, 337static ssize_t show_ideapad_cam(struct device *dev,
@@ -573,6 +717,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
573 if (!priv) 717 if (!priv)
574 return -ENOMEM; 718 return -ENOMEM;
575 dev_set_drvdata(&adevice->dev, priv); 719 dev_set_drvdata(&adevice->dev, priv);
720 ideapad_priv = priv;
576 ideapad_handle = adevice->handle; 721 ideapad_handle = adevice->handle;
577 priv->cfg = cfg; 722 priv->cfg = cfg;
578 723
@@ -580,6 +725,10 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
580 if (ret) 725 if (ret)
581 goto platform_failed; 726 goto platform_failed;
582 727
728 ret = ideapad_debugfs_init(priv);
729 if (ret)
730 goto debugfs_failed;
731
583 ret = ideapad_input_init(priv); 732 ret = ideapad_input_init(priv);
584 if (ret) 733 if (ret)
585 goto input_failed; 734 goto input_failed;
@@ -605,6 +754,8 @@ backlight_failed:
605 ideapad_unregister_rfkill(adevice, i); 754 ideapad_unregister_rfkill(adevice, i);
606 ideapad_input_exit(priv); 755 ideapad_input_exit(priv);
607input_failed: 756input_failed:
757 ideapad_debugfs_exit(priv);
758debugfs_failed:
608 ideapad_platform_exit(priv); 759 ideapad_platform_exit(priv);
609platform_failed: 760platform_failed:
610 kfree(priv); 761 kfree(priv);
@@ -620,6 +771,7 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type)
620 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 771 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
621 ideapad_unregister_rfkill(adevice, i); 772 ideapad_unregister_rfkill(adevice, i);
622 ideapad_input_exit(priv); 773 ideapad_input_exit(priv);
774 ideapad_debugfs_exit(priv);
623 ideapad_platform_exit(priv); 775 ideapad_platform_exit(priv);
624 dev_set_drvdata(&adevice->dev, NULL); 776 dev_set_drvdata(&adevice->dev, NULL);
625 kfree(priv); 777 kfree(priv);