86
87
struct bios_return {
92
enum hp_return_value {
93
HPWMI_RET_WRONG_SIGNATURE = 0x02,
94
HPWMI_RET_UNKNOWN_COMMAND = 0x03,
95
HPWMI_RET_UNKNOWN_CMDTYPE = 0x04,
96
HPWMI_RET_INVALID_PARAMETERS = 0x05,
99
enum hp_wireless2_bits {
100
HPWMI_POWER_STATE = 0x01,
101
HPWMI_POWER_SOFT = 0x02,
102
HPWMI_POWER_BIOS = 0x04,
103
HPWMI_POWER_HARD = 0x08,
106
#define IS_HWBLOCKED(x) ((x & (HPWMI_POWER_BIOS | HPWMI_POWER_HARD)) \
107
!= (HPWMI_POWER_BIOS | HPWMI_POWER_HARD))
108
#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
110
struct bios_rfkill2_device_state {
115
u16 subsys_vendor_id;
116
u16 subsys_product_id;
122
/* 7 devices fit into the 128 byte buffer */
123
#define HPWMI_MAX_RFKILL2_DEVICES 7
125
struct bios_rfkill2_state {
129
struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
92
132
static const struct key_entry hp_wmi_keymap[] = {
108
148
static struct rfkill *bluetooth_rfkill;
109
149
static struct rfkill *wwan_rfkill;
151
struct rfkill2_device {
154
struct rfkill *rfkill;
157
static int rfkill2_count;
158
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
111
160
static const struct dev_pm_ops hp_wmi_pm_ops = {
112
161
.resume = hp_wmi_resume_handler,
113
162
.restore = hp_wmi_resume_handler,
129
178
* query: The commandtype -> What should be queried
130
179
* write: The command -> 0 read, 1 write, 3 ODM specific
131
180
* buffer: Buffer used as input and/or output
132
* buffersize: Size of buffer
181
* insize: Size of input buffer
182
* outsize: Size of output buffer
134
184
* returns zero on success
135
185
* an HP WMI query specific error code (which is positive)
140
190
* size. E.g. Battery info query (0x7) is defined to have 1 byte input
141
191
* and 128 byte output. The caller would do:
142
192
* buffer = kzalloc(128, GFP_KERNEL);
143
* ret = hp_wmi_perform_query(0x7, 0, buffer, 128)
193
* ret = hp_wmi_perform_query(0x7, 0, buffer, 1, 128)
145
static int hp_wmi_perform_query(int query, int write, u32 *buffer,
195
static int hp_wmi_perform_query(int query, int write, void *buffer,
196
int insize, int outsize)
148
struct bios_return bios_return;
198
struct bios_return *bios_return;
150
200
union acpi_object *obj;
151
201
struct bios_args args = {
152
202
.signature = 0x55434553,
153
203
.command = write ? 0x2 : 0x1,
154
204
.commandtype = query,
155
.datasize = buffersize,
158
208
struct acpi_buffer input = { sizeof(struct bios_args), &args };
159
209
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
161
status = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
212
if (WARN_ON(insize > sizeof(args.data)))
214
memcpy(&args.data, buffer, insize);
216
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
163
218
obj = output.pointer;
172
bios_return = *((struct bios_return *)obj->buffer.pointer);
174
memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
227
bios_return = (struct bios_return *)obj->buffer.pointer;
228
rc = bios_return->return_code;
231
if (rc != HPWMI_RET_UNKNOWN_CMDTYPE)
232
pr_warn("query 0x%x returned error 0x%x\n", query, rc);
238
/* ignore output data */
243
actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
244
memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
245
memset(buffer + actual_outsize, 0, outsize - actual_outsize);
354
static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
356
int rfkill_id = (int)(long)data;
357
char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
359
if (hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 1,
360
buffer, sizeof(buffer), 0))
365
static const struct rfkill_ops hp_wmi_rfkill2_ops = {
366
.set_block = hp_wmi_rfkill2_set_block,
369
static int hp_wmi_rfkill2_refresh(void)
372
struct bios_rfkill2_state state;
374
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state,
379
for (i = 0; i < rfkill2_count; i++) {
380
int num = rfkill2[i].num;
381
struct bios_rfkill2_device_state *devstate;
382
devstate = &state.device[num];
384
if (num >= state.count ||
385
devstate->rfkill_id != rfkill2[i].id) {
386
pr_warn("power configuration of the wireless devices unexpectedly changed\n");
390
rfkill_set_states(rfkill2[i].rfkill,
391
IS_SWBLOCKED(devstate->power),
392
IS_HWBLOCKED(devstate->power));
282
398
static ssize_t show_display(struct device *dev, struct device_attribute *attr,
402
516
case HPWMI_BEZEL_BUTTON:
403
517
ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
405
520
sizeof(key_code));
409
524
if (!sparse_keymap_report_event(hp_wmi_input_dev,
410
525
key_code, 1, true))
411
printk(KERN_INFO PREFIX "Unknown key code - 0x%x\n",
526
pr_info("Unknown key code - 0x%x\n", key_code);
414
528
case HPWMI_WIRELESS:
530
hp_wmi_rfkill2_refresh();
416
535
rfkill_set_states(wifi_rfkill,
417
536
hp_wmi_get_sw_state(HPWMI_WIFI),
426
545
hp_wmi_get_hw_state(HPWMI_WWAN));
428
547
case HPWMI_CPU_BATTERY_THROTTLE:
429
printk(KERN_INFO PREFIX UNIMP "CPU throttle because of 3 Cell"
430
" battery event detected\n");
548
pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
432
550
case HPWMI_LOCK_SWITCH:
435
printk(KERN_INFO PREFIX "Unknown event_id - %d - 0x%x\n",
436
event_id, event_data);
553
pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
502
619
device_remove_file(&device->dev, &dev_attr_tablet);
505
static int __devinit hp_wmi_bios_setup(struct platform_device *device)
622
static int __devinit hp_wmi_rfkill_setup(struct platform_device *device)
508
625
int wireless = 0;
510
627
err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless,
628
sizeof(wireless), sizeof(wireless));
515
err = device_create_file(&device->dev, &dev_attr_display);
517
goto add_sysfs_error;
518
err = device_create_file(&device->dev, &dev_attr_hddtemp);
520
goto add_sysfs_error;
521
err = device_create_file(&device->dev, &dev_attr_als);
523
goto add_sysfs_error;
524
err = device_create_file(&device->dev, &dev_attr_dock);
526
goto add_sysfs_error;
527
err = device_create_file(&device->dev, &dev_attr_tablet);
529
goto add_sysfs_error;
531
632
if (wireless & 0x1) {
532
633
wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
533
634
RFKILL_TYPE_WLAN,
574
675
register_wwan_err:
575
676
rfkill_destroy(wwan_rfkill);
576
678
if (bluetooth_rfkill)
577
679
rfkill_unregister(bluetooth_rfkill);
578
680
register_bluetooth_error:
579
681
rfkill_destroy(bluetooth_rfkill);
682
bluetooth_rfkill = NULL;
581
684
rfkill_unregister(wifi_rfkill);
582
685
register_wifi_error:
583
686
rfkill_destroy(wifi_rfkill);
691
static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device)
694
struct bios_rfkill2_state state;
695
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state,
700
if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
701
pr_warn("unable to parse 0x1b query output\n");
705
for (i = 0; i < state.count; i++) {
706
struct rfkill *rfkill;
707
enum rfkill_type type;
709
switch (state.device[i].radio_type) {
711
type = RFKILL_TYPE_WLAN;
714
case HPWMI_BLUETOOTH:
715
type = RFKILL_TYPE_BLUETOOTH;
716
name = "hp-bluetooth";
719
type = RFKILL_TYPE_WWAN;
723
pr_warn("unknown device type 0x%x\n",
724
state.device[i].radio_type);
728
if (!state.device[i].vendor_id) {
729
pr_warn("zero device %d while %d reported\n",
734
rfkill = rfkill_alloc(name, &device->dev, type,
735
&hp_wmi_rfkill2_ops, (void *)(long)i);
741
rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
742
rfkill2[rfkill2_count].num = i;
743
rfkill2[rfkill2_count].rfkill = rfkill;
745
rfkill_init_sw_state(rfkill,
746
IS_SWBLOCKED(state.device[i].power));
747
rfkill_set_hw_state(rfkill,
748
IS_HWBLOCKED(state.device[i].power));
750
if (!(state.device[i].power & HPWMI_POWER_BIOS))
751
pr_info("device %s blocked by BIOS\n", name);
753
err = rfkill_register(rfkill);
755
rfkill_destroy(rfkill);
764
for (; rfkill2_count > 0; rfkill2_count--) {
765
rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
766
rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
771
static int __devinit hp_wmi_bios_setup(struct platform_device *device)
775
/* clear detected rfkill devices */
777
bluetooth_rfkill = NULL;
781
if (hp_wmi_rfkill_setup(device))
782
hp_wmi_rfkill2_setup(device);
784
err = device_create_file(&device->dev, &dev_attr_display);
786
goto add_sysfs_error;
787
err = device_create_file(&device->dev, &dev_attr_hddtemp);
789
goto add_sysfs_error;
790
err = device_create_file(&device->dev, &dev_attr_als);
792
goto add_sysfs_error;
793
err = device_create_file(&device->dev, &dev_attr_dock);
795
goto add_sysfs_error;
796
err = device_create_file(&device->dev, &dev_attr_tablet);
798
goto add_sysfs_error;
585
802
cleanup_sysfs(device);