Ubuntu – Circumventing MacBook Pro’s motion sensor using /dev/input/js0 as a joystick

joystickkernelmacbook proudev

I'm on a MacBook Pro 8,1 running 14.04 and I've never plugged in any device with a joystick to my laptop. When I was trying to fix an input problem I was having, I checked /dev/input/js0 thinking that it shouldn't exist, but there it was.

I didn't see anything joystick-related in xinput list:

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ bcm5974                                   id=11   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ Apple Inc. Apple Internal Keyboard / Trackpad id=10   [slave  keyboard (3)]
    ↳ FaceTime HD Camera (Built-in)             id=12   [slave  keyboard (3)]
    ↳ Apple Computer, Inc. IR Receiver          id=13   [slave  keyboard (3)]

But, udevadm info /dev/input/js0 shows:

P: /devices/platform/applesmc.768/input/input7/js0
N: input/js0
E: DEVNAME=/dev/input/js0
E: DEVPATH=/devices/platform/applesmc.768/input/input7/js0
E: ID_INPUT=1
E: ID_PATH=platform-applesmc.768
E: ID_PATH_TAG=platform-applesmc_768
E: MAJOR=13
E: MINOR=0
E: SUBSYSTEM=input
E: USEC_INITIALIZED=789104

and udevadm info --attribute-walk /dev/input/js0 shows:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/applesmc.768/input/input7/js0':
    KERNEL=="js0"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/platform/applesmc.768/input/input7':
    KERNELS=="input7"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{max}=="50"
    ATTRS{min}=="0"
    ATTRS{name}=="applesmc"
    ATTRS{phys}==""
    ATTRS{poll}=="50"
    ATTRS{uniq}==""
    ATTRS{properties}=="0"

  looking at parent device '/devices/platform/applesmc.768':
    KERNELS=="applesmc.768"
    SUBSYSTEMS=="platform"
    DRIVERS=="applesmc"
    ATTRS{key_at_index_data}==""
    ATTRS{key_at_index_name}=="#KEY"
    ATTRS{key_at_index_type}=="ui32"
    ATTRS{name}=="applesmc"
    ATTRS{fan1_manual}=="0"
    ATTRS{temp12_input}=="59000"
    ATTRS{temp12_label}=="TCGC"
    ATTRS{temp3_input}=="34500"
    ATTRS{temp3_label}=="TB2T"
    ATTRS{fan1_output}=="6200"
    ATTRS{temp19_input}=="52000"
    ATTRS{temp19_label}=="TPCD"
    ATTRS{light}=="(0,0)"
    ATTRS{fan1_max}=="6200"
    ATTRS{fan1_min}=="6200"
    ATTRS{temp13_input}=="54000"
    ATTRS{temp13_label}=="TCSA"
    ATTRS{temp4_input}=="59000"
    ATTRS{temp4_label}=="TC0C"
    ATTRS{key_count}=="379"
    ATTRS{fan1_input}=="6313"
    ATTRS{fan1_label}=="Exhaust  "
    ATTRS{temp14_input}=="-250"
    ATTRS{temp14_label}=="TCTD"
    ATTRS{temp5_input}=="58500"
    ATTRS{temp5_label}=="TC0D"
    ATTRS{temp20_input}=="-127000"
    ATTRS{temp20_label}=="TW0P"
    ATTRS{key_at_index}=="0"
    ATTRS{position}=="(-8,-5,248)"
    ATTRS{key_at_index_data_length}=="4"
    ATTRS{temp15_input}=="42000"
    ATTRS{temp15_label}=="TM0P"
    ATTRS{temp6_input}=="59750"
    ATTRS{temp6_label}=="TC0E"
    ATTRS{temp21_input}=="40500"
    ATTRS{temp21_label}=="Th1H"
    ATTRS{calibrate}=="(1,8)"
    ATTRS{temp16_input}=="44500"
    ATTRS{temp16_label}=="TM0S"
    ATTRS{temp7_input}=="61000"
    ATTRS{temp7_label}=="TC0F"
    ATTRS{temp22_input}=="33000"
    ATTRS{temp22_label}=="Ts0P"
    ATTRS{temp10_input}=="60000"
    ATTRS{temp10_label}=="TC1C"
    ATTRS{temp1_input}=="35000"
    ATTRS{temp1_label}=="TB0T"
    ATTRS{temp17_input}=="0"
    ATTRS{temp17_label}=="TMBS"
    ATTRS{temp8_input}=="1000"
    ATTRS{temp8_label}=="TC0J"
    ATTRS{temp23_input}=="38500"
    ATTRS{temp23_label}=="Ts0S"
    ATTRS{temp11_input}=="59000"
    ATTRS{temp11_label}=="TC2C"
    ATTRS{temp2_input}=="35000"
    ATTRS{temp2_label}=="TB1T"
    ATTRS{temp18_input}=="44000"
    ATTRS{temp18_label}=="TP0P"
    ATTRS{temp9_input}=="54500"
    ATTRS{temp9_label}=="TC0P"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

I recognize the temp sensors above which is why I was wondering why applesmc, would have anything to do with joysticks. Assuming I understood it right, it's because applesmc uses /dev/input/js0 for the MacBook Pro's motion sensors (I think they're the ones used to detect if it's on a level surface). How important are the motion sensors in system use? Is it safe to get rid of /dev/input/js0? If so, how to do it safely?


Background to the input problem I'm having is with Skyrim on Wine. If I'm running in any direction during a lag spike, my character gets stuck running in that direction regardless of other directional input or whether character is on auto-run. What fixed it for most people were disabling gamepad/joystick settings. I've disabled it through the game's settings and .ini files, yet the problem persists which led me to look into whether or not it's js0-related.

Best Answer

You have to blacklist it with udev. I went here first:

https://github.com/denilsonsa/udev-joystick-blacklist

I wanted to add a Rumblepad. My rules file looks like this:

SUBSYSTEM=="input", ATTRS{name}=="applesmc", ENV{ID_INPUT_JOYSTICK}=="?*", ENV{ID_INPUT_JOYSTICK}=""
SUBSYSTEM=="input", ATTRS{name}=="applesmc", KERNEL=="js[0-9]*", RUN+="/bin/rm %E{DEVNAME}", ENV{ID_INPUT_JOYSTICK}=""
SUBSYSTEM=="input", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1c26", ENV{ID_INPUT_JOYSTICK}=="?*", ENV{ID_INPUT_JOYSTICK}=""
SUBSYSTEM=="input", ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1c26", KERNEL=="js[0-9]*", RUN+="/bin/mv %E{DEVNAME} /dev/input/js0", ENV{ID_INPUT_JOYSTICK}=""
Related Question