compal-laptop: Replace sysfs support with rfkill support
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / platform / x86 / compal-laptop.c
index 11003bb..2740b40 100644 (file)
 /*
  * comapl-laptop.c - Compal laptop support.
  *
- * This driver exports a few files in /sys/devices/platform/compal-laptop/:
- *
- *   wlan - wlan subsystem state: contains 0 or 1 (rw)
- *
- *   bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
- *
- *   raw - raw value taken from embedded controller register (ro)
- *
- * In addition to these platform device attributes the driver
- * registers itself in the Linux backlight control subsystem and is
- * available to userspace under /sys/class/backlight/compal-laptop/.
+ * The driver registers itself with the rfkill subsystem and
+ * the Linux backlight control subsystem.
  *
  * This driver might work on other laptops produced by Compal. If you
  * want to try it you can pass force=1 as argument to the module which
@@ -51,7 +42,7 @@
 #include <linux/dmi.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
-#include <linux/autoconf.h>
+#include <linux/rfkill.h>
 
 #define COMPAL_DRIVER_VERSION "0.2.6"
 
 #define WLAN_MASK      0x01
 #define BT_MASK        0x02
 
+static struct rfkill *wifi_rfkill;
+static struct rfkill *bt_rfkill;
+static struct platform_device *compal_device;
+
 static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -89,65 +84,75 @@ static int get_lcd_level(void)
        return (int) result;
 }
 
-static int set_wlan_state(int state)
+static int compal_rfkill_set(void *data, bool blocked)
 {
+       unsigned long radio = (unsigned long) data;
        u8 result, value;
 
        ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
 
-       if ((result & KILLSWITCH_MASK) == 0)
-               return -EINVAL;
-       else {
-               if (state)
-                       value = (u8) (result | WLAN_MASK);
-               else
-                       value = (u8) (result & ~WLAN_MASK);
-               ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
-       }
+       if (!blocked)
+               value = (u8) (result | radio);
+       else
+               value = (u8) (result & ~radio);
+       ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
 
        return 0;
 }
 
-static int set_bluetooth_state(int state)
+static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
 {
-       u8 result, value;
+       u8 result;
+       bool hw_blocked;
 
        ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
 
-       if ((result & KILLSWITCH_MASK) == 0)
-               return -EINVAL;
-       else {
-               if (state)
-                       value = (u8) (result | BT_MASK);
-               else
-                       value = (u8) (result & ~BT_MASK);
-               ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
-       }
-
-       return 0;
+       hw_blocked = !(result & KILLSWITCH_MASK);
+       rfkill_set_hw_state(rfkill, hw_blocked);
 }
 
-static int get_wireless_state(int *wlan, int *bluetooth)
+static const struct rfkill_ops compal_rfkill_ops = {
+       .poll = compal_rfkill_poll,
+       .set_block = compal_rfkill_set,
+};
+
+static int setup_rfkill(void)
 {
-       u8 result;
+       int ret;
 
-       ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+       wifi_rfkill = rfkill_alloc("compal-wifi", &compal_device->dev,
+                               RFKILL_TYPE_WLAN, &compal_rfkill_ops,
+                               (void *) WLAN_MASK);
+       if (!wifi_rfkill)
+               return -ENOMEM;
 
-       if (wlan) {
-               if ((result & KILLSWITCH_MASK) == 0)
-                       *wlan = 0;
-               else
-                       *wlan = result & WLAN_MASK;
-       }
+       ret = rfkill_register(wifi_rfkill);
+       if (ret)
+               goto err_wifi;
 
-       if (bluetooth) {
-               if ((result & KILLSWITCH_MASK) == 0)
-                       *bluetooth = 0;
-               else
-                       *bluetooth = (result & BT_MASK) >> 1;
+       bt_rfkill = rfkill_alloc("compal-bluetooth", &compal_device->dev,
+                               RFKILL_TYPE_BLUETOOTH, &compal_rfkill_ops,
+                               (void *) BT_MASK);
+       if (!bt_rfkill) {
+               ret = -ENOMEM;
+               goto err_allocate_bt;
        }
+       ret = rfkill_register(bt_rfkill);
+       if (ret)
+               goto err_register_bt;
 
        return 0;
+
+err_register_bt:
+       rfkill_destroy(bt_rfkill);
+
+err_allocate_bt:
+       rfkill_unregister(wifi_rfkill);
+
+err_wifi:
+       rfkill_destroy(wifi_rfkill);
+
+       return ret;
 }
 
 /* Backlight device stuff */
@@ -170,86 +175,6 @@ static struct backlight_ops compalbl_ops = {
 
 static struct backlight_device *compalbl_device;
 
-/* Platform device */
-
-static ssize_t show_wlan(struct device *dev,
-       struct device_attribute *attr, char *buf)
-{
-       int ret, enabled;
-
-       ret = get_wireless_state(&enabled, NULL);
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%i\n", enabled);
-}
-
-static ssize_t show_raw(struct device *dev,
-       struct device_attribute *attr, char *buf)
-{
-       u8 result;
-
-       ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
-
-       return sprintf(buf, "%i\n", result);
-}
-
-static ssize_t show_bluetooth(struct device *dev,
-       struct device_attribute *attr, char *buf)
-{
-       int ret, enabled;
-
-       ret = get_wireless_state(NULL, &enabled);
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%i\n", enabled);
-}
-
-static ssize_t store_wlan_state(struct device *dev,
-       struct device_attribute *attr, const char *buf, size_t count)
-{
-       int state, ret;
-
-       if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
-               return -EINVAL;
-
-       ret = set_wlan_state(state);
-       if (ret < 0)
-               return ret;
-
-       return count;
-}
-
-static ssize_t store_bluetooth_state(struct device *dev,
-       struct device_attribute *attr, const char *buf, size_t count)
-{
-       int state, ret;
-
-       if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
-               return -EINVAL;
-
-       ret = set_bluetooth_state(state);
-       if (ret < 0)
-               return ret;
-
-       return count;
-}
-
-static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
-static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
-static DEVICE_ATTR(raw, 0444, show_raw, NULL);
-
-static struct attribute *compal_attributes[] = {
-       &dev_attr_bluetooth.attr,
-       &dev_attr_wlan.attr,
-       &dev_attr_raw.attr,
-       NULL
-};
-
-static struct attribute_group compal_attribute_group = {
-       .attrs = compal_attributes
-};
 
 static struct platform_driver compal_driver = {
        .driver = {
@@ -258,8 +183,6 @@ static struct platform_driver compal_driver = {
        }
 };
 
-static struct platform_device *compal_device;
-
 /* Initialization */
 
 static int dmi_check_cb(const struct dmi_system_id *id)
@@ -311,6 +234,47 @@ static struct dmi_system_id __initdata compal_dmi_table[] = {
                },
                .callback = dmi_check_cb
        },
+       {
+               .ident = "Dell Mini 9",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"),
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "Dell Mini 10",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"),
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "Dell Mini 10v",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "Dell Inspiron 11z",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"),
+               },
+               .callback = dmi_check_cb
+       },
+       {
+               .ident = "Dell Mini 12",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"),
+               },
+               .callback = dmi_check_cb
+       },
+
        { }
 };
 
@@ -349,23 +313,21 @@ static int __init compal_init(void)
 
        ret = platform_device_add(compal_device);
        if (ret)
-               goto fail_platform_device1;
+               goto fail_platform_device;
 
-       ret = sysfs_create_group(&compal_device->dev.kobj,
-               &compal_attribute_group);
+       ret = setup_rfkill();
        if (ret)
-               goto fail_platform_device2;
+               goto fail_rfkill;
 
        printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
                " successfully loaded.\n");
 
        return 0;
 
-fail_platform_device2:
-
+fail_rfkill:
        platform_device_del(compal_device);
 
-fail_platform_device1:
+fail_platform_device:
 
        platform_device_put(compal_device);
 
@@ -383,10 +345,13 @@ fail_backlight:
 static void __exit compal_cleanup(void)
 {
 
-       sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
        platform_device_unregister(compal_device);
        platform_driver_unregister(&compal_driver);
        backlight_device_unregister(compalbl_device);
+       rfkill_unregister(wifi_rfkill);
+       rfkill_destroy(wifi_rfkill);
+       rfkill_unregister(bt_rfkill);
+       rfkill_destroy(bt_rfkill);
 
        printk(KERN_INFO "compal-laptop: driver unloaded.\n");
 }
@@ -404,3 +369,8 @@ MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*");
 MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*");
 MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*");
 MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*");