0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/rfkill.h>
0011 #include <linux/olpc-ec.h>
0012
0013 static bool card_blocked;
0014
0015 static int rfkill_set_block(void *data, bool blocked)
0016 {
0017 unsigned char cmd;
0018 int r;
0019
0020 if (blocked == card_blocked)
0021 return 0;
0022
0023 if (blocked)
0024 cmd = EC_WLAN_ENTER_RESET;
0025 else
0026 cmd = EC_WLAN_LEAVE_RESET;
0027
0028 r = olpc_ec_cmd(cmd, NULL, 0, NULL, 0);
0029 if (r == 0)
0030 card_blocked = blocked;
0031
0032 return r;
0033 }
0034
0035 static const struct rfkill_ops rfkill_ops = {
0036 .set_block = rfkill_set_block,
0037 };
0038
0039 static int xo1_rfkill_probe(struct platform_device *pdev)
0040 {
0041 struct rfkill *rfk;
0042 int r;
0043
0044 rfk = rfkill_alloc(pdev->name, &pdev->dev, RFKILL_TYPE_WLAN,
0045 &rfkill_ops, NULL);
0046 if (!rfk)
0047 return -ENOMEM;
0048
0049 r = rfkill_register(rfk);
0050 if (r) {
0051 rfkill_destroy(rfk);
0052 return r;
0053 }
0054
0055 platform_set_drvdata(pdev, rfk);
0056 return 0;
0057 }
0058
0059 static int xo1_rfkill_remove(struct platform_device *pdev)
0060 {
0061 struct rfkill *rfk = platform_get_drvdata(pdev);
0062 rfkill_unregister(rfk);
0063 rfkill_destroy(rfk);
0064 return 0;
0065 }
0066
0067 static struct platform_driver xo1_rfkill_driver = {
0068 .driver = {
0069 .name = "xo1-rfkill",
0070 },
0071 .probe = xo1_rfkill_probe,
0072 .remove = xo1_rfkill_remove,
0073 };
0074
0075 module_platform_driver(xo1_rfkill_driver);
0076
0077 MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
0078 MODULE_LICENSE("GPL");
0079 MODULE_ALIAS("platform:xo1-rfkill");