X86 platform drivers
 help / color / mirror / Atom feed
From: Marco Chiappero <marco@absence.it>
To: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: platform-driver-x86@vger.kernel.org, Mattia Dongili <malattia@linux.it>
Subject: [PATCH V2 12/14] sony-laptop: rfkill improvements
Date: Fri, 09 Sep 2011 19:01:15 +0200	[thread overview]
Message-ID: <1315587675.3613.103.camel@vesuvio> (raw)
In-Reply-To: <1315585214.3613.51.camel@vesuvio>

This patch introduces some rfkill improvements in terms of both code
cleaning and support extension. More precisely:

- removed any handle autodetection inside the setup function as it's now
provided by the caller
- rfkill type now persistent, using the hardware capability of storing
the wireless devices power state
- added support for newer WWAN modules
- removed some global variables now included in a few struct for a
cleaner code. These structs have been placed close to the rfkill
functions for better readability
- minor code improvements

Signed-off-by: Marco Chiappero <marco@absence.it> 
--- 

--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -141,19 +141,6 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
 		 "(default: 0)");
 
 
-enum sony_nc_rfkill {
-	SONY_WIFI,
-	SONY_BLUETOOTH,
-	SONY_WWAN,
-	SONY_WIMAX,
-	N_SONY_RFKILL,
-};
-
-static unsigned int sony_rfkill_handle;
-static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
-static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700,
0x900};
-static void sony_nc_rfkill_update(void);
-
 /*********** Input Devices ***********/
 
 #define SONY_LAPTOP_BUF_SIZE	128
@@ -1204,30 +1191,51 @@ static int sony_nc_hotkeys_decode(unsign
 	return ret;
 }
 
