Platform: hp-wmi: add rfkill support for integrated GPS
authorTrepák Vilmos <trepo@netcomga.sk>
Thu, 11 Oct 2012 10:51:00 +0000 (12:51 +0200)
committerMatthew Garrett <matthew.garrett@nebula.com>
Sun, 24 Feb 2013 22:49:56 +0000 (14:49 -0800)
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>
drivers/platform/x86/hp-wmi.c

index 1dde7accf27ccb9f4b9150a3927e7c9e8b0a3189..2179c03b94deea90aaa05d69ba5fcb51f17785bd 100644 (file)
@@ -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;
 }