Find the answer to your Linux question:
Results 1 to 9 of 9
Like Tree1Likes
  • 1 Post By Padfoots
Hi, I am trying to get the accelerometer working on my Acer Iconia Tab W501 In windows, it reported as a BMA150 device, so I have that driver loading on ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jun 2012
    Posts
    5

    Accelerometer help needed - Arch Linux - Kernel 3.4


    Hi,
    I am trying to get the accelerometer working on my Acer Iconia Tab W501
    In windows, it reported as a BMA150 device, so I have that driver loading on boot.
    After months of googling and making a mess in /sys, I still have not got the device working. I was working under the assumption that the device hangs off the i2c bus, but a "lucky google" today uncovered that it is showing up through acpi - acpid is present in my daemons array of rc.conf and the kernel module acer_wmi is also loaded.
    The device is certainly sending signals to the kernel. Upon boot, dmesg ends up as follows:
    Code:
    [   11.689709] ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
    [   12.108374] EXT4-fs (sda2): re-mounted. Opts: commit=0
    [   12.148026] EXT4-fs (sda3): re-mounted. Opts: commit=0
    [   17.759006] FS-Cache: Loaded
    [   17.780371] FS-Cache: Netfs 'cifs' registered for caching
    [   17.816097] CIFS VFS: default security mechanism requested.  The default security mechanism will be upgraded from ntlm to ntlmv2 in kernel release 3.3
    [   22.459133] wlan0: no IPv6 routers present
    Now, if I rotate the device, and run dmesg again, I have the following:
    Code:
    [ 1255.189705] acer_wmi: Unknown function number - 5 - 1
    [ 1257.363688] acer_wmi: Unknown function number - 5 - 1
    [ 1268.268809] acer_wmi: Unknown function number - 5 - 1
    [ 1268.409270] acer_wmi: Unknown function number - 5 - 1
    [ 1308.653700] acer_wmi: Unknown function number - 5 - 1
    [ 1308.784623] acer_wmi: Unknown function number - 5 - 1
    acpi -V does not show the device:
    Code:
    Battery 0: Full, 100%
    Battery 0: design capacity 2865 mAh, last full capacity 2678 mAh = 93%
    Adapter 0: on-line
    Thermal 0: ok, 59.0 degrees C
    Thermal 0: trip point 0 switches to mode critical at temperature 87.0 degrees C
    Thermal 0: trip point 1 switches to mode passive at temperature 77.0 degrees C
    Cooling 0: LCD 0 of 9
    Cooling 1: Processor 0 of 3
    Cooling 2: Processor 0 of 10
    nor is it configured on boot - dmesg | grep ACPI:
    Code:
    [    0.404389] pnp: PnP ACPI init
    [    0.404443] ACPI: bus type pnp registered
    [    0.405020] pnp 00:00: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
    [    0.405295] system 00:01: Plug and Play ACPI device, IDs PNP0c02 (active)
    [    0.405829] pnp 00:02: Plug and Play ACPI device, IDs PNP0103 (active)
    [    0.406106] pnp 00:03: Plug and Play ACPI device, IDs PNP0200 (active)
    [    0.406268] pnp 00:04: Plug and Play ACPI device, IDs PNP0c04 (active)
    [    0.406514] pnp 00:05: Plug and Play ACPI device, IDs PNP0b00 (active)
    [    0.406613] pnp 00:06: Plug and Play ACPI device, IDs PNP0800 (active)
    [    0.406774] pnp 00:07: Plug and Play ACPI device, IDs PNP0303 (active)
    [    0.407104] system 00:08: Plug and Play ACPI device, IDs PNP0c02 (active)
    [    0.407390] system 00:09: Plug and Play ACPI device, IDs PNP0c01 (active)
    [    0.408373] pnp: PnP ACPI: found 10 devices
    [    0.408377] ACPI: ACPI bus type pnp unregistered
    [    4.684770] ACPI: Power Button [PWRB]
    [    4.685381] ACPI: acpi_idle registered with cpuidle
    [    4.686148] ACPI: Lid Switch [LID]
    [    4.692517] ACPI: Power Button [PWRF]
    [    4.696710] [Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness
    [    4.719486] ACPI: Video Device [VGA] (multi-head: yes  rom: no  post: no)
    [    4.729977] ACPI: AC Adapter [AC0] (on-line)
    [    4.746949] ACPI: Battery Slot [BAT0] (battery present)
    [    4.824909] ACPI: Thermal Zone [THRM] (61 C)
    [    5.220895] acer_wmi: Acer Laptop ACPI-WMI Extras
    Yet, running acpi_listen generates the following when the tablet is rotated:
    Code:
     PNP0C14:00 000000bc 00000000
     PNP0C14:00 000000bc 00000000
     PNP0C14:00 000000bc 00000000
     PNP0C14:00 000000bc 00000000
    So, it would seem the device is working and sending data to the kernel/drivers, it appears some config is needed to get it properly recognised and an entry in /dev generated.
    Really hoping there is an acpi expert around who may be able to help me get the device properly recognised and configures, ideally, as a /dev/input/js*
    Cheers.

  2. #2
    Just Joined!
    Join Date
    Jun 2012
    Posts
    28
    Just to clarify... Did you already run
    Code:
    # modprobe -v acer_wmi
    ?

  3. #3
    Just Joined!
    Join Date
    Jun 2012
    Posts
    5
    Quote Originally Posted by shellscriptcoder View Post
    Just to clarify... Did you already run
    Code:
    # modprobe -v acer_wmi
    ?
    The module is auto loaded on boot. However, the following is output when I:

    Code:
    # rmmod acer_wmi
    # modprobe -v acer_wmi
    insmod /lib/modules/3.4.0-1-ARCH/kernel/drivers/platform/x86/acer-wmi.ko.gz
    
    # dmesg
    ......
    [  353.064277] acer_wmi: Acer Laptop ACPI-WMI Extras
    [  353.064450] acer_wmi: Function bitmap for Communication Button: 0x841
    [  353.064467] acer_wmi: Brightness must be controlled by acpi video driver
    [  353.067279] input: Acer WMI hotkeys as /devices/virtual/input/input14

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Guru
    Join Date
    Jul 2004
    Posts
    4,593
    Are you just trying to rotate the screen when you rotate the tablet? I have accomplished this on my Azpen X1 tablet. It was originally a Windows 7 tablet, so your solution may be different. I found that when using a Gnome based desktop, that the tablet would switch workspaces when rotated. I then created four scripts to rotate the screen in the four positions, and then substituted them for the workspace shortcuts.

    I made an extensive thread about it here:

    Rotating Screen/Touchpad On Linux
    Last edited by waterhead; 06-05-2012 at 02:29 PM.
    Please do not send Private Messages to me with requests for help. I will not reply.

  6. #5
    Just Joined!
    Join Date
    Jun 2012
    Posts
    5
    Quote Originally Posted by waterhead View Post
    Are you just trying to rotate the screen when you rotate the tablet? I have accomplished this on my Azpen X1 tablet. It was originally a Windows 7 tablet, so your solution may be different. I found that when using a Gnome based desktop, that the tablet would switch workspaces when rotated. I then created four scripts to rotate the screen in the four positions, and then substituted them for the workspace shortcuts.
    Hi Waterhead,

    That is not the issue I am having. The issue is getting the accelerometer to work in the first place. It is sending data through the kernel, hence the error messages I am getting, but it it not properly recognised and configured as a device for me to even link turning the device with rotating the screen.

    Thankyou anyway, but what I need is help getting the device properly recognised and configured.

    Thanks.

  7. #6
    Just Joined!
    Join Date
    Jun 2012
    Posts
    28
    Ah. I may have found something - did you apply this patch to drivers/platform/x86/acer-wmi.c ?
    Code:
    diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
    index c1a3fd8..edb6bad 100644
    --- a/drivers/platform/x86/acer-wmi.c
    +++ b/drivers/platform/x86/acer-wmi.c
    @@ -95,6 +95,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
    
     enum acer_wmi_event_ids {
     	WMID_HOTKEY_EVENT = 0x1,
    +	WMID_ACCEL_EVENT = 0x5,
     };
    
     static const struct key_entry acer_wmi_keymap[] = {
    @@ -130,6 +131,7 @@ static const struct key_entry acer_wmi_keymap[] = {
     };
    
     static struct input_dev *acer_wmi_input_dev;
    +static struct input_dev *acer_wmi_accel_dev;
    
     struct event_return_value {
     	u8 function;
    @@ -200,6 +202,7 @@ struct hotkey_function_type_aa {
     #define ACER_CAP_BLUETOOTH		(1<<2)
     #define ACER_CAP_BRIGHTNESS		(1<<3)
     #define ACER_CAP_THREEG			(1<<4)
    +#define ACER_CAP_ACCEL			(1<<5)
     #define ACER_CAP_ANY			(0xFFFFFFFF)
    
     /*
    @@ -1375,6 +1378,60 @@ static void acer_backlight_exit(void)
     }
    
     /*
    + * Accelerometer device
    + */
    +static acpi_handle gsensor_handle;
    +
    +static int acer_gsensor_init(void)
    +{
    +	acpi_status status;
    +	struct acpi_buffer output;
    +	union acpi_object out_obj;
    +
    +	output.length = sizeof(out_obj);
    +	output.pointer = &out_obj;
    +	status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output);
    +	if (ACPI_FAILURE(status))
    +		return -1;
    +
    +	return 0;
    +}
    +
    +static int acer_gsensor_open(struct input_dev *input)
    +{
    +	return acer_gsensor_init();
    +}
    +
    +static int acer_gsensor_event(void)
    +{
    +	acpi_status status;
    +	struct acpi_buffer output;
    +	union acpi_object out_obj[5];
    +
    +	if (!has_cap(ACER_CAP_ACCEL))
    +		return -1;
    +
    +	output.length = sizeof(out_obj);
    +	output.pointer = out_obj;
    +
    +	status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output);
    +	if (ACPI_FAILURE(status))
    +		return -1;
    +
    +	if (out_obj->package.count != 4)
    +		return -1;
    +
    +	input_report_abs(acer_wmi_accel_dev, ABS_X,
    +		(s16)out_obj->package.elements[0].integer.value);
    +	input_report_abs(acer_wmi_accel_dev, ABS_Y,
    +		(s16)out_obj->package.elements[1].integer.value);
    +	input_report_abs(acer_wmi_accel_dev, ABS_Z,
    +		(s16)out_obj->package.elements[2].integer.value);
    +	input_sync(acer_wmi_accel_dev);
    +	return 0;
    +}
    +
    +/*
      * Rfkill devices
      */
     static void acer_rfkill_update(struct work_struct *ignored);
    @@ -1649,6 +1706,9 @@ static void acer_wmi_notify(u32 value, void *context)
     						   1, true);
     		}
     		break;
    +	case WMID_ACCEL_EVENT:
    +		acer_gsensor_event();
    +		break;
     	default:
     		pr_warn("Unknown function number - %d - %d\n",
     			return_value.function, return_value.key_num);
    @@ -1734,6 +1794,74 @@ static int acer_wmi_enable_lm(void)
     	return status;
     }
    
    +static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
    +						void *ctx, void **retval)
    +{
    +	*(acpi_handle *)retval = ah;
    +	return AE_OK;
    +}
    +
    +static int __init acer_wmi_get_handle(const char *name, const char *prop,
    +					acpi_handle *ah)
    +{
    +	acpi_status status;
    +	acpi_handle handle;
    +
    +	BUG_ON(!name || !ah);
    +
    +	handle = 0;
    +	status = acpi_get_devices(prop, acer_wmi_get_handle_cb,
    +					(void *)name, &handle);
    +
    +	if (ACPI_SUCCESS(status)) {
    +		*ah = handle;
    +		return 0;
    +	} else {
    +		return -ENODEV;
    +	}
    +}
    +
    +static int __init acer_wmi_accel_setup(void)
    +{
    +	int err;
    +
    +	err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle);
    +	if (err)
    +		return err;
    +
    +	interface->capability |= ACER_CAP_ACCEL;
    +
    +	acer_wmi_accel_dev = input_allocate_device();
    +	if (!acer_wmi_accel_dev)
    +		return -ENOMEM;
    +
    +	acer_wmi_accel_dev->open = acer_gsensor_open;
    +
    +	acer_wmi_accel_dev->name = "Acer BMA150 accelerometer";
    +	acer_wmi_accel_dev->phys = "wmi/input1";
    +	acer_wmi_accel_dev->id.bustype = BUS_HOST;
    +	acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS);
    +	input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0);
    +	input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0);
    +	input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0);
    +
    +	err = input_register_device(acer_wmi_accel_dev);
    +	if (err)
    +		goto err_free_dev;
    +
    +	return 0;
    +
    +err_free_dev:
    +	input_free_device(acer_wmi_accel_dev);
    +	return err;
    +}
    +
    +static void acer_wmi_accel_destroy(void)
    +{
    +	input_unregister_device(acer_wmi_accel_dev);
    +	input_free_device(acer_wmi_accel_dev);
    +}
    +
     static int __init acer_wmi_input_setup(void)
     {
     	acpi_status status;
    @@ -1889,6 +2017,9 @@ static int acer_platform_resume(struct platform_device *device)
     	if (has_cap(ACER_CAP_BRIGHTNESS))
     		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
    
    +	if (has_cap(ACER_CAP_ACCEL))
    +		acer_gsensor_init();
    +
     	return 0;
     }
    
    @@ -2066,6 +2197,8 @@ static int __init acer_wmi_init(void)
     			return err;
     	}
    
    +	acer_wmi_accel_setup();
    +
     	err = platform_driver_register(&acer_platform_driver);
     	if (err) {
     		pr_err("Unable to register platform driver\n");
    @@ -2109,6 +2242,8 @@ error_device_alloc:
     error_platform_register:
     	if (wmi_has_guid(ACERWMID_EVENT_GUID))
     		acer_wmi_input_destroy();
    +	if (has_cap(ACER_CAP_ACCEL))
    +		acer_wmi_accel_destroy();
    
     	return err;
     }
    @@ -2118,6 +2253,9 @@ static void __exit acer_wmi_exit(void)
     	if (wmi_has_guid(ACERWMID_EVENT_GUID))
     		acer_wmi_input_destroy();
    
    +	if (has_cap(ACER_CAP_ACCEL))
    +		acer_wmi_accel_destroy();
    +
     	remove_sysfs(acer_platform_device);
     	remove_debugfs();
     	platform_device_unregister(acer_platform_device);

  8. #7
    Just Joined!
    Join Date
    Jun 2012
    Posts
    5
    shellscriptcoder, I will give that patch a try. May I ask where you found it? Is it proposed for the kernel?

    Cheers.

  9. #8
    Just Joined!
    Join Date
    Jun 2012
    Posts
    28
    I located it at blog.gmane.org/gmane.linux.drivers.platform.x86.devel/3350 .

    I'm not sure whether it's proposed for the kernel, but seeing as that is the driver dev page, there's a fair chance it will be implemented at some point.

  10. #9
    Just Joined!
    Join Date
    Jun 2012
    Posts
    5
    shellscriptcoder, you are an absolute champion! Thank you so much.

    I applied the patch and now have a working accelerometer on /dev/input/js*

    Hopefully this will be included in the kernel soon. I have checked the source for 3.5.rc1 and it is not there yet, but here's hoping.

    Thanks again.
    nimoscar likes this.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •