xo1-rfkill.c (1509B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Support for rfkill through the OLPC XO-1 laptop embedded controller 4 * 5 * Copyright (C) 2010 One Laptop per Child 6 */ 7 8#include <linux/module.h> 9#include <linux/platform_device.h> 10#include <linux/rfkill.h> 11#include <linux/olpc-ec.h> 12 13static bool card_blocked; 14 15static int rfkill_set_block(void *data, bool blocked) 16{ 17 unsigned char cmd; 18 int r; 19 20 if (blocked == card_blocked) 21 return 0; 22 23 if (blocked) 24 cmd = EC_WLAN_ENTER_RESET; 25 else 26 cmd = EC_WLAN_LEAVE_RESET; 27 28 r = olpc_ec_cmd(cmd, NULL, 0, NULL, 0); 29 if (r == 0) 30 card_blocked = blocked; 31 32 return r; 33} 34 35static const struct rfkill_ops rfkill_ops = { 36 .set_block = rfkill_set_block, 37}; 38 39static int xo1_rfkill_probe(struct platform_device *pdev) 40{ 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 59static int xo1_rfkill_remove(struct platform_device *pdev) 60{ 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", 70 }, 71 .probe = xo1_rfkill_probe, 72 .remove = xo1_rfkill_remove, 73}; 74 75module_platform_driver(xo1_rfkill_driver); 76 77MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); 78MODULE_LICENSE("GPL"); 79MODULE_ALIAS("platform:xo1-rfkill");