blob: cb3253c10ef33ba7bcac11b42c26bf7c42945a54 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Daniel Drake260586d2010-10-05 15:55:21 +01002/*
3 * Support for rfkill through the OLPC XO-1 laptop embedded controller
4 *
5 * Copyright (C) 2010 One Laptop per Child
Daniel Drake260586d2010-10-05 15:55:21 +01006 */
7
8#include <linux/module.h>
9#include <linux/platform_device.h>
10#include <linux/rfkill.h>
Andres Salomon3bf94282012-07-11 01:16:29 -070011#include <linux/olpc-ec.h>
Daniel Drake260586d2010-10-05 15:55:21 +010012
Daniel Drakebc7ab492012-04-18 18:08:21 +010013static bool card_blocked;
14
Daniel Drake260586d2010-10-05 15:55:21 +010015static int rfkill_set_block(void *data, bool blocked)
16{
17 unsigned char cmd;
Daniel Drakebc7ab492012-04-18 18:08:21 +010018 int r;
19
20 if (blocked == card_blocked)
21 return 0;
22
Daniel Drake260586d2010-10-05 15:55:21 +010023 if (blocked)
24 cmd = EC_WLAN_ENTER_RESET;
25 else
26 cmd = EC_WLAN_LEAVE_RESET;
27
Daniel Drakebc7ab492012-04-18 18:08:21 +010028 r = olpc_ec_cmd(cmd, NULL, 0, NULL, 0);
29 if (r == 0)
30 card_blocked = blocked;
31
32 return r;
Daniel Drake260586d2010-10-05 15:55:21 +010033}
34
35static const struct rfkill_ops rfkill_ops = {
36 .set_block = rfkill_set_block,
37};
38
Greg Kroah-Hartmanb859f152012-12-21 13:18:33 -080039static int xo1_rfkill_probe(struct platform_device *pdev)
Daniel Drake260586d2010-10-05 15:55:21 +010040{
41 struct rfkill *rfk;
42 int r;
43
44 rfk = rfkill_alloc(pdev->name, &pdev->dev, RFKILL_TYPE_WLAN,
45 &rfkill_ops, NULL);
46 if (!rfk)
47 return -ENOMEM;
48
49 r = rfkill_register(rfk);
50 if (r) {
51 rfkill_destroy(rfk);
52 return r;
53 }
54
55 platform_set_drvdata(pdev, rfk);
56 return 0;
57}
58
Greg Kroah-Hartmanb859f152012-12-21 13:18:33 -080059static int xo1_rfkill_remove(struct platform_device *pdev)
Daniel Drake260586d2010-10-05 15:55:21 +010060{
61 struct rfkill *rfk = platform_get_drvdata(pdev);
62 rfkill_unregister(rfk);
63 rfkill_destroy(rfk);
64 return 0;
65}
66
67static struct platform_driver xo1_rfkill_driver = {
68 .driver = {
69 .name = "xo1-rfkill",
Daniel Drake260586d2010-10-05 15:55:21 +010070 },
71 .probe = xo1_rfkill_probe,
Greg Kroah-Hartmanb859f152012-12-21 13:18:33 -080072 .remove = xo1_rfkill_remove,
Daniel Drake260586d2010-10-05 15:55:21 +010073};
74
Axel Lin73d99a22011-11-26 12:14:37 +080075module_platform_driver(xo1_rfkill_driver);
Daniel Drake260586d2010-10-05 15:55:21 +010076
77MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
78MODULE_LICENSE("GPL");
79MODULE_ALIAS("platform:xo1-rfkill");