+enum sony_nc_rfkill {
+	SONY_WIFI,
+	SONY_BLUETOOTH,
+	SONY_WWAN,
+	SONY_WIMAX,
+	N_SONY_RFKILL,
+};
+struct snc_rfkill_data {
+	unsigned int handle;
+	struct rfkill *devices[N_SONY_RFKILL];
+	const unsigned int address[N_SONY_RFKILL];
+};
+static struct snc_rfkill_data snc_rfkill = {
+	0, {NULL}, {0x300, 0x500, 0x700, 0x900}
+};
+
 static void sony_nc_rfkill_cleanup(void)
 {
 	int i;
 
 	for (i = 0; i < N_SONY_RFKILL; i++) {
-		if (sony_rfkill_devices[i]) {
-			rfkill_unregister(sony_rfkill_devices[i]);
-			rfkill_destroy(sony_rfkill_devices[i]);
+		if (snc_rfkill.devices[i]) {
+			rfkill_unregister(snc_rfkill.devices[i]);
+			rfkill_destroy(snc_rfkill.devices[i]);
 		}
 	}
 }
 
 static int sony_nc_rfkill_set(void *data, bool blocked)
 {
-	unsigned int result;
-	unsigned int argument = sony_rfkill_address[(long) data] + 0x100;
+	unsigned int result, argument = snc_rfkill.address[(long) data];
 
+	/* do not force an already set state */
+	sony_call_snc_handle(snc_rfkill.handle, argument, &result);
+	if ((result & 0x1) == !blocked)
+		return 0;
+
+	argument += 0x100;
 	if (!blocked)
 		argument |= 0xff0000;
 
-	return sony_call_snc_handle(sony_rfkill_handle, argument, &result);
+	return sony_call_snc_handle(snc_rfkill.handle, argument, &result);
 }
 
-static const struct rfkill_ops sony_rfkill_ops = {
+static const struct rfkill_ops snc_rfkill_ops = {
 	.set_block = sony_nc_rfkill_set,
 };
 
@@ -1239,7 +1247,7 @@ static int sony_nc_setup_rfkill(struct a
 	enum rfkill_type type;
 	const char *name;
 	unsigned int result;
-	bool hwblock;
+	bool hwblock, swblock;
 
 	switch (nc_type) {
 	case SONY_WIFI:
@@ -1263,12 +1271,19 @@ static int sony_nc_setup_rfkill(struct a
 	}
 
 	rfk = rfkill_alloc(name, &device->dev, type,
-			   &sony_rfkill_ops, (void *)nc_type);
+			   &snc_rfkill_ops, (void *)nc_type);
 	if (!rfk)
 		return -ENOMEM;
 
-	sony_call_snc_handle(sony_rfkill_handle, 0x200, &result);
+	sony_call_snc_handle(snc_rfkill.handle, 0x200, &result);
 	hwblock = !(result & 0x1);
+
+	result = 0;
+	sony_call_snc_handle(snc_rfkill.handle, snc_rfkill.address[nc_type],
+				&result);
+	swblock = !(result & 0x2);
+
+	rfkill_init_sw_state(rfk, swblock);
 	rfkill_set_hw_state(rfk, hwblock);
 
 	err = rfkill_register(rfk);
@@ -1276,7 +1291,7 @@ static int sony_nc_setup_rfkill(struct a
 		rfkill_destroy(rfk);
 		return err;
 	}
-	sony_rfkill_devices[nc_type] = rfk;
+	snc_rfkill.devices[nc_type] = rfk;
 	return err;
 }
 
@@ -1284,51 +1299,35 @@ static void sony_nc_rfkill_update(void)
 {
 	enum sony_nc_rfkill i;
 	unsigned int result;
-	bool hwblock;
+	bool hwblock, swblock;
 
-	sony_call_snc_handle(sony_rfkill_handle, 0x200, &result);
+	sony_call_snc_handle(snc_rfkill.handle, 0x200, &result);
 	hwblock = !(result & 0x1);
 
 	for (i = 0; i < N_SONY_RFKILL; i++) {
-		unsigned int argument = sony_rfkill_address[i];
+		unsigned int argument = snc_rfkill.address[i];
 
-		if (!sony_rfkill_devices[i])
+		if (!snc_rfkill.devices[i])
 			continue;
 
-		if (hwblock) {
-			if (rfkill_set_hw_state(sony_rfkill_devices[i], true))
-				/* we already know we're blocked */ ;
-
-			continue;
-		}
+		sony_call_snc_handle(snc_rfkill.handle, argument, &result);
+		swblock = !(result & 0x2);
 
-		sony_call_snc_handle(sony_rfkill_handle, argument, &result);
-		rfkill_set_states(sony_rfkill_devices[i],
-				  !(result & 0xf), false);
+		rfkill_set_states(snc_rfkill.devices[i], swblock, hwblock);
 	}
 }
 
-static int sony_nc_rfkill_setup(struct acpi_device *device)
+static int sony_nc_rfkill_setup(struct acpi_device *device, unsigned
int handle)
 {
 #define	RFKILL_BUFF_SIZE 8
 	u8 dev_code, i, buff[RFKILL_BUFF_SIZE] = { 0 };
-	int offset;
 
-	offset = sony_find_snc_handle(0x124);
-	if (offset == -1) {
-		offset = sony_find_snc_handle(0x135);
-		if (offset == -1)
-			return 0;
-		else
-			sony_rfkill_handle = 0x135;
-	} else
-		sony_rfkill_handle = 0x124;
-	dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle);
+	snc_rfkill.handle = handle;
 
 	/* need to read the whole buffer returned by the acpi call to SN06
 	 * here otherwise we may miss some features
 	 */
-	if (sony_call_snc_handle_buffer(sony_rfkill_handle, 0x000,
+	if (sony_call_snc_handle_buffer(snc_rfkill.handle, 0x000,
 					buff, RFKILL_BUFF_SIZE) < 0)
 		return -EIO;
 
@@ -1341,19 +1340,38 @@ static int sony_nc_rfkill_setup(struct a
 		if (dev_code == 0xff)
 			break;
 
+		/*
+		   known codes:
+
+		   0x00	WLAN
+		   0x10 BLUETOOTH
+		   0x20 WWAN GPRS-EDGE
+		   0x21 WWAN HSDPA
+		   0x22 WWAN EV-DO
+		   0x23 WWAN GPS
+		   0x25	Gobi WWAN no GPS
+		   0x26 Gobi WWAN + GPS
+		   0x28	Gobi WWAN no GPS
+		   0x29 Gobi WWAN + GPS
+		   0x50	Gobi WWAN no GPS
+		   0x51 Gobi WWAN + GPS
+		   0x30	WIMAX
+		   0x70 no SIM card slot
+		   0x71 SIM card slot
+		*/
 		dprintk("Radio devices, looking at 0x%.2x\n", dev_code);
 
-		if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI])
+		if (dev_code == 0 && !snc_rfkill.devices[SONY_WIFI])
 			sony_nc_setup_rfkill(device, SONY_WIFI);
 
-		if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH])
+		if (dev_code == 0x10 && !snc_rfkill.devices[SONY_BLUETOOTH])
 			sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
 
-		if ((0xf0 & dev_code) == 0x20 &&
-				!sony_rfkill_devices[SONY_WWAN])
+		if (((0xf0 & dev_code) == 0x20 || (0xf0 & dev_code) == 0x50) &&
+				!snc_rfkill.devices[SONY_WWAN])
 			sony_nc_setup_rfkill(device, SONY_WWAN);
 
-		if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX])
+		if (dev_code == 0x30 && !snc_rfkill.devices[SONY_WIMAX])
 			sony_nc_setup_rfkill(device, SONY_WIMAX);
 	}
 
