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>
This commit is contained in:
Trepák Vilmos 2012-10-11 12:51:00 +02:00 committed by Matthew Garrett
parent 5f3511d2a6
commit 4fca7ce39f

View File

@ -60,6 +60,7 @@ enum hp_wmi_radio {
HPWMI_WIFI = 0, HPWMI_WIFI = 0,
HPWMI_BLUETOOTH = 1, HPWMI_BLUETOOTH = 1,
HPWMI_WWAN = 2, HPWMI_WWAN = 2,
HPWMI_GPS = 3,
}; };
enum hp_wmi_event_ids { 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 *wifi_rfkill;
static struct rfkill *bluetooth_rfkill; static struct rfkill *bluetooth_rfkill;
static struct rfkill *wwan_rfkill; static struct rfkill *wwan_rfkill;
static struct rfkill *gps_rfkill;
struct rfkill2_device { struct rfkill2_device {
u8 id; u8 id;
@ -543,6 +545,10 @@ static void hp_wmi_notify(u32 value, void *context)
rfkill_set_states(wwan_rfkill, rfkill_set_states(wwan_rfkill,
hp_wmi_get_sw_state(HPWMI_WWAN), hp_wmi_get_sw_state(HPWMI_WWAN),
hp_wmi_get_hw_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; break;
case HPWMI_CPU_BATTERY_THROTTLE: case HPWMI_CPU_BATTERY_THROTTLE:
pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n"); 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); (void *) HPWMI_WWAN);
if (!wwan_rfkill) { if (!wwan_rfkill) {
err = -ENOMEM; err = -ENOMEM;
goto register_bluetooth_error; goto register_gps_error;
} }
rfkill_init_sw_state(wwan_rfkill, rfkill_init_sw_state(wwan_rfkill,
hp_wmi_get_sw_state(HPWMI_WWAN)); 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; 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; return 0;
register_wwan_err: register_wwan_err:
rfkill_destroy(wwan_rfkill); rfkill_destroy(wwan_rfkill);
wwan_rfkill = NULL; wwan_rfkill = NULL;
if (gps_rfkill)
rfkill_unregister(gps_rfkill);
register_gps_error:
rfkill_destroy(gps_rfkill);
gps_rfkill = NULL;
if (bluetooth_rfkill) if (bluetooth_rfkill)
rfkill_unregister(bluetooth_rfkill); rfkill_unregister(bluetooth_rfkill);
register_bluetooth_error: register_bluetooth_error:
@ -729,6 +758,10 @@ static int hp_wmi_rfkill2_setup(struct platform_device *device)
type = RFKILL_TYPE_WWAN; type = RFKILL_TYPE_WWAN;
name = "hp-wwan"; name = "hp-wwan";
break; break;
case HPWMI_GPS:
type = RFKILL_TYPE_GPS;
name = "hp-gps";
break;
default: default:
pr_warn("unknown device type 0x%x\n", pr_warn("unknown device type 0x%x\n",
state.device[i].radio_type); state.device[i].radio_type);
@ -786,6 +819,7 @@ static int hp_wmi_bios_setup(struct platform_device *device)
wifi_rfkill = NULL; wifi_rfkill = NULL;
bluetooth_rfkill = NULL; bluetooth_rfkill = NULL;
wwan_rfkill = NULL; wwan_rfkill = NULL;
gps_rfkill = NULL;
rfkill2_count = 0; rfkill2_count = 0;
if (hp_wmi_rfkill_setup(device)) 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_unregister(wwan_rfkill);
rfkill_destroy(wwan_rfkill); rfkill_destroy(wwan_rfkill);
} }
if (gps_rfkill) {
rfkill_unregister(gps_rfkill);
rfkill_destroy(gps_rfkill);
}
return 0; return 0;
} }
@ -870,6 +908,10 @@ static int hp_wmi_resume_handler(struct device *device)
rfkill_set_states(wwan_rfkill, rfkill_set_states(wwan_rfkill,
hp_wmi_get_sw_state(HPWMI_WWAN), hp_wmi_get_sw_state(HPWMI_WWAN),
hp_wmi_get_hw_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; return 0;
} }