* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define ACER_WMI_VERSION "0.1"
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/i8042.h>
+#include <linux/debugfs.h>
#include <acpi/acpi_drivers.h>
int brightness;
};
+struct acer_debug {
+ struct dentry *root;
+ struct dentry *devices;
+ u32 wmid_devices;
+};
+
/* Each low-level interface must define at least some of the following */
struct wmi_interface {
/* The WMI device type */
/* Private data for the current interface */
struct acer_data data;
+
+ /* debugfs entries associated with this interface */
+ struct acer_debug debug;
};
/* The static interface pointer, points to the currently detected interface */
static void set_quirks(void)
{
+ if (!interface)
+ return;
+
if (quirks->mailled)
interface->capability |= ACER_CAP_MAILLED;
static acpi_status set_u32(u32 value, u32 cap)
{
+ acpi_status status;
+
if (interface->capability & cap) {
switch (interface->type) {
case ACER_AMW0:
return AMW0_set_u32(value, cap, interface);
case ACER_AMW0_V2:
+ if (cap == ACER_CAP_MAILLED)
+ return AMW0_set_u32(value, cap, interface);
+
+ /*
+ * On some models, some WMID methods don't toggle
+ * properly. For those cases, we want to run the AMW0
+ * method afterwards to be certain we've really toggled
+ * the device state.
+ */
+ if (cap == ACER_CAP_WIRELESS ||
+ cap == ACER_CAP_BLUETOOTH) {
+ status = WMID_set_u32(value, cap, interface);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ return AMW0_set_u32(value, cap, interface);
+ }
case ACER_WMID:
return WMID_set_u32(value, cap, interface);
default:
static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR,
show_interface, NULL);
+/*
+ * debugfs functions
+ */
+static u32 get_wmid_devices(void)
+{
+ struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = wmi_query_block(WMID_GUID2, 1, &out);
+ if (ACPI_FAILURE(status))
+ return 0;
+
+ obj = (union acpi_object *) out.pointer;
+ if (obj && obj->type == ACPI_TYPE_BUFFER &&
+ obj->buffer.length == sizeof(u32)) {
+ return *((u32 *) obj->buffer.pointer);
+ } else {
+ return 0;
+ }
+}
+
/*
* Platform device
*/
return retval;
}
+static void remove_debugfs(void)
+{
+ debugfs_remove(interface->debug.devices);
+ debugfs_remove(interface->debug.root);
+}
+
+static int create_debugfs(void)
+{
+ interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
+ if (!interface->debug.root) {
+ printk(ACER_ERR "Failed to create debugfs directory");
+ return -ENOMEM;
+ }
+
+ interface->debug.devices = debugfs_create_u32("devices", S_IRUGO,
+ interface->debug.root,
+ &interface->debug.wmid_devices);
+ if (!interface->debug.devices)
+ goto error_debugfs;
+
+ return 0;
+
+error_debugfs:
+ remove_debugfs();
+ return -ENOMEM;
+}
+
static int __init acer_wmi_init(void)
{
int err;
- printk(ACER_INFO "Acer Laptop ACPI-WMI Extras version %s\n",
- ACER_WMI_VERSION);
+ printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
find_quirks();
return -ENODEV;
}
+ set_quirks();
+
if (platform_driver_register(&acer_platform_driver)) {
printk(ACER_ERR "Unable to register platform driver.\n");
goto error_platform_register;
if (err)
return err;
+ if (wmi_has_guid(WMID_GUID2)) {
+ interface->debug.wmid_devices = get_wmid_devices();
+ err = create_debugfs();
+ if (err)
+ return err;
+ }
+
/* Override any initial settings with values from the commandline */
acer_commandline_init();