@@ -1717,7 +1735,7 @@ static int sony_nc_handles_setup(struct 
 			ret = sony_nc_kbd_backlight_setup(pd, handle);
 		case 0x0124:
 		case 0x0135:
-			ret = sony_nc_rfkill_setup(sony_nc_acpi_device);
+			ret = sony_nc_rfkill_setup(sony_nc_acpi_device, handle);
 			break;
 		default:
 			continue;

  parent reply	other threads:[~2011-09-09 17:01 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-09 16:20 [PATCH V2 0/14] miscellaneous code improvements for sony-laptop Marco Chiappero
2011-09-09 16:34 ` [PATCH V2 1/14] sony-laptop: fix potential improper handle usage Marco Chiappero
2011-09-09 16:39 ` [PATCH V2 2/14] sony-laptop: use usigned data type when calling ACPI methods Marco Chiappero
2011-09-09 16:41 ` [PATCH V2 3/14] sony-laptop: replace simple_strtoul with strict_strtoul Marco Chiappero
2011-09-09 16:45 ` [PATCH V2 4/14] sony-laptop: add new ACPI SN06 method helper functions Marco Chiappero
2011-09-09 16:47 ` [PATCH V2 5/14] sony-laptop: new SNC setup and cleanup functions Marco Chiappero
2011-09-09 16:49 ` [PATCH V2 6/14] sony-laptop: new sony_nc_handles_resume function Marco Chiappero
2011-09-09 16:51 ` [PATCH V2 7/14] sony-laptop: sony_nc_function_setup modifications Marco Chiappero
2011-09-09 16:53 ` [PATCH V2 8/14] sony-laptop: sony_nc_notify rewritten and improved Marco Chiappero
2011-09-09 16:54 ` [PATCH V2 9/14] sony-laptop: sony_walk_callback moved for better readability Marco Chiappero
2011-09-09 16:56 ` [PATCH V2 10/14] sony-laptop: code style fixes Marco Chiappero
2011-09-09 16:58 ` [PATCH V2 11/14] sony-laptop: keyboard backlight support extended to newer Vaios Marco Chiappero
2011-09-09 17:01 ` Marco Chiappero [this message]
2011-09-09 17:02 ` [PATCH V2 13/14] sony-laptop: input core improvements Marco Chiappero
2011-09-09 17:04 ` [PATCH V2 14/14] sony-laptop: Documentation changes Marco Chiappero
2011-09-10  4:03 ` [PATCH V2 0/14] miscellaneous code improvements for sony-laptop Mattia Dongili
2011-09-13 20:58   ` Marco Chiappero
2011-09-13 20:43 ` [PATCH V2 RESEND 1/14] sony-laptop: fix potential improper handle usage Marco Chiappero
2011-09-13 20:45 ` [PATCH V2 RESEND 2/14] sony-laptop: use usigned data type when calling ACPI methods Marco Chiappero
2011-09-13 20:45 ` [PATCH V2 RESEND 3/14] sony-laptop: replace simple_strtoul with strict_strtoul Marco Chiappero
2011-09-13 20:45 ` [PATCH V2 RESEND 4/14] sony-laptop: add new ACPI SN06 method helper functions Marco Chiappero
2011-09-13 20:46 ` [PATCH V2 RESEND 5/14] sony-laptop: new SNC setup and cleanup functions Marco Chiappero
2011-09-13 20:47 ` [PATCH V2 RESEND 6/14] sony-laptop: new sony_nc_handles_resume function Marco Chiappero
2011-09-13 20:47 ` [PATCH V2 RESEND 7/14] sony-laptop: sony_nc_function_setup modifications Marco Chiappero
2011-09-13 20:47 ` [PATCH V2 RESEND 8/14] sony-laptop: sony_nc_notify rewritten and improved Marco Chiappero
2011-09-13 20:47 ` [PATCH V2 RESEND 9/14] sony-laptop: sony_walk_callback moved for better readability Marco Chiappero
2011-09-13 20:47 ` [PATCH V2 RESEND 10/14] sony-laptop: code style fixes Marco Chiappero
2011-09-13 20:53 ` [PATCH V2 RESEND 11/14] sony-laptop: keyboard backlight support extended to newer Vaios Marco Chiappero
2011-09-13 20:53 ` [PATCH V2 RESEND 12/14] sony-laptop: rfkill improvements Marco Chiappero
2011-09-13 20:53 ` [PATCH V2 RESEND 13/14] sony-laptop: input core improvements Marco Chiappero
2011-09-13 20:53 ` [PATCH V2 RESEND 14/14] sony-laptop: documentation changes Marco Chiappero

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=1315587675.3613.103.camel@vesuvio \
    --to=marco@absence.it \
    --cc=malattia@linux.it \
    --cc=mjg59@srcf.ucam.org \
    --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