linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Corentin Chary <corentincj@iksaif.net>
To: platform-driver-x86@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@suse.de>,
	Corentin Chary <corentincj@iksaif.net>,
	Matthew Garrett <mjg@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 12/15] samsung-laptop: add true rfkill support for swsmi
Date: Tue, 22 Nov 2011 23:02:43 +0100	[thread overview]
Message-ID: <1321999366-23784-13-git-send-email-corentincj@iksaif.net> (raw)
In-Reply-To: <1321999366-23784-1-git-send-email-corentincj@iksaif.net>

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
---
 drivers/platform/x86/samsung-laptop.c |  201 ++++++++++++++++++++++++++++-----
 1 files changed, 170 insertions(+), 31 deletions(-)

diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index 17afb13..c9f574c 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -45,6 +45,9 @@
 #define SABI_IFACE_COMPLETE		0x04
 #define SABI_IFACE_DATA			0x05
 
+#define WL_STATUS_WLAN			0x0
+#define WL_STATUS_BT			0x2
+
 /* Structure get/set data using sabi */
 struct sabi_data {
 	union {
@@ -113,6 +116,10 @@ struct sabi_commands {
 	u16 get_usb_charge;
 	u16 set_usb_charge;
 
+	/* the first byte is for bluetooth and the third one is for wlan */
+	u16 get_wireless_status;
+	u16 set_wireless_status;
+
 	/* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */
 	u16 kbd_backlight;
 
@@ -129,6 +136,7 @@ struct sabi_performance_level {
 };
 
 struct sabi_config {
+	int sabi_version;
 	const char *test_string;
 	u16 main_function;
 	const struct sabi_header_offsets header_offsets;
@@ -140,6 +148,10 @@ struct sabi_config {
 
 static const struct sabi_config sabi_configs[] = {
 	{
+		/* I don't know if it is really 2, but it it is
+		 * less than 3 anyway */
+		.sabi_version = 2,
+
 		.test_string = "SECLINUX",
 
 		.main_function = 0x4c49,
@@ -175,6 +187,9 @@ static const struct sabi_config sabi_configs[] = {
 			.get_usb_charge = 0xFFFF,
 			.set_usb_charge = 0xFFFF,
 
+			.get_wireless_status = 0xFFFF,
+			.set_wireless_status = 0xFFFF,
+
 			.kbd_backlight = 0xFFFF,
 
 			.set_linux = 0x0a,
@@ -195,6 +210,8 @@ static const struct sabi_config sabi_configs[] = {
 		.max_brightness = 8,
 	},
 	{
+		.sabi_version = 3,
+
 		.test_string = "SwSmi@",
 
 		.main_function = 0x5843,
@@ -230,6 +247,9 @@ static const struct sabi_config sabi_configs[] = {
 			.get_usb_charge = 0x67,
 			.set_usb_charge = 0x68,
 
+			.get_wireless_status = 0x69,
+			.set_wireless_status = 0x6a,
+
 			.kbd_backlight = 0x78,
 
 			.set_linux = 0xff,
@@ -274,6 +294,14 @@ struct samsung_laptop_debug {
 	struct debugfs_blob_wrapper data_wrapper;
 };
 
+struct samsung_laptop;
+
+struct samsung_rfkill {
+	struct samsung_laptop *samsung;
+	struct rfkill *rfkill;
+	enum rfkill_type type;
+};
+
 struct samsung_laptop {
 	const struct sabi_config *config;
 
@@ -285,7 +313,9 @@ struct samsung_laptop {
 
 	struct platform_device *platform_device;
 	struct backlight_device *backlight_device;
-	struct rfkill *rfk;
+
+	struct samsung_rfkill wlan;
+	struct samsung_rfkill bluetooth;
 
 	struct led_classdev kbd_led;
 	int kbd_led_wk;
@@ -486,26 +516,74 @@ static const struct backlight_ops backlight_ops = {
 	.update_status	= update_status,
 };
 
-static int rfkill_set(void *data, bool blocked)
+static int seclinux_rfkill_set(void *data, bool blocked)
 {
 	struct samsung_laptop *samsung = data;
 	const struct sabi_commands *commands = &samsung->config->commands;
 
-	/* Do something with blocked...*/
-	/*
-	 * blocked == false is on
-	 * blocked == true is off
-	 */
-	if (blocked)
-		sabi_set_commandb(samsung, commands->set_wireless_button, 0);
+	return sabi_set_commandb(samsung, commands->set_wireless_button,
+				 !blocked);
+}
+
+static struct rfkill_ops seclinux_rfkill_ops = {
+	.set_block = seclinux_rfkill_set,
+};
+
+static int swsmi_wireless_status(struct samsung_laptop *samsung,
+				 struct sabi_data *data)
+{
+	const struct sabi_commands *commands = &samsung->config->commands;
+
+	return sabi_command(samsung, commands->get_wireless_status,
+			    NULL, data);
+}
+
+static int swsmi_rfkill_set(void *priv, bool blocked)
+{
+	struct samsung_rfkill *srfkill = priv;
+	struct samsung_laptop *samsung = srfkill->samsung;
+	const struct sabi_commands *commands = &samsung->config->commands;
+	struct sabi_data data;
+	int ret;
+
+	ret = swsmi_wireless_status(samsung, &data);
+	if (ret)
+		return ret;
+
+	data.data[1] = 0;
+	if (srfkill->type == RFKILL_TYPE_WLAN)
+		data.data[WL_STATUS_WLAN] = !blocked;
+	else if (srfkill->type == RFKILL_TYPE_BLUETOOTH)
+		data.data[WL_STATUS_BT] = !blocked;
+
+	return sabi_command(samsung, commands->set_wireless_status,
+			    &data, &data);
+}
+
+static void swsmi_rfkill_query(struct rfkill *rfkill, void *priv)
+{
+	struct samsung_rfkill *srfkill = priv;
+	struct samsung_laptop *samsung = srfkill->samsung;
+	struct sabi_data data;
+	int ret;
+
+	ret = swsmi_wireless_status(samsung, &data);
+	if (ret)
+		return ;
+
+	if (srfkill->type == RFKILL_TYPE_WLAN)
+		ret = data.data[WL_STATUS_WLAN];
+	else if (srfkill->type == RFKILL_TYPE_BLUETOOTH)
+		ret = data.data[WL_STATUS_BT];
 	else
-		sabi_set_commandb(samsung, commands->set_wireless_button, 1);
+		return ;
 
-	return 0;
+	rfkill_set_sw_state(rfkill, !ret);
 }
 
-static struct rfkill_ops rfkill_ops = {
-	.set_block = rfkill_set,
+static struct rfkill_ops swsmi_rfkill_ops = {
+	.set_block = swsmi_rfkill_set,
+	.query = swsmi_rfkill_query,
 };
 
 static ssize_t get_performance_level(struct device *dev,
@@ -730,31 +808,92 @@ static int find_signature(void __iomem *memcheck, const char *testStr)
 
 static void samsung_rfkill_exit(struct samsung_laptop *samsung)
 {
-	if (samsung->rfk) {
-		rfkill_unregister(samsung->rfk);
-		rfkill_destroy(samsung->rfk);
-		samsung->rfk = NULL;
+	if (samsung->wlan.rfkill) {
+		rfkill_unregister(samsung->wlan.rfkill);
+		rfkill_destroy(samsung->wlan.rfkill);
+		samsung->wlan.rfkill = NULL;
+	}
+	if (samsung->bluetooth.rfkill) {
+		rfkill_unregister(samsung->bluetooth.rfkill);
+		rfkill_destroy(samsung->bluetooth.rfkill);
+		samsung->bluetooth.rfkill = NULL;
 	}
 }
 
-static int __init samsung_rfkill_init(struct samsung_laptop *samsung)
+static int samsung_new_rfkill(struct samsung_laptop *samsung,
+			      struct samsung_rfkill *arfkill,
+			      const char *name, enum rfkill_type type,
+			      const struct rfkill_ops *ops,
+			      int blocked)
 {
-	int retval;
+	struct rfkill **rfkill = &arfkill->rfkill;
+	int ret;
 
-	samsung->rfk = rfkill_alloc("samsung-wifi",
-				    &samsung->platform_device->dev,
-				    RFKILL_TYPE_WLAN,
-				    &rfkill_ops, samsung);
-	if (!samsung->rfk)
-		return -ENOMEM;
+	arfkill->type = type;
+	arfkill->samsung = samsung;
 
-	retval = rfkill_register(samsung->rfk);
-	if (retval) {
-		rfkill_destroy(samsung->rfk);
-		samsung->rfk = NULL;
-		return -ENODEV;
+	*rfkill = rfkill_alloc(name, &samsung->platform_device->dev,
+			       type, ops, arfkill);
+
+	if (!*rfkill)
+		return -EINVAL;
+
+	if (blocked != -1)
+		rfkill_init_sw_state(*rfkill, blocked);
+
+	ret = rfkill_register(*rfkill);
+	if (ret) {
+		rfkill_destroy(*rfkill);
+		*rfkill = NULL;
+		return ret;
 	}
+	return 0;
+}
 
+static int __init samsung_rfkill_init_seclinux(struct samsung_laptop *samsung)
+{
+	return samsung_new_rfkill(samsung, &samsung->wlan, "samsung-wlan",
+				  RFKILL_TYPE_WLAN, &seclinux_rfkill_ops, -1);
+}
+
+static int __init samsung_rfkill_init_swsmi(struct samsung_laptop *samsung)
+{
+	struct sabi_data data;
+	int ret;
+
+	ret = swsmi_wireless_status(samsung, &data);
+	if (ret)
+		return ret;
+
+	ret = samsung_new_rfkill(samsung, &samsung->wlan,
+				 "samsung-wlan",
+				 RFKILL_TYPE_WLAN,
+				 &swsmi_rfkill_ops,
+				 !data.data[WL_STATUS_WLAN]);
+	if (ret)
+		goto exit;
+
+	ret = samsung_new_rfkill(samsung, &samsung->bluetooth,
+				 "samsung-bluetooth",
+				 RFKILL_TYPE_BLUETOOTH,
+				 &swsmi_rfkill_ops,
+				 !data.data[WL_STATUS_BT]);
+	if (ret)
+		goto exit;
+
+exit:
+	if (ret)
+		samsung_rfkill_exit(samsung);
+
+	return ret;
+}
+
+static int __init samsung_rfkill_init(struct samsung_laptop *samsung)
+{
+	if (samsung->config->sabi_version == 2)
+		return samsung_rfkill_init_seclinux(samsung);
+	if (samsung->config->sabi_version == 3)
+		return samsung_rfkill_init_swsmi(samsung);
 	return 0;
 }
 
-- 
1.7.5.4


  parent reply	other threads:[~2011-11-22 22:04 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1321999366-23784-1-git-send-email-corentincj@iksaif.net>
2011-11-22 22:02 ` [PATCH 01/15] samsung-laptop: put all local variables in a single structure Corentin Chary
2011-11-22 22:18   ` Greg KH
2011-11-22 22:02 ` [PATCH 02/15] samsung-laptop: move code into init/exit functions Corentin Chary
2011-11-22 22:19   ` Greg KH
2011-11-23  6:24     ` Corentin Chary
2011-11-22 22:02 ` [PATCH 03/15] samsung-laptop: don't handle backlight if handled by acpi/video Corentin Chary
2011-11-22 22:16   ` Greg KH
2011-11-23  6:58     ` Corentin Chary
2011-11-23 20:30       ` Greg KH
2011-11-23 16:01   ` David Herrmann
2011-11-22 22:02 ` [PATCH 04/15] samsung-laptop: use a sysfs group Corentin Chary
2011-11-22 22:19   ` Greg KH
2011-11-22 22:02 ` [PATCH 05/15] samsung-laptop: ehance SABI support Corentin Chary
2011-11-22 22:18   ` Greg KH
2011-11-23  6:22     ` Corentin Chary
2011-11-22 22:02 ` [PATCH 06/15] samsung-laptop: add small debugfs interface Corentin Chary
2011-11-22 22:20   ` Greg KH
2011-11-23  6:27     ` Corentin Chary
2011-11-22 22:02 ` [PATCH 07/15] samsung-laptop: remove selftest Corentin Chary
2011-11-22 22:21   ` Greg KH
2011-11-22 22:02 ` [PATCH 08/15] samsung-laptop: add battery life extender support Corentin Chary
2011-11-22 22:21   ` Greg KH
2011-11-23  6:28     ` Corentin Chary
2011-11-23 16:17   ` David Herrmann
2011-11-23 16:54     ` Corentin Chary
2011-11-23 17:10       ` David Herrmann
2011-11-23 18:11         ` Corentin Chary
2011-11-23 20:14           ` David Herrmann
2011-11-22 22:02 ` [PATCH 09/15] samsung-laptop: add usb charge support Corentin Chary
2011-11-22 22:22   ` Greg KH
2011-11-22 22:02 ` [PATCH 10/15] samsung-laptop: cleanup KConfig Corentin Chary
2011-11-22 22:22   ` Greg KH
2011-11-23 16:19   ` David Herrmann
2011-11-22 22:02 ` [PATCH 11/15] samsung-laptop: add keyboard backlight support Corentin Chary
2011-11-22 22:23   ` Greg KH
2011-11-23  6:35     ` Corentin Chary
2011-11-23 16:41       ` David Herrmann
2011-11-23 16:51         ` Corentin Chary
2011-11-24  7:07           ` Corentin Chary
2011-11-25 19:18             ` David Herrmann
2011-11-25 21:41               ` Corentin Chary
2011-11-22 22:02 ` Corentin Chary [this message]
2011-11-22 22:24   ` [PATCH 12/15] samsung-laptop: add true rfkill support for swsmi Greg KH
2011-11-23  6:37     ` Corentin Chary
2011-11-23 20:29       ` Greg KH
2011-11-22 22:02 ` [PATCH 13/15] samsung-laptop: make the dmi check less strict Corentin Chary
2011-11-22 22:27   ` Greg KH
2011-11-23  7:17     ` Corentin Chary
2011-11-23 20:30       ` Greg KH
2011-11-22 22:02 ` [PATCH 14/15] samsung-laptop: dump model and version informations Corentin Chary
2011-11-22 22:28   ` Greg KH
2011-11-23  6:37     ` Corentin Chary
2011-11-22 22:02 ` [PATCH 15/15] samsung-laptop: promote myself as maintainer of samsung-laptop Corentin Chary
2011-11-22 22:29   ` Greg KH
2011-11-23  6:38     ` Corentin Chary
2011-11-23 16:46       ` David Herrmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1321999366-23784-13-git-send-email-corentincj@iksaif.net \
    --to=corentincj@iksaif.net \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg@redhat.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).