mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
sony-laptop: enumerate rfkill devices using SN06
SN06 makes sure we get back a longer buffer which seems to be necessary going forward as the SNC devices describes more and more devices (or features more precisely). Moreover SN06 should be called with only the descriptor offset to make sure we hit the rfkill controlling function (F124 or F135) with a 0 argument to get a full list of features. Signed-off-by: Mattia Dongili <malattia@linux.it> Tested-by: Miguel Rodríguez Pérez <miguelrp@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
d5a664a311
commit
528809c35f
1 changed files with 57 additions and 19 deletions
|
@ -1156,35 +1156,73 @@ static void sony_nc_rfkill_update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sony_nc_rfkill_setup(struct acpi_device *device)
|
static void sony_nc_rfkill_setup(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
int result, ret;
|
int offset;
|
||||||
|
u8 dev_code, i;
|
||||||
|
acpi_status status;
|
||||||
|
struct acpi_object_list params;
|
||||||
|
union acpi_object in_obj;
|
||||||
|
union acpi_object *device_enum;
|
||||||
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
|
|
||||||
if (sony_find_snc_handle(0x124) == -1) {
|
offset = sony_find_snc_handle(0x124);
|
||||||
if (sony_find_snc_handle(0x135) == -1)
|
if (offset == -1) {
|
||||||
return -1;
|
offset = sony_find_snc_handle(0x135);
|
||||||
|
if (offset == -1)
|
||||||
|
return;
|
||||||
else
|
else
|
||||||
sony_rfkill_handle = 0x135;
|
sony_rfkill_handle = 0x135;
|
||||||
} else
|
} else
|
||||||
sony_rfkill_handle = 0x124;
|
sony_rfkill_handle = 0x124;
|
||||||
|
dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle);
|
||||||
|
|
||||||
ret = sony_call_snc_handle(sony_rfkill_handle, 0xb00, &result);
|
/* need to read the whole buffer returned by the acpi call to SN06
|
||||||
if (ret) {
|
* here otherwise we may miss some features
|
||||||
printk(KERN_INFO DRV_PFX
|
*/
|
||||||
"Unable to enumerate rfkill devices: %x\n", ret);
|
params.count = 1;
|
||||||
return ret;
|
params.pointer = &in_obj;
|
||||||
|
in_obj.type = ACPI_TYPE_INTEGER;
|
||||||
|
in_obj.integer.value = offset;
|
||||||
|
status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms,
|
||||||
|
&buffer);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
dprintk("Radio device enumeration failed\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result & 0x1)
|
device_enum = (union acpi_object *) buffer.pointer;
|
||||||
sony_nc_setup_rfkill(device, SONY_WIFI);
|
if (!device_enum || device_enum->type != ACPI_TYPE_BUFFER) {
|
||||||
if (result & 0x2)
|
printk(KERN_ERR "Invalid SN06 return object 0x%.2x\n",
|
||||||
sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
|
device_enum->type);
|
||||||
if (result & 0x1c)
|
goto out_no_enum;
|
||||||
sony_nc_setup_rfkill(device, SONY_WWAN);
|
}
|
||||||
if (result & 0x20)
|
|
||||||
sony_nc_setup_rfkill(device, SONY_WIMAX);
|
|
||||||
|
|
||||||
return 0;
|
/* the buffer is filled with magic numbers describing the devices
|
||||||
|
* available, 0xff terminates the enumeration
|
||||||
|
*/
|
||||||
|
while ((dev_code = *(device_enum->buffer.pointer + i)) != 0xff &&
|
||||||
|
i < device_enum->buffer.length) {
|
||||||
|
i++;
|
||||||
|
dprintk("Radio devices, looking at 0x%.2x\n", dev_code);
|
||||||
|
|
||||||
|
if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI])
|
||||||
|
sony_nc_setup_rfkill(device, SONY_WIFI);
|
||||||
|
|
||||||
|
if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH])
|
||||||
|
sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
|
||||||
|
|
||||||
|
if ((0xf0 & dev_code) == 0x20 &&
|
||||||
|
!sony_rfkill_devices[SONY_WWAN])
|
||||||
|
sony_nc_setup_rfkill(device, SONY_WWAN);
|
||||||
|
|
||||||
|
if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX])
|
||||||
|
sony_nc_setup_rfkill(device, SONY_WIMAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_no_enum:
|
||||||
|
kfree(buffer.pointer);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sony_nc_add(struct acpi_device *device)
|
static int sony_nc_add(struct acpi_device *device)
|
||||||
|
|
Loading…
Reference in a new issue