Browse Source

Platform: hp-wmi: add rfkill support for integrated GPS

Add rfkill support for the GPS radio found in HP laptops (HP Elitebook 2170p and the like)
using the Ericsson F5321/H5321 Mobile Broadband Module.

Signed-off-by: Viliam Trepák <trepo@netcomga.sk>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Trepák Vilmos 12 years ago
parent
commit
4fca7ce39f
1 changed files with 43 additions and 1 deletions
  1. 43 1
      drivers/platform/x86/hp-wmi.c

+ 43 - 1
drivers/platform/x86/hp-wmi.c

@@ -60,6 +60,7 @@ enum hp_wmi_radio {
 	HPWMI_WIFI = 0,
 	HPWMI_BLUETOOTH = 1,
 	HPWMI_WWAN = 2,
+	HPWMI_GPS = 3,
 };
 
 enum hp_wmi_event_ids {
@@ -147,6 +148,7 @@ static struct platform_device *hp_wmi_platform_dev;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
+static struct rfkill *gps_rfkill;
 
 struct rfkill2_device {
 	u8 id;
@@ -543,6 +545,10 @@ static void hp_wmi_notify(u32 value, void *context)
 			rfkill_set_states(wwan_rfkill,
 					  hp_wmi_get_sw_state(HPWMI_WWAN),
 					  hp_wmi_get_hw_state(HPWMI_WWAN));
+		if (gps_rfkill)
+			rfkill_set_states(gps_rfkill,
+					  hp_wmi_get_sw_state(HPWMI_GPS),
+					  hp_wmi_get_hw_state(HPWMI_GPS));
 		break;
 	case HPWMI_CPU_BATTERY_THROTTLE:
 		pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
@@ -670,7 +676,7 @@ static int hp_wmi_rfkill_setup(struct platform_device *device)
 					   (void *) HPWMI_WWAN);
 		if (!wwan_rfkill) {
 			err = -ENOMEM;
-			goto register_bluetooth_error;
+			goto register_gps_error;
 		}
 		rfkill_init_sw_state(wwan_rfkill,
 				     hp_wmi_get_sw_state(HPWMI_WWAN));
@@ -681,10 +687,33 @@ static int hp_wmi_rfkill_setup(struct platform_device *device)
 			goto register_wwan_err;
 	}
 
+	if (wireless & 0x8) {
+		gps_rfkill = rfkill_alloc("hp-gps", &device->dev,
+						RFKILL_TYPE_GPS,
+						&hp_wmi_rfkill_ops,
+						(void *) HPWMI_GPS);
+		if (!gps_rfkill) {
+			err = -ENOMEM;
+			goto register_bluetooth_error;
+		}
+		rfkill_init_sw_state(gps_rfkill,
+				     hp_wmi_get_sw_state(HPWMI_GPS));
+		rfkill_set_hw_state(bluetooth_rfkill,
+				    hp_wmi_get_hw_state(HPWMI_GPS));
+		err = rfkill_register(gps_rfkill);
+		if (err)
+			goto register_gps_error;
+	}
+
 	return 0;
 register_wwan_err:
 	rfkill_destroy(wwan_rfkill);
 	wwan_rfkill = NULL;
+	if (gps_rfkill)
+		rfkill_unregister(gps_rfkill);
+register_gps_error:
+	rfkill_destroy(gps_rfkill);
+	gps_rfkill = NULL;
 	if (bluetooth_rfkill)
 		rfkill_unregister(bluetooth_rfkill);
 register_bluetooth_error:
@@ -729,6 +758,10 @@ static int hp_wmi_rfkill2_setup(struct platform_device *device)
 			type = RFKILL_TYPE_WWAN;
 			name = "hp-wwan";
 			break;
+		case HPWMI_GPS:
+			type = RFKILL_TYPE_GPS;
+			name = "hp-gps";
+			break;
 		default:
 			pr_warn("unknown device type 0x%x\n",
 				state.device[i].radio_type);
@@ -786,6 +819,7 @@ static int hp_wmi_bios_setup(struct platform_device *device)
 	wifi_rfkill = NULL;
 	bluetooth_rfkill = NULL;
 	wwan_rfkill = NULL;
+	gps_rfkill = NULL;
 	rfkill2_count = 0;
 
 	if (hp_wmi_rfkill_setup(device))
@@ -835,6 +869,10 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
 		rfkill_unregister(wwan_rfkill);
 		rfkill_destroy(wwan_rfkill);
 	}
+	if (gps_rfkill) {
+		rfkill_unregister(gps_rfkill);
+		rfkill_destroy(gps_rfkill);
+	}
 
 	return 0;
 }
@@ -870,6 +908,10 @@ static int hp_wmi_resume_handler(struct device *device)
 		rfkill_set_states(wwan_rfkill,
 				  hp_wmi_get_sw_state(HPWMI_WWAN),
 				  hp_wmi_get_hw_state(HPWMI_WWAN));
+	if (gps_rfkill)
+		rfkill_set_states(gps_rfkill,
+				  hp_wmi_get_sw_state(HPWMI_GPS),
+				  hp_wmi_get_hw_state(HPWMI_GPS));
 
 	return 0;
 }