linux-surface icon indicating copy to clipboard operation
linux-surface copied to clipboard

[SB] SAM Support (dGPU-detection, clipboard-detach handling)

Open Menci opened this issue 5 years ago • 97 comments

Menci@Menci-Surface:~$ lspci
00:00.0 Host bridge: Intel Corporation Skylake Host Bridge/DRAM Registers (rev 08)
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 520 (rev 07)
00:05.0 Multimedia controller: Intel Corporation Skylake Imaging Unit (rev 01)
00:08.0 System peripheral: Intel Corporation Skylake Gaussian Mixture Model
00:14.0 USB controller: Intel Corporation Sunrise Point-LP USB 3.0 xHCI Controller (rev 21)
00:14.2 Signal processing controller: Intel Corporation Sunrise Point-LP Thermal subsystem (rev 21)
00:14.3 Multimedia controller: Intel Corporation Device 9d32 (rev 01)
00:15.0 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #0 (rev 21)
00:15.1 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #1 (rev 21)
00:15.2 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #2 (rev 21)
00:15.3 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #3 (rev 21)
00:16.0 Communication controller: Intel Corporation Sunrise Point-LP CSME HECI #1 (rev 21)
00:16.4 Communication controller: Intel Corporation Device 9d3e (rev 21)
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #5 (rev f1)
00:1d.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #9 (rev f1)
00:1d.3 PCI bridge: Intel Corporation Device 9d1b (rev f1)
00:1f.0 ISA bridge: Intel Corporation Sunrise Point-LP LPC Controller (rev 21)
00:1f.2 Memory controller: Intel Corporation Sunrise Point-LP PMC (rev 21)
00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio (rev 21)
02:00.0 Non-Volatile memory controller: Toshiba America Info Systems NVMe Controller (rev 01)
03:00.0 Ethernet controller: Marvell Technology Group Ltd. 88W8897 [AVASTAR] 802.11ac Wireless
Menci@Menci-Surface:~$ 

Menci avatar Oct 31 '18 10:10 Menci

I believe it's not supported (yet?). Check the What's Not Working section: Dedicated Nvidia GPU (if you have a performance base on a Surface Book 1, otherwise onboard works fine)

mdudzinski avatar Oct 31 '18 12:10 mdudzinski

But at least there'd be the device in lspci?

Menci avatar Oct 31 '18 13:10 Menci

Hi,

I'm a Linux newbie. I've been reading a lot about the benefits of Linux and decided to migrate to Mint. But as I read, the dGPU of the SB Performance Base version (mine as well) is not working at all. It seems that the dGPU, the battery status and the camera are the only issues and barriers that stop me from migrating 100%.

Is there anything I could do to figure out a way to solve these problems?

Thanks,

Felipe

ghost avatar Nov 04 '18 15:11 ghost

My battery status works.

Menci avatar Nov 05 '18 10:11 Menci

So I did migrate after all, and it seems that I have the same problem as you. I find it curious that I could even find in Nvidia's website its driver (https://www.nvidia.com/Download/driverResults.aspx/140135/en-us) but the Surface itself doesn't recognize the dGPU, as you pointed. Have you made any progress? I'm struggling with the current Intel GPU to edit photos/videos

ghost avatar Nov 21 '18 18:11 ghost

@Menci the dGPU in the performance base for the SB is not currently supported by the linux kernel.

jakeday avatar Dec 28 '18 19:12 jakeday

DSDT from SB1 with Performance Base of mine is here:

and DSDT from SB2 15" is posted by JoshKaufman here:

Comparing these DSDTs might help to find something but I don't know where to start.

kitakar5525 avatar Jan 06 '19 15:01 kitakar5525

@kitakar5525 If you want to try something: When I was looking over the DSDT of the SB1 for the button issue I found this somewhat interesting debug message. This code path can be triggered by a _DSM call, so that might be worth looking into.

To me it looks like this code powers-up and "links" the dGPU, but I'm not sure if this solves the problem. I don't have a SB1 so I can't try it.

qzed avatar Jan 06 '19 15:01 qzed

I installed acpi_call and issued echo '\_SB.PCI0.RP05.HGON' > /proc/acpi/call, I got following errors in dmesg:

kern  :warn  : [ +42.597418] i2c i2c-5: protocol 0x0e not supported for client 0x28
kern  :err   : [  +0.000006] ACPI Exception: AE_BAD_PARAMETER, Returned by Handler for [GenericSerialBus] (20170728/evregion-300)
kern  :err   : [  +0.000020] ACPI Error: Result stack is empty! State=ffff88d4a417d400 (20170728/dswstate-99)
kern  :err   : [  +0.000018] ACPI Error: Method parse/execution failed \_SB.PCI0.I2C0.SAM.SCMD, AE_BAD_PARAMETER (20170728/psparse-550)
kern  :err   : [  +0.000015] ACPI Error: Method parse/execution failed \_SB.PCI0.RP05.HGON, AE_BAD_PARAMETER (20170728/psparse-550)
kern  :err   : [  +0.000017] acpi_call: Method call failed: Error: AE_BAD_PARAMETER

🤔 I'll try more with acpi_call.

kitakar5525 avatar Jan 11 '19 04:01 kitakar5525

@kitakar5525 I don't think you can go any further with acpi_call. It looks like it's going wrong here, due to AttribRawBytes (defined as protocol in the I2C OpRegion being accessed via SCMD/WRIT) not being supported in the handler.

AttribRawBytes is described in the ACPI spec as

Raw Read/Write N-Bytes Protocol (AttribRawBytes)

The GenericSerialBus Raw Read/Write N Bytes protocol (AttribRawBytes) transfers variable-sized data. The actual number of bytes to read or write is specified as part of the AccessAs attribute. [...] Raw accesses assume that the writer has knowledge of the bus that the access is made over and the device that is being accessed. The protocol may only ensure that the buffer is transmitted to the appropriate driver, but the driver must be able to interpret the buffer to communicate to a register.

The italic part is the catch: The data transmitted can basically be anything, implying that a custom driver is required. This, in concept, is quite similar to the mechanism used for the EC in the SB2 (etc.), but the data-protocol seems to differ (here's whats being transmitted).

I'm not sure what's supposed to happen with this data driver-side, this may be a problem moving forward. Nevertheless I can speculate a bit (take this with a few big grains of salt):

  • The name SAM could mean Surface Attach(ment) Mechanism means System Aggregator Module (source).
  • All calls to SCMD are dGPU related.
  • There is an eerie similarity between the SB1 and SB2 in terms of the MOPT function (Nvidia Optimus related): Compare this to the SB2. Specifically, the calls to SCMD and RQST have the same command-id. On the SB2, those calls lock/unlock the base so that it can't be detached when the dGPU is in use. There are no similar calls with the other command-id (0x04, 0x05) on the SB2.

and probably the main points

  • The actual dGPU power-on/initialization mechanism is actually quite similar, with the crucial difference that on the SB1, there is a call to SCMD where on the SB2 there are values being set via calls to SGOV. Note that on the SB2 the while-loop for waiting on the status-change is extracted to the WGPS function.
  • There is no dependency specification (_DEP) on the SAM device and it seems like there is actually a real I2C chip there (which is a difference to the SB2).

All in all I'm fairly certain that we need a custom I2C driver to get this to work. It might be possible to reverse-engineer that (maybe via some logs from Windows, similar to what helped us figure things out for the SB2 etc.) but I doubt it'll be easy.

qzed avatar Jan 11 '19 15:01 qzed

It might also help to find out what exactly is being given to the driver. I couldn't recognize anything, but if somebody else wants to try: Have a look at this.

qzed avatar Jan 11 '19 15:01 qzed

@qzed Thank you for pointing out the problems! I'm at least glad to know it will not be easy…

kitakar5525 avatar Jan 12 '19 07:01 kitakar5525

Sorry I can't help you more at the moment. I've still planned to find out the missing SB2 features via logging on Windows, maybe we can use the same approach here, but I have to get that working properly first.

qzed avatar Jan 13 '19 23:01 qzed

Has there been any progress on this feature? I've been having performance issues lately and I think having the dGPU could help; as a side note I just switched back from Wayland and things have run a lot smoother since.

Wynston avatar Mar 20 '19 20:03 Wynston

Not much, there's currently a bit of discussion on gitter about the SAM device, which seems to be the embedded controller on the older surface devices (SB1, SP4, ...?), so that's probably what we'd have to look at to get this working.

qzed avatar Mar 20 '19 21:03 qzed

Changed the title to better reflect the state of this. A small update following shortly.

qzed avatar Mar 20 '19 21:03 qzed

Okay, so far we know that SAM is the "Surface Aggregator Module", which seems to be the embedded controller in charge of all of this. We know from this (thanks to @tmarkov and @kitakar5525), that we should be able to communicate with it via HID-over-I2C. HID is (for me at least) a bit of a weird choice (since it's designed for input-devices, e.g. mice, keyboards, gamepads, touchscreens, ...) but it should be capable of handling everything that is needed from a technical standpoint.

I think we should now try to figure out if the buffer contents here could be some HID-over-I2C report and also listen-in on the communication from the Windows side. For that I'll just copy what I wrote on gitter:

Since we now know it's really an I2C device I think somebody should check and see if we can get some logs for this via the method we already used on the newer devices (described here). The difference being that you need to replace \Driver\iaLPSS2_UART2 with the I2C driver that handles this device. I can't give you the specific name (probably along the lines of \Driver\iaLPSS2_I2C), but you should see some messages appear if you do something like detach the clipboard. If there are more than one, it may also work to just select all of them, but that could also result in a flood of other unrelated events, so best only select the necessary one if you can.

qzed avatar Mar 20 '19 22:03 qzed

Here's the HID-over-I2C specification in a readable format (because of course Microsoft needs to push their .docx format):

hid-over-i2c-protocol-spec-v1-0.pdf

qzed avatar Mar 20 '19 22:03 qzed

Also interesting, it's right there in the DSDT that it communicates via HID:

Name (_CID, "PNP0C50" /* HID Protocol Device (I2C bus) */) // _CID: Compatible ID

Also there's a driver in Linux for generic HID-over-i2c devices which matches the _CID: i2c-hid-core.c Can anyone have a look at the /dev/hidrawX devices and their names? A list of input devices (e.g. via evtest) should probably also include the device.

qzed avatar Mar 20 '19 23:03 qzed

It seems that \Driver\iaLPSS2i_I2C -> \Device\NTPNP_PCI0007 -> ... -> \Device\00000040 is the thing we should look at, according to VrtuleTree. I will look into it further.

SAM on VrtuleTree

kitakar5525 avatar Mar 21 '19 00:03 kitakar5525

With one of Alex' slides and the HID-over-I2C spec I think I've figured out the buffer that is being sent (it's indeed valid HID-over-I2C):

  • BE EF probably the address, not sure about that tough, could also be some communication header for the driver communication.
  • 05 00 select command register
  • 3F 03 24 the command (03: set_report, 3F: type is feature report, the F means an extra byte is used for the report ID, 24: report ID)
  • 06 00 select data register
  • 13 00 length of data (including these two bytes)
  • 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 report data

The second byte in the report-data gets set by SCMD as some value, so we need the report descriptor to find out more.

qzed avatar Mar 21 '19 00:03 qzed

I see BSoD many times caused by IRPMon driver, but I've got one log.

This is a log when I pressed detach button on keyboard but I left tablet attached. DebugView【detach-button-pressed-on-keyboard,left-tablet-attached】.LOG

kitakar5525 avatar Mar 21 '19 03:03 kitakar5525

BSoD KMODE_EXCEPTION_NOT_HANDLED caused by irpmndrv.sys is making collecting logs harder :( I cannot get a log when I detach tablet yet.

This is a log when I pressed Surface DTX app on system tray but I left tablet attached. I don't expect much difference, though. DebugView【SurfaceDTX-app-pressed-on-systray,left-tablet-attached】.LOG

kitakar5525 avatar Mar 21 '19 06:03 kitakar5525

Also there's a driver in Linux for generic HID-over-i2c devices which matches the _CID: i2c-hid-core.c Can anyone have a look at the /dev/hidrawX devices and their names?

$ ls -lh /dev/hidraw?
crw------- 1 root root 238, 0 Mar 21 15:55 /dev/hidraw0
crw------- 1 root root 238, 1 Mar 21 16:34 /dev/hidraw1

I don't know how to find their names, but at least /dev/hidraw0 is related to IPTS and /dev/hidraw1 is related to Surface Keyboard according to output of sudo hexdump /dev/hidrawX. The timestamp is different from each other because I detached and re-attached the keyboard.

A list of input devices (e.g. via evtest) should probably also include the device.

The list of input devices from evtest:

$ evtest
No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event0:    Lid Switch
/dev/input/event1:    Video Bus
/dev/input/event2:    Surface Pro 3/4 Buttons
/dev/input/event3:    PC Speaker
/dev/input/event4:    ipts 1B96:005E UNKNOWN
/dev/input/event5:    ipts 1B96:005E
/dev/input/event6:    ipts 1B96:005E Touchscreen
/dev/input/event7:    ipts 1B96:005E Mouse
/dev/input/event8:    Microsoft Surface Keyboard
/dev/input/event9:    Microsoft Surface Keyboard Mouse
/dev/input/event10:    Microsoft Surface Keyboard Consumer Control
/dev/input/event11:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event12:    Microsoft Surface Keyboard Touchpad
/dev/input/event13:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event14:    HDA Intel PCH Mic
/dev/input/event15:    HDA Intel PCH Headphone
/dev/input/event16:    HDA Intel PCH HDMI/DP,pcm=3
/dev/input/event17:    HDA Intel PCH HDMI/DP,pcm=7
/dev/input/event18:    HDA Intel PCH HDMI/DP,pcm=8
/dev/input/event19:    HDA Intel PCH HDMI/DP,pcm=9
/dev/input/event20:    HDA Intel PCH HDMI/DP,pcm=10
/dev/input/event21:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event22:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event23:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event24:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event25:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event26:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event27:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event28:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event29:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event30:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event31:    Microsoft Surface Keyboard UNKNOWN
/dev/input/event256:    Microsoft Surface Keyboard UNKNOWN
Select the device event number [0-256]: 

I can't find PNP0C50 device at all. find /sys -name "*PNP0C50*" shows nothing.

EDIT

🤔

$ tail $(sudo find /sys -name modalias) | grep -n1 PNP0C50
243-==> /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-5/i2c-MSHW0030:00/modalias <==
244:acpi:MSHW0030:PNP0C50:
245-
--
558-==> /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:71/MSHW0030:00/modalias <==
559:acpi:MSHW0030:PNP0C50:
560-

kitakar5525 avatar Mar 21 '19 07:03 kitakar5525

Ah yeah, PNP0C50 is the compatibility ID (_CID) the actual device ID is MSHW0030. It's probably not visible in /dev/input and /dev/hidraw because the OperationRegion handler on the parent device is not implemented yet (kind of forgot that yesterday, sorry).

The BSOD is weird, I never experienced that. I've had a look at the logs and it looks like some of the data does not get dumped. So far (ignoring the IOCTLs), I can only see the buffer contents of a few write commands, which are, as far as I can tell, mostly the ones being sent via ACPI (there are other reads/writes going on where I can't see the buffers being received/sent). Then again @carrylook had to modify the IRPMon source specifically to get this data for the newer devices. Unfortunately, I basically don't know anything about that. There are also a few smaller writes that I can't make sense of (they seem to be related to some IOCTLs and not the HID stuff, so maybe we can ignore them).

qzed avatar Mar 21 '19 21:03 qzed

SAM device itself is \Device\00000060. Maybe we should also watch this device (?) I will look into it later.

Device_Manager___Device_00000060___SB PCI0 I2C0 SAM VrtuleTree__Device_00000060

kitakar5525 avatar Mar 22 '19 15:03 kitakar5525

Might make a difference, to be honest I can't say.

qzed avatar Mar 22 '19 20:03 qzed

This time, I disabled/enabled dGPU from Device Manager and didn't press detach button (because pressing that is more likely to cause BSoD).

I watched each device with two different settings. IRPMon-default-settings/enabled-all-settings Left in the picture is default settings, whereas right in the picture is enabled all settings.

\Device\00000040

default settings

enabled all settings

\Device\0000001a (Surface DTX, MSHW0041)

No logs collected.

\Device\00000060 (I2C HID Device, MSHW0030, SAM)

No logs collected.


Sorry but I don't understand what the logs are telling us and what kind of log is needed, yet :( I can say at least there is no much difference between default settings and enabled all settings, press detach button and disable/enable dGPU.

kitakar5525 avatar Mar 24 '19 07:03 kitakar5525

And what I wonder is why I can see report descriptor of sensor related thing which are part of SAM but I cannot see that of detach/dGPU related thing on Linux.

sudo find /sys -name report_descriptor
/sys/devices/pci0000:00/0000:00:16.4/mei::3e8d0870-271a-4208-8eb5-9acb9402ae04:0F/0044:1B96:005E.0002/report_descriptor
/sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-5/i2c-MSHW0030:00/0018:045E:0914.0001/report_descriptor
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4:1.0/0003:045E:07CE.0003/report_descriptor

I upload report descriptor of MSHW0030:00 045E:0914 (sensor related) if someone is interested in:

raw output

hex output with od -An -tx1

output with hidrd-convert -o code

The second byte in the report-data gets set by SCMD as some value, so we need the report descriptor to find out more.

If we need report descriptor of detach/dGPU related thing, maybe we can get it on Windows by another way instead of IRPMon/DebugView.

kitakar5525 avatar Mar 24 '19 08:03 kitakar5525

If we need report descriptor of detach/dGPU related thing, maybe we can get it on Windows by another way instead of IRPMon/DebugView.

That's probably an option, but I'm not that sure any more that it'll give us much more information.

I'll try to have another look at the logs tomorrow, still can't see the relevant information though. Maybe I'm misinterpreting something.

qzed avatar Mar 24 '19 20:03 qzed

This time, I got some logs using bentiss/SimplePeripheralBusProbe: I2C/SPI probe for Windows 10.

Note: dGPU is not shown in Device Manager while I'm using this probe. Maybe I patched DSDT in the wrong way.

spbProbe-log【enabled-from-DeviceManager】.txt This log was collected in these steps:

  1. disabled SAM device from Device Manager
  2. started logging
  3. enabled SAM device from Device Manager

spbProbe-log【detached】.txt This log was collected in these steps:

  1. enabled SAM device from Device Manager
  2. started logging
  3. detached/re-attached the keyboard

I see report descriptor in the first log, and which is the same as MSHW0030:00 045E:0914 I posted in https://github.com/jakeday/linux-surface/issues/286#issuecomment-475938478 🤔

kitakar5525 avatar Mar 27 '19 17:03 kitakar5525

For those who want to use spbProbe:

To use the probe, you need to modify spbProbe.inf like this:

diff --git a/spbProbe.inf.ORIG b/spbProbe.inf
index 0e0d751..e057848 100755
--- a/spbProbe.inf.ORIG
+++ b/spbProbe.inf
@@ -42,7 +42,7 @@ spbProbe.sys  = 1,,
 ; Decorated model section take precedence over undecorated 
 ; ones on XP and later.
 [Standard.NTamd64]
-%spbProbe.DeviceDesc%=spbProbe_Device, ACPI\spbProbe
+%spbProbe.DeviceDesc%=spbProbe_Device, ACPI\PROBE01
 
 [spbProbe_Device.NT]
 CopyFiles=Drivers_Dir

and modify DSDT like this:

diff --git a/dsdt.dsl b/dsdt-mod.dsl
index c214d37..d86f532 100755
--- a/dsdt.dsl
+++ b/dsdt-mod.dsl
@@ -1,7 +1,7 @@
-Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload-496)
-Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload2-477)
-Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload-496)
-Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload2-477)
+//Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload-496)
+//Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload2-477)
+//Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload-496)
+//Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (20190215/dswload2-477)
 /*
  * Intel ACPI Component Architecture
  * AML/ASL+ Disassembler version 20190215 (64-bit version)
@@ -22,7 +22,7 @@ Firmware Error (ACPI): Could not resolve symbol [^GFX0.CLID], AE_NOT_FOUND (2019
  *     Compiler ID      "INTL"
  *     Compiler Version 0x20160422 (538313762)
  */
-DefinitionBlock ("", "DSDT", 2, "MSFT  ", "MSFT    ", 0x00000000)
+DefinitionBlock ("", "DSDT", 2, "MSFT  ", "MSFT    ", 0x00000001)
 {
     External (_GPE.AL6F, MethodObj)    // 0 Arguments
     External (_GPE.HLVT, MethodObj)    // 0 Arguments
@@ -16370,8 +16370,12 @@ DefinitionBlock ("", "DSDT", 2, "MSFT  ", "MSFT    ", 0x00000000)
             {
                 Name (RBUF, ResourceTemplate ()
                 {
+                    //I2cSerialBusV2 (0x0028, ControllerInitiated, 0x00061A80,
+                        //AddressingMode7Bit, "\\_SB.PCI0.I2C0",
+                        //0x00, ResourceConsumer, , Exclusive,
+                        //)
                     I2cSerialBusV2 (0x0028, ControllerInitiated, 0x00061A80,
-                        AddressingMode7Bit, "\\_SB.PCI0.I2C0",
+                        AddressingMode7Bit, "\\_SB.PCI0.SPB1",
                         0x00, ResourceConsumer, , Exclusive,
                         )
                     Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
@@ -16436,6 +16440,27 @@ DefinitionBlock ("", "DSDT", 2, "MSFT  ", "MSFT    ", 0x00000000)
         }
     }
 
+    Scope (_SB.PCI0)
+    {
+        Device(SPB1)
+        {
+            Name(_HID, "PROBE01")
+            Name(_UID, 1)
+            Method(_CRS, 0x0, NotSerialized)
+            {
+                Name (RBUF, ResourceTemplate ()
+                {
+                    //I2CSerialBus (0x07, ControllerInitiated, 100000,AddressingMode7Bit, "\\_SB.I2C3",,,,)
+                    I2cSerialBusV2 (0x0028, ControllerInitiated, 0x00061A80,
+                        AddressingMode7Bit, "\\_SB.PCI0.I2C0",
+                        0x00, ResourceConsumer, , Exclusive,
+                        )
+                })
+                Return(RBUF)
+            }
+        }
+    }
+
     Scope (_SB)
     {
         Device (WSLT)

Helpful links

kitakar5525 avatar Mar 27 '19 17:03 kitakar5525

Awesome work! I'm a bit busy at the moment, so I've only had a quick look over the logs, but it seems like this is everything we needed!

I think we should try to get the HID device working on Linux next (as far as I can see that would amount to implementing the operation-region handler in the parent device node, the device should then get picked up by the i2c-hid driver), and then connect to it and compare with the logs.

qzed avatar Mar 28 '19 01:03 qzed

I can detach the keyboard using i2cset

sudo modprobe i2c-dev
sudo modprobe -r i2c-hid
sudo i2cset -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i

interesting🤣

where 5 is the number of i2c-X, you can find it with ls -lh /sys/bus/i2c/devices/ and search for MSHW0030. 0x28 is the SAM device address, you can find it with sudo i2cdetect -y -r 5

kitakar5525 avatar Mar 30 '19 23:03 kitakar5525

From DSDT, we can see some command-ids:

# part of HGON
^^I2C0.SAM.SCMD (0x05)
# part of HGOF
^^I2C0.SAM.SCMD (0x04)
# ADBG ("Send Apps not present cmd")
^^^I2C0.SAM.SCMD (0x07)
# ADBG ("Send Apps present cmd")
^^^I2C0.SAM.SCMD (0x06)

and then, I can confirm that sending 0x06 before 0x08 prevent detaching the keyboard (LED turns red):

sudo i2cset -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i
sudo i2cset -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i

then, sending 0x07 results in detaching the keyboard:

sudo i2cset -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i

However, I cannot see dGPU on lspci when I just send 0x05.

kitakar5525 avatar Mar 31 '19 00:03 kitakar5525

After a very dirty hack to DSDT, I can see NVIDIA card

$ lspci -nn | grep -i nvidia
01:00.0 3D controller [0302]: NVIDIA Corporation GM206M [GeForce GTX 965M] [10de:1427] (rev a1)

I replaced every I2C0.SAM.SCMD () with Sleep () and while sleeping, send the command id 0x05 using i2cset from terminal manually.

DSDT patchset is here if you want to have a look.

Maybe I describe more later.

kitakar5525 avatar Apr 02 '19 18:04 kitakar5525

Wow, that's some good progress! Sorry I've been absent for a while (had some exams), I'll try to have a look at it this evening.

If I understand you correctly, your DSDT patch indicates that to detect the dGPU we'd only have to implement the operation region. The trickiest part about that is probably the part talking to the child device while it already has a driver attached. That part's a bit new to me, but I think it should be fairly straightforward.

I still have some stuff to clean up in the surface-acpi repo (mostly renaming, shouldn't be that much) which I want to get done first, but I'll try implementing that in a second repo directly after (for now I think a different repo is better for prototyping, though eventually I'd like to include that in the surface-acpi module).

qzed avatar Apr 03 '19 11:04 qzed

Just for the record: The HID vendor/ID of the SAM device is 045E:0914.

qzed avatar Apr 05 '19 11:04 qzed

Okay, I've uploaded an initial driver here. It doesn't send the I2C messages yet, but it should show some output in the dmesg log. Can you check if those messages show up (they should start with surface_sam:)? Just compile with make and then load the module with insmod surface_sam.ko. I hope this works without unloading the i2c-hid driver.

qzed avatar Apr 05 '19 11:04 qzed

it should show some output in the dmesg log

Yes, I can see it:

$ dmesg -xHTw
# after `insmod surface_sam.ko`
kern  :info  : [Fri Apr  5 21:11:34 2019] surface_sam: device-name: \_SB_.PCI0.I2C0.SAM_
kern  :info  : [Fri Apr  5 21:11:34 2019] surface_sam: parent-name: \_SB_.PCI0.I2C0
kern  :err   : [Fri Apr  5 21:11:34 2019] surface_sam: could not install address space handler: 7
kern  :warn  : [Fri Apr  5 21:11:34 2019] Surface SAM Driver: probe of MSHW0030:00 failed with error -14

EDIT

Sorry, I made a copy-paste mistake. Not error -1 but error -14

kitakar5525 avatar Apr 05 '19 12:04 kitakar5525

On SB1, I can also see this:

kern  :info  : [ven. avril  5 14:17:47 2019] surface_sam: device-name: \_SB_.PCI0.I2C0.SAM_
kern  :info  : [ven. avril  5 14:17:47 2019] surface_sam: parent-name: \_SB_.PCI0.I2C0
kern  :err   : [ven. avril  5 14:17:47 2019] surface_sam: could not install address space handler: 7
kern  :warn  : [ven. avril  5 14:17:47 2019] Surface SAM Driver: probe of MSHW0030:00 failed with error -14

jrevillard avatar Apr 05 '19 12:04 jrevillard

On Surface Book with Performance Base:

$ make
make -C /lib/modules/"5.0.1-surface-linux-surface"/build M=/home/Menci/linux-surface-sam-hid modules
make[1]: Entering directory '/usr/src/linux-headers-5.0.1-surface-linux-surface'
  CC [M]  /home/Menci/linux-surface-sam-hid/surface_sam.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/Menci/linux-surface-sam-hid/surface_sam.mod.o
  LD [M]  /home/Menci/linux-surface-sam-hid/surface_sam.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.0.1-surface-linux-surface'
$ sudo insmod surface_sam.ko
$ dmesg
<some unrelated output omitted>
[   89.307915] surface_sam: loading out-of-tree module taints kernel.
[   89.307996] surface_sam: module verification failed: signature and/or required key missing - tainting kernel
[   89.308393] surface_sam: device-name: \_SB_.PCI0.I2C0.SAM_
[   89.308395] surface_sam: parent-name: \_SB_.PCI0.I2C0
[   89.308397] surface_sam: could not install address space handler: 7
[   89.308406] Surface SAM Driver: probe of MSHW0030:00 failed with error -14
```

Menci avatar Apr 05 '19 12:04 Menci

Okay, thanks guys! I'll try to figure out why the address-space handler can't be installed.

qzed avatar Apr 05 '19 12:04 qzed

It seems there's a "signature error" when a inserting the module. Let me disable Secure Boot and try again.

Menci avatar Apr 05 '19 12:04 Menci

@Menci that's just a warning, shouldn't make any difference.

qzed avatar Apr 05 '19 12:04 qzed

@qzed Sure, I got the same message after I disabled Secure Boot.

Menci avatar Apr 05 '19 12:04 Menci

Error 7 should be AE_ALREADY_EXISTS , so there is already a handler attached. Makes sense looking back at https://github.com/jakeday/linux-surface/issues/286#issuecomment-453378745. I'll have to see how to replace that one.

Edit: Right, we already discovered that back in January... https://elixir.bootlin.com/linux/v5.0.6/source/drivers/i2c/i2c-core-acpi.c#L637 . Should have remembered that.

qzed avatar Apr 05 '19 12:04 qzed

Okay, I don't think there is a clean way to do this. It looks like we have to patch in a quirk in i2c-core-acpi.c.

qzed avatar Apr 05 '19 13:04 qzed

I've pushed a patch and uploaded a kernel for testing (currently Arch, Debian will follow in a few minutes). There should again be some output prefixed with surface_sam:.

qzed avatar Apr 05 '19 16:04 qzed

I installed binary release and the output:

$ dmesg -xH | grep "surface_sam"
kern  :warn  : [  +0.000219] surface_sam: checking quirks
kern  :warn  : [  +0.000004] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.026133] surface_sam: checking quirks
kern  :warn  : [  +0.000005] surface_sam: not a SAM device
kern  :warn  : [  +0.009066] surface_sam: checking quirks
kern  :warn  : [  +0.000008] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.015909] surface_sam: checking quirks
kern  :warn  : [  +0.000009] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.007982] surface_sam: checking quirks
kern  :warn  : [  +0.000008] surface_sam: SAM is not a child of this adapter

kitakar5525 avatar Apr 05 '19 17:04 kitakar5525

The surface_sam: not a SAM device line is a bit weird (as far as I can see from the DSDT the adapter should only have the SAM device as child), but after a quick look at the code it seems that the acpi_device_hid method might return the CID instead. I'll try to fix that.

qzed avatar Apr 05 '19 17:04 qzed

I've updated the release.

qzed avatar Apr 05 '19 18:04 qzed

It works!

$ dmesg -xH | grep "surface_sam"
kern  :warn  : [  +0.000223] surface_sam: checking quirks
kern  :warn  : [  +0.000005] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.002224] surface_sam: checking quirks
kern  :warn  : [  +0.000006] surface_sam: applying quirks
kern  :warn  : [  +0.000966] surface_sam: checking quirks
kern  :warn  : [  +0.000005] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.020800] surface_sam: checking quirks
kern  :warn  : [  +0.000006] surface_sam: SAM is not a child of this adapter
kern  :warn  : [  +0.021322] surface_sam: checking quirks
kern  :warn  : [  +0.000005] surface_sam: SAM is not a child of this adapter

kitakar5525 avatar Apr 06 '19 00:04 kitakar5525

Nice! What about the dGPU? The patch should also allow for the I2C communication via ACPI to work (e.g. in HGON).

qzed avatar Apr 06 '19 09:04 qzed

Yes, I can power dGPU on via HGON!

$ acall(){ echo "$1" | sudo tee /proc/acpi/call >/dev/null && sudo cat /proc/acpi/call;echo;}
$ acall "\_SB.PCI0.RP05.HGON"
0x1called
$ dmesg -xHw
kern  :warn  : [ +25.018163] surface_sam: handler called
kern  :warn  : [  +0.001007] surface_sam: writing to i2c, status: 0
kern  :info  : [  +0.251400] pciehp 0000:00:1c.0:pcie004: Slot(4): Card present
kern  :debug : [  +0.164161] pci 0000:01:00.0: [10de:1427] type 00 class 0x030200
kern  :debug : [  +0.000033] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00ffffff]
kern  :debug : [  +0.000014] pci 0000:01:00.0: reg 0x14: [mem 0x00000000-0x0fffffff 64bit pref]
kern  :debug : [  +0.000013] pci 0000:01:00.0: reg 0x1c: [mem 0x00000000-0x01ffffff 64bit pref]
kern  :debug : [  +0.000008] pci 0000:01:00.0: reg 0x24: [io  0x0000-0x007f]
kern  :debug : [  +0.000009] pci 0000:01:00.0: reg 0x30: [mem 0x00000000-0x0007ffff pref]
kern  :info  : [  +0.000144] pci 0000:01:00.0: 15.752 Gb/s available PCIe bandwidth, limited by 8 GT/s x2 link at 0000:00:1c.0 (capable of 126.016 Gb/s with 8 GT/s x16 link)
kern  :info  : [  +0.009802] pci 0000:01:00.0: BAR 1: assigned [mem 0xc0000000-0xcfffffff 64bit pref]
kern  :info  : [  +0.000010] pci 0000:01:00.0: BAR 3: assigned [mem 0xa2000000-0xa3ffffff 64bit pref]
kern  :info  : [  +0.000008] pci 0000:01:00.0: BAR 0: assigned [mem 0xba000000-0xbaffffff]
kern  :info  : [  +0.000004] pci 0000:01:00.0: BAR 6: assigned [mem 0xb9700000-0xb977ffff pref]
kern  :info  : [  +0.000001] pci 0000:01:00.0: BAR 5: assigned [io  0x3000-0x307f]
kern  :info  : [  +0.000004] pcieport 0000:00:1c.0: PCI bridge to [bus 01]
kern  :info  : [  +0.000003] pcieport 0000:00:1c.0:   bridge window [io  0x3000-0x6fff]
kern  :info  : [  +0.000003] pcieport 0000:00:1c.0:   bridge window [mem 0xb9700000-0xd16fffff]
kern  :info  : [  +0.000002] pcieport 0000:00:1c.0:   bridge window [mem 0xa1400000-0xb93fffff 64bit pref]
kern  :info  : [  +0.002852] IPMI message handler: version 39.2
kern  :info  : [  +0.002905] ipmi device interface
kern  :warn  : [  +0.016556] nvidia: module license 'NVIDIA' taints kernel.
kern  :warn  : [  +0.000002] Disabling lock debugging due to kernel taint
kern  :info  : [  +0.023313] nvidia-nvlink: Nvlink Core is being initialized, major device number 234
kern  :info  : [  +0.000936] nvidia 0000:01:00.0: enabling device (0000 -> 0003)
kern  :warn  : [  +0.100991] NVRM: loading NVIDIA UNIX x86_64 Kernel Module  418.56  Fri Mar 15 12:59:26 CDT 2019
kern  :info  : [  +0.004406] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms  418.56  Fri Mar 15 12:32:40 CDT 2019
kern  :info  : [  +0.004482] [drm] [nvidia-drm] [GPU ID 0x00000100] Loading driver
kern  :info  : [  +0.000003] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:01:00.0 on minor 1
$ lspci -nn | grep -i nvidia
01:00.0 3D controller [0302]: NVIDIA Corporation GM206M [GeForce GTX 965M] [10de:1427] (rev a1)

kitakar5525 avatar Apr 06 '19 11:04 kitakar5525

Or, I can power dGPU on via calling \_SB_.PCI0.LPCB.EC0_.VGBI._DSM twice

# prepare
echo 0xFFFFFFFF > /sys/module/acpi/parameters/debug_layer
echo 0x00000002 > /sys/module/acpi/parameters/debug_level
acall(){ echo "$1" | sudo tee /proc/acpi/call >/dev/null && sudo cat /proc/acpi/call;echo;}

VGBI_UUID_DGPU="{0x69 0x5C 0xD0 0x6F 0xE3 0xCD 0xF4 0x49 0x95 0xED 0xAB 0x16 0x65 0x49 0x80 0x35}"
acall_vgbi_dgpu(){ acall "\_SB_.PCI0.LPCB.EC0_.VGBI._DSM $VGBI_UUID_DGPU 1 1 0";}
$ dmesg -xHw
# acall_vgbi_dgpu
kern  :warn  : [Apr 6 21:27] ACPI Warning: \_SB.PCI0.LPCB.EC0.VGBI._DSM: Argument #4 type mismatch - Found [Integer], ACPI requires [Package] (20181213/nsarguments-66)
kern  :warn  : [  +0.000762] ACPI Debug:  "[EC0._DSM] - Base attached, powering dGPU"
kern  :warn  : [  +0.000019] ACPI Debug:  "SAM Command Method - Cmd = 0000000000000005"
kern  :warn  : [  +0.000019] surface_sam: handler called
kern  :warn  : [  +0.000798] surface_sam: writing to i2c, status: 0
# acall_vgbi_dgpu
kern  :warn  : [  +6.355106] ACPI Debug:  "[EC0._DSM] - dGPU PCIe linking"
kern  :warn  : [  +0.000019] ACPI Debug:  "HGON"
kern  :warn  : [  +0.000038] ACPI Debug:  "SAM Command Method - Cmd = 0000000000000005"
kern  :warn  : [  +0.000027] surface_sam: handler called
kern  :warn  : [  +0.000762] surface_sam: writing to i2c, status: 0
kern  :warn  : [  +0.001127] ACPI Debug:  "|- GPIO_GPU_PWR_STATE Time delay = 0000000000000000X"
kern  :info  : [  +0.029456] pciehp 0000:00:1c.0:pcie004: Slot(4): Card present
kern  :warn  : [  +0.110972] ACPI Debug:  "|- L23R wait time = 0000000000000000X"
kern  :warn  : [  +0.000102] ACPI Debug:  "|- LASX wait time = 0000000000000000X"
kern  :debug : [  +0.049762] pci 0000:01:00.0: [10de:1427] type 00 class 0x030200
kern  :debug : [  +0.000034] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00ffffff]
kern  :debug : [  +0.000015] pci 0000:01:00.0: reg 0x14: [mem 0x00000000-0x0fffffff 64bit pref]
kern  :debug : [  +0.000014] pci 0000:01:00.0: reg 0x1c: [mem 0x00000000-0x01ffffff 64bit pref]
kern  :debug : [  +0.000008] pci 0000:01:00.0: reg 0x24: [io  0x0000-0x007f]
kern  :debug : [  +0.000010] pci 0000:01:00.0: reg 0x30: [mem 0x00000000-0x0007ffff pref]
kern  :info  : [  +0.000163] pci 0000:01:00.0: 15.752 Gb/s available PCIe bandwidth, limited by 8 GT/s x2 link at 0000:00:1c.0 (capable of 126.016 Gb/s with 8 GT/s x16 link)
kern  :info  : [  +0.009645] pci 0000:01:00.0: BAR 1: assigned [mem 0xc0000000-0xcfffffff 64bit pref]
kern  :info  : [  +0.000021] pci 0000:01:00.0: BAR 3: assigned [mem 0xa2000000-0xa3ffffff 64bit pref]
kern  :info  : [  +0.000017] pci 0000:01:00.0: BAR 0: assigned [mem 0xba000000-0xbaffffff]
kern  :info  : [  +0.000009] pci 0000:01:00.0: BAR 6: assigned [mem 0xb9700000-0xb977ffff pref]
kern  :info  : [  +0.000005] pci 0000:01:00.0: BAR 5: assigned [io  0x3000-0x307f]
kern  :info  : [  +0.000010] pcieport 0000:00:1c.0: PCI bridge to [bus 01]
kern  :info  : [  +0.000006] pcieport 0000:00:1c.0:   bridge window [io  0x3000-0x6fff]
kern  :info  : [  +0.000008] pcieport 0000:00:1c.0:   bridge window [mem 0xb9700000-0xd16fffff]
kern  :info  : [  +0.000007] pcieport 0000:00:1c.0:   bridge window [mem 0xa1400000-0xb93fffff 64bit pref]
kern  :info  : [  +0.028090] IPMI message handler: version 39.2
kern  :info  : [  +0.004585] ipmi device interface
kern  :warn  : [  +0.016943] nvidia: module license 'NVIDIA' taints kernel.
kern  :warn  : [  +0.000002] Disabling lock debugging due to kernel taint
kern  :info  : [  +0.024636] nvidia-nvlink: Nvlink Core is being initialized, major device number 234
kern  :info  : [  +0.000817] nvidia 0000:01:00.0: enabling device (0000 -> 0003)
kern  :info  : [  +0.078167] pcieport 0000:00:1c.0: PCI bridge to [bus 01]
kern  :info  : [  +0.000004] pcieport 0000:00:1c.0:   bridge window [io  0x3000-0x6fff]
kern  :info  : [  +0.000005] pcieport 0000:00:1c.0:   bridge window [mem 0xb9700000-0xd16fffff]
kern  :info  : [  +0.000004] pcieport 0000:00:1c.0:   bridge window [mem 0xa1400000-0xb93fffff 64bit pref]
kern  :warn  : [  +0.022806] NVRM: loading NVIDIA UNIX x86_64 Kernel Module  418.56  Fri Mar 15 12:59:26 CDT 2019
kern  :info  : [  +0.007129] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms  418.56  Fri Mar 15 12:32:40 CDT 2019
kern  :info  : [  +0.004722] [drm] [nvidia-drm] [GPU ID 0x00000100] Loading driver
kern  :info  : [  +0.000003] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:01:00.0 on minor 1

run acall_vgbi_dgpu when base detached to unlink dGPU from PCIe:

$ dmesg -xHw
# acall_vgbi_dgpu
kern  :warn  : [  +9.287502] ACPI Debug:  "[EC0._DSM] - Base detached"

then, attach the base and run acall_vgbi_dgpu twice again to power dGPU on again.

kitakar5525 avatar Apr 06 '19 12:04 kitakar5525

I'm reading the document linux-surfacegen5-acpi/surface-dtx.txt now and I noticed

sudo modprobe i2c-dev
scmd(){
    sudo i2cset -f -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 "$1" \
        0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i
}

scmd 0x08 && sleep 0.1 && scmd 0x09

makes detach faster on SB1, too. This is useful.

kitakar5525 avatar Apr 06 '19 15:04 kitakar5525

Awesome! I think with that the ACPI part is done, the rest should work via a HID driver. According to the descriptor from one of your logs, the HID vendor/product IDs should be 045E:0914 (vendor is Microsoft, so that would make sense). I think by just attaching a basic driver that dumps all input-reports we should get a good overview of how to proceed.

Yeah, the SB2 and SB1 seem to have the same command IDs for the detachment system, it might also be the same for the events. I've written down all I could find so far in the documentation.

qzed avatar Apr 06 '19 16:04 qzed

If you want to, you could try and implement a basic HID driver, I haven't looked into that yet. Not sure when I'll get to that.

qzed avatar Apr 06 '19 20:04 qzed

I think by just attaching a basic driver that dumps all input-reports we should get a good overview of how to proceed.

you could try and implement a basic HID driver

Okay, I don't know how to do that quite well right now, though I will also try to do it.

Thank you so much!

kitakar5525 avatar Apr 08 '19 10:04 kitakar5525

I can't help you with the HID driver specifics (haven't read into that yet), but the overall driver structure is always the same, so you should get started with a basic driver tutorial. Very briefly: Create a kernel module, fill the static driver struct (should be hid_driver in this case) and register it with the respective macro (should module_hid_driver in this case). Also a good website to look at the code specifics or some examples is https://elixir.bootlin.com/linux/latest/source, that site helped me really at the beginning.

Also feel free to ask any questions (here or on gitter) if you have some!

qzed avatar Apr 08 '19 18:04 qzed

What would be the ideal functionality of this driver.

  • Detachment events. Should it do all the handling, or should it simply forward them to user space for a separate daemon to handle?
  • Does it need to so something about dGPU?
  • Are there other things we would want to use SAM for?

tmarkov avatar Apr 08 '19 18:04 tmarkov

@tmarkov It would be ideal if in the end it would be compatible to the detachment-system driver on the SB2, as I've already written a basic user-space daemon for this. And from what it looks like now, I think we can make it so, although I'd like to get a bit more information on what SAM does (and potential differences to the newer device generations which use the SSH instead), hence implementing a basic driver that just "dumps" everything it receives should be a good start.

The current situation on the SB2 is: Detachment-requests are forwarded from the driver to user-space, handled in user-space by the daemon, which then either opens the latch or aborts detachment. The daemon can run any script you specify. This can be used to e.g. unload the driver and unmount any USB/storage-devices attached to the base. As far as I know, there is no special handling required for the dGPU, although it could make sense to make sure that it's turned off prior to detaching, which should also be possible via the script once we've implemented a bit more friendly way to do this (I'm currently focusing on that part for the SB2, it might be possible to also apply this to the SB1).

As to the other things we could use SAM for: It seems that SAM has quite a few other capabilities (if you're interested in this you could have a look at the presentation linked somewhere above) and the HID interface could be used for them, though I don't know if we'll end up using them yet. Nevertheless it would make sense to keep a similar structure as I've done in the driver for the newer devices and separate the SAM part from the detachment and other more specific parts.

qzed avatar Apr 08 '19 20:04 qzed

@kitakar5525 Have you made any progress? If not I can have a look at this again.

qzed avatar Apr 23 '19 12:04 qzed

Sadly no progress from me. I'm now a little bit busy for a while -_-

kitakar5525 avatar Apr 23 '19 12:04 kitakar5525

That's alright, I can have a look at this later today if you want me to.

qzed avatar Apr 23 '19 12:04 qzed

I'd appreciate it if you could.

kitakar5525 avatar Apr 23 '19 12:04 kitakar5525

Awesome, I've got some time today, I'll see how far I can get.

qzed avatar Apr 23 '19 12:04 qzed

@kitakar5525 Okay, I've added a small module that should log all events/records being sent from the SAM device here (just build it with make in the module directory, then run sudo insmod hid_surface_sam.ko). Can you get me a dmesg log of what happens when you press the detach button with the driver loaded?

You might need to make sure that the driver gets properly loaded by unbinding the generic hid driver, similar to what is described here, just use hid instead of usb in the paths. The device path should contain the device ID, i.e. 045E:0914. There should be a message in the dmesg log containing sam_probe: if it has attached correctly.

qzed avatar Apr 23 '19 14:04 qzed

Sorry to be late!

Preparing

ls /sys/bus/hid/drivers/*
/sys/bus/hid/drivers/hid-generic:
bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-multitouch:
0003:045E:07CE.0004  0044:1B96:005E.0006  bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-sensor-hub:
0018:045E:0914.0001  bind  module  new_id  uevent  unbind

Unbind 0018:045E:0914.0001 from hid-sensor-hub

sudo sh -c "echo -n '0018:045E:0914.0001' > /sys/bus/hid/drivers/hid-sensor-hub/unbind"
ls /sys/bus/hid/drivers/*
/sys/bus/hid/drivers/hid-generic:
bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-multitouch:
0003:045E:07CE.0004  0044:1B96:005E.0006  bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-sensor-hub:
bind  module  new_id  uevent  unbind

Load the module

sudo insmod hid_surface_sam.ko
ls /sys/bus/hid/drivers/*
/sys/bus/hid/drivers/hid-generic:
bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-multitouch:
0003:045E:07CE.0004  0044:1B96:005E.0006  bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid-sensor-hub:
bind  module  new_id  uevent  unbind

/sys/bus/hid/drivers/hid_surface_sam:
0018:045E:0914.0001  bind  module  new_id  uevent  unbind

dmesg log

Can you get me a dmesg log of what happens when you press the detach button with the driver loaded?

Here is a complete log after loading the module, detach the base, re-attach the base and remove the module. Lines starting with # are my comment.

dmesg-xHw.txt

It seems

  • the module is correctly attached
  • I cannot see anything regarding detach/attach yet

EDIT

Below is an excerpt of the relevant part (Lines starting with # are my comment):

$ dmesg -xHw
# sudo insmod hid_surface_sam.ko
kern  :info  : [  +0.107206] hid_surface_sam 0018:045E:0914.0001: sam_probe: device: MSHW0030:00 045E:0914, bus: 24
# detach the base
    # no relevant logs
# attach the base
    # no relevant logs
# sudo rmmod hid_surface_sam.ko
kern  :info  : [Apr24 14:29] hid_surface_sam 0018:045E:0914.0001: sam_remove: device: MSHW0030:00 045E:0914, bus: 24

kitakar5525 avatar Apr 24 '19 05:04 kitakar5525

Sorry to be late.

Nothing to be sorry for!

I cannot see anything regarding detach/attach yet

That's what I've feared. I haven't called start or open on the device yet, so I'll have to check the hid subsystem what it expects specifically. Since the other commands don't seem to require any of this, I hoped it would just work.

If that doesn't work, I need to have another look at your spbProbe logs. Might be we need to enable these events (that's the case on the SAM via SSH side).

qzed avatar Apr 24 '19 07:04 qzed

Okay, I've added the call to hid_hw_start now, any changes?. Now that I think about it, the generic driver probably called that before any of the commands ever got executed.

qzed avatar Apr 24 '19 07:04 qzed

A log file as before: dmesg-xHw.txt

Below is an excerpt of the relevant part (Lines starting with # are my comment):

$ dmesg -xHw
# sudo insmod hid_surface_sam.ko
kern  :info  : [  +0.105052] hid_surface_sam 0018:045E:0914.0001: sam_probe: device: MSHW0030:00 045E:0914, bus: 24
kern  :info  : [  +0.000129] hid_surface_sam 0018:045E:0914.0001: hidraw2: I2C HID v1.00 Device [MSHW0030:00 045E:0914] on i2c-MSHW0030:00
kern  :info  : [  +0.000003] hid_surface_sam 0018:045E:0914.0001: sam_probe: success
# detach the base
    # no relevant logs
# attach the base
    # no relevant logs
# sudo rmmod hid_surface_sam.ko
kern  :info  : [  +8.174257] hid_surface_sam 0018:045E:0914.0001: sam_remove: device: MSHW0030:00 045E:0914, bus: 24

I still cannot see anything regarding detach/attach yet.

kitakar5525 avatar Apr 26 '19 13:04 kitakar5525

Yeah okay, looks like we need to configure the device. I'll have another look at the logs and see if I can find anything.

qzed avatar Apr 26 '19 15:04 qzed

Okay, so this will probably need some trial-and-error... I've annotated your logs based on the hid-over-i2c spec and it looks quite interesting. There are some commands very similar to the SCMD commands from ACPI, specifically:

  • O_SCMD (0x02): This is basically SCMD (0x02) with the difference that it's send as an output-report instead of a feature report. No idea if this makes any substantial difference though, and no idea what that command does... it's all over the place and I can't connect it to one specific event.
  • SCMD (0x12): This might be an init-command. It is send before any of the input reports arrive. Furthermore, what looks like some additional configuration via set-feature-report is only done after this command has been issued.
  • SCMD (0x09): We already know what that one does (thanks to your testing, opens the base latch), so I think it's a good hint that the previous input report (there is only one in the log) is the detach-request event (i.e. shows what we'd expect to see).

If you want to try out some stuff: You could try and send the SCMD 0x12 and O_SCMD 0x02 commands while the driver is attached. Should be possible via hidraw (doc) as your dmesg log from attaching the driver indicates that there is an hidraw device created. I might try and write a script for that when I find the time.

spb-detach.log spb-enable.log

qzed avatar Apr 26 '19 21:04 qzed

@kitakar5525 Sorry it took me this long, thanks for your patience! I've pushed a script to send a SCMD via hidraw. Unfortunately I can't test it so you probably should check that it works by sending the known detach commands (0x08, 0x09). You can simply run it via

sudo ./scripts/hidraw-scmd /dev/hidrawX <scmd-id>

after loading the module. You should find the specific hidraw device in the dmesg log as above (comment). The interesting part should now be: What happens when you run SCMD 0x12 before detaching? What if you run SCMD 0x02?

qzed avatar Jun 03 '19 01:06 qzed

Thank you for your work! I tested the script!

First, I need to modify the data list in scmd() like this:

@@ -69,8 +69,8 @@ class HidDevice():
     def scmd(self, code):
         data = [
             0x24,    # first byte must be report id
-            0x24, code, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            code, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         ]

Then, load the module like the above comment (https://github.com/jakeday/linux-surface/issues/286#issuecomment-486075439):

$ dmesg -xHw
kern  :warn  : [ +23.596308] ACPI Debug:  "SAM wake up interrupt sent"
kern  :info  : [  +0.109889] hid_surface_sam 0018:045E:0914.0001: sam_probe: device: MSHW0030:00 045E:0914, bus: 24
kern  :info  : [  +0.000498] hid_surface_sam 0018:045E:0914.0001: hidraw2: I2C HID v1.00 Device [MSHW0030:00 045E:0914] on i2c-MSHW0030:00
kern  :info  : [  +0.000010] hid_surface_sam 0018:045E:0914.0001: sam_probe: success

and send a command:

$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x08

and the base is detached. The first time it takes about 5 seconds to be ready for detach, the second time or later it will be ready for detaching immediately.

Regarding 0x12 and 0x02, I see no difference compared to only sending 0x08:

$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x12
$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x08
$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x02
$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x08

kitakar5525 avatar Jun 05 '19 15:06 kitakar5525

@kitakar5525 Thanks for the correction, are you sure it's 16 bytes and not 17 for data? From the DSDT the payload should be 19 bytes minus the 2 bytes specifying the length, although this might not change anything.

I'm still convinced that we're missing some sort of setup call/routine. I'll adapt the script to also support sending output reports and getting feature reports. At this point I can't really make any more speculations from the logs, so you might have to modify the script a bit to poke around (e.g. trying different SCMDs, or maybe reading some feature reports). You could try and replay your logs and see if that gets you anywhere. In general you shouldn't be able to break something with this, but I can't make any guarantees.

qzed avatar Jun 05 '19 16:06 qzed

are you sure it's 16 bytes and not 17 for data?

Oh, sorry it's 17 bytes. I can confirm this (17 bytes for data) also worked:

@@ -69,7 +69,7 @@ class HidDevice():
     def scmd(self, code):
         data = [
             0x24,    # first byte must be report id
-            0x24, code, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            code, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         ]

kitakar5525 avatar Jun 05 '19 17:06 kitakar5525

@kitakar5525 No worries! Shouldn't make much difference, only if the command takes some arguments or more data I guess.

One thing you could maybe also try is to log the SAM communication on Windows during suspend/resume. Commands sent during the resuming phase were on the SSH (SB2, ...) at least directly related to event setup, maybe that could give us the right clue.

qzed avatar Jun 06 '19 11:06 qzed

Wrong button, sorry!

qzed avatar Jun 06 '19 11:06 qzed

@qzed By the way, do you have any idea how to coexist hid-sensor-hub and hid_surface_sam? Currently, I have to unbind hid-sensor-hub to bind hid_surface_sam to 0018:045E:0914.0001

kitakar5525 avatar Jul 04 '19 12:07 kitakar5525

No idea, sorry. IIRC we have a remotely similar problem for the SP17 type-cover backlight issue (https://github.com/qzed/linux-surfacegen5-acpi/issues/4) where we'd have to extend the functionality of a HID driver.

qzed avatar Jul 04 '19 15:07 qzed

Hi,

As a SB1 (i5-6300U, 8GB RAM, Nvidia 940M) owner, it makes me really happy to see some people digging into this. Thank you for your efforts! :)

@qzed Is the following a fair summary of the current state of dGPU support on the SB1? You guys have identified the bus the dGPU operates on, now looking to create a module / driver that makes it available in userspace and also handles detach / attach of the base?

As a person with no coding skills, is there anything I can do to support you guys?

irreleph4nt avatar Jul 12 '19 23:07 irreleph4nt

qzed managed to power dGPU on

I've not tested yet whether the dGPU actually works.

We are now working on handling the dGPU by a kernel module.

Logging SAM device communication is a complicated one.

One thing you could maybe also try is to log the SAM communication on Windows during suspend/resume. Commands sent during the resuming phase were on the SSH (SB2, ...) at least directly related to event setup, maybe that could give us the right clue.

If someone is interested in logging SAM, please refer to my comment (https://github.com/jakeday/linux-surface/issues/286#issuecomment-477260349)

There are several things which have higher priority than dGPU for me for now. I hope those who are more interested in dGPU may work on this issue with qzed.

kitakar5525 avatar Aug 15 '19 05:08 kitakar5525

Hi hope this is not a stupid question, but could someone enlighten on how to add the kernel provided by qzed.

brokenheist avatar Aug 18 '19 23:08 brokenheist

Hi @brokenheist. Do you mean you want to apply the patch 0001-Add-quirk-for-Surface-SAM-I2C-address-space.patch to see if dGPU will work on SB1?

kitakar5525 avatar Sep 07 '19 11:09 kitakar5525

@brokenheist I'm super sorry for taking a long time to answer🙇

Following is the guide to build kernels for Debian-based distros with the SAM I2C quirk patch (0001-Add-quirk-for-Surface-SAM-I2C-address-space.patch).

building the kernel for Debian-based distros with the SAM I2C quirk patch

If you're interested, click here to expand

First, clone the linux-surface repository (from qzed fork):

git clone --depth 1 https://github.com/qzed/linux-surface.git

Then, you can mostly follow this guide: https://github.com/qzed/linux-surface#compiling-the-kernel-from-source

(Optional) On Step 1, if your network is too slow, you can reduce the download size by using --depth 1 (limit commit history) and just clone linux-5.3.y branch (instead of master). In this case, you can skip Step 3.

git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ -b linux-5.3.y linux-stable

On Step 3, checkout linux-5.3.y (5.3.y is currently the most recent stable kernel)

git checkout -b linux-5.3.y origin/linux-5.3.y

After Step 4, you can apply additional patches like Step 4. Download the patch:

cd ..
wget https://raw.githubusercontent.com/qzed/linux-surface-sam-hid/master/patches/5.1/0001-Add-quirk-for-Surface-SAM-I2C-address-space.patch

Apply the patch:

cd linux-stable
patch -p1 -i ../0001-Add-quirk-for-Surface-SAM-I2C-address-space.patch

On Step 5, get kernel config from qzed/linux-surface-kernel-configs

wget https://raw.githubusercontent.com/qzed/linux-surface-kernel-configs/v5.3/debian-5.3-x86_64.config -O .config

(Optional) After Step 5, you can skip generating dbg package by setting CONFIG_DEBUG_INFO=n (using make menuconfig)

(Optional) On Step 6, you can instead use LOCALVERSION=-surface to match with qzed build.

On Step 7, install the deb packages

cd ..
sudo dpkg -i linux-headers-*.deb linux-image-*.deb linux-libc-dev-*.deb

binary release

For Debian-based distros, I've also built the kernel and released it here (this time only) For Arch-based distros, have a look at my repository (It includes the SAM I2C quirk patch)

Secure Boot signing

Sorry, I don't know well (yet) about Secure Boot signing. Just disable the Secure Boot or sign the kernel manually.

installing acpi-call

sudo apt install acpi-call-dkms

Load the module (might be required after every boot on Ubuntu?)

sudo modprobe acpi_call

Then, make sure if the path exists:

ls /proc/acpi/call

powering on the dGPU

Have a look at my comment (https://github.com/jakeday/linux-surface/issues/286#issuecomment-521518380)


We need to rebuild the whole kernel because what we're trying to patch is not a module in this case. I hope many people work on this issue!

kitakar5525 avatar Oct 18 '19 15:10 kitakar5525

@kitakar5525 Thank you so much for this detailed explanation! Will the config you mention also work for other distributions than Ubuntu/Debian? Do you have, for example, your Arch config flying around somewhere so that others can use it? I'll have a look at this once exam period is over. Besides collecting SAM data (had a look at your previous comments), is there anything we can do to support? Like, looking to answer particular questions when investigating the data?

irreleph4nt avatar Oct 18 '19 21:10 irreleph4nt

Will the config you mention also work for other distributions than Ubuntu/Debian?

qzed also provides a config for Arch Linux on qzed/linux-surface-kernel-configs (I'll add this link to my previous comment)

That being said, for most distros, I think that

  1. after applying patches
  2. get distribution's config (e.g. official Arch Linux config is here)
  3. just running make oldconfig
  4. just answering m or y may be sufficient.

is there anything we can do to support?

The current issue on the module is that, we have to unbind hid-sensor-hub first (https://github.com/jakeday/linux-surface/issues/286#issuecomment-486075439). To be honest, I've never done this kind of things before, I also don't know what we should do next 😰

kitakar5525 avatar Oct 19 '19 02:10 kitakar5525

@kitakar5525

scmd(){
    sudo i2cset -f -y 5 0x28 0x05 0x00 0x3f 0x03 0x24 0x06 0x00 0x13 0x00 0x24 "$1" \
        0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 i
}

As of the latest release, 5.3.6, the above function seems to be failing for me with Error: Write failed. Do you know what could have broken it?

tmarkov avatar Oct 21 '19 16:10 tmarkov

I2CBUS or CHIP-ADDRESS might be different. On the example

  • I2CBUS is 5
  • CHIP-ADDRESS is 0x28

locating I2CBUS

Try to locate I2CBUS with

ls -lh /sys/bus/i2c/devices/ | grep "MSHW0030"

X in i2c-X is the I2CBUS

For example, on my SB1:

$ ls -lh /sys/bus/i2c/devices/ | grep "MSHW0030"
lrwxrwxrwx 1 root root 0 Oct 21 23:06 i2c-MSHW0030:00 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-5/i2c-MSHW0030:00

So, it's 5

locating CHIP-ADDRESS

Try to locate CHIP-ADDRESS with

sudo i2cdetect -y -r ${I2CBUS}

For example, on my SB1:

$ sudo i2cdetect -y -r 5
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

So, it's 0x28

kitakar5525 avatar Oct 21 '19 17:10 kitakar5525

By the way, I mentioned before that I cannot see any events from hid_surface_sam module:

I still cannot see anything regarding detach/attach yet. https://github.com/jakeday/linux-surface/issues/286#issuecomment-487061831

So, I modified hid-sensor-hub instead:

sam event logging using hid_surface_sam

diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index be92a6f79..bdcfc4bb9 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -476,6 +476,12 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
        void *priv = NULL;
        struct hid_sensor_hub_device *hsdev = NULL;
 
+       if (report->application != 2097153) {
+               hid_info(hdev, "sam_raw_event\n");
+               hid_info(hdev, "  report: id=%u, type=%u, application=%u\n", report->id, report->type, report->application);
+               print_hex_dump(KERN_INFO, "raw_data: ", DUMP_PREFIX_OFFSET, 16, 1, raw_data, size, false);
+       }
+
        hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
                         report->id, size, report->type);
        hid_dbg(hdev, "maxfield:%d\n", report->maxfield);
@@ -746,6 +752,25 @@ static void sensor_hub_remove(struct hid_device *hdev)
        mutex_destroy(&data->mutex);
 }
 
+static int sam_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value)
+{
+       if (field->application != 2097153) {
+               hid_info(hdev, "sam_event\n");
+               hid_info(hdev, " field: physical=%u, logical=%u, application=%u\n", field->physical, field->logical, field->application);
+               hid_info(hdev, " usage: hid=%u, c_idx=%u, u_idx=%u\n", usage->hid, usage->collection_index, usage->usage_index);
+               hid_info(hdev, " value: %d\n", value);
+       }
+       return 1;
+}
+
+static void sam_report(struct hid_device *hdev, struct hid_report *report)
+{
+       if (report->application != 2097153) {
+               hid_info(hdev, "sam_report: \n");
+               hid_info(hdev, "  report: id=%u, type=%u, application=%u\n", report->id, report->type, report->application);
+       }
+}
+
 static const struct hid_device_id sensor_hub_devices[] = {
        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
                     HID_ANY_ID) },
@@ -759,6 +784,8 @@ static struct hid_driver sensor_hub_driver = {
        .probe = sensor_hub_probe,
        .remove = sensor_hub_remove,
        .raw_event = sensor_hub_raw_event,
+       .event            = sam_event,
+       .report           = sam_report,
        .report_fixup = sensor_hub_report_fixup,
 #ifdef CONFIG_PM
        .suspend = sensor_hub_suspend,

It seems that application == 2097153 is sensor data. So, I excluded it from logging.

application == 4278452304 seems to appear when I pressed detach button:

# pressed detach button
kern  :info  : [38103.530994] hid-sensor-hub 0018:045E:0914.0021: sam_raw_event
kern  :info  : [38103.531003] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304
kern  :info  : [38103.531009] raw_data: 00000000: 24 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [38103.531013] raw_data: 00000010: 00 00
kern  :info  : [38103.531023] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38103.531029] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38103.531035] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452350, c_idx=31, u_idx=0
kern  :info  : [38103.531040] hid-sensor-hub 0018:045E:0914.0021:  value: 258
kern  :info  : [38103.531045] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38103.531049] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38103.531054] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452351, c_idx=31, u_idx=1
kern  :info  : [38103.531058] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38103.531062] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38103.531067] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38103.531072] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452352, c_idx=31, u_idx=2
kern  :info  : [38103.531076] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38103.531080] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38103.531084] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38103.531088] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452353, c_idx=31, u_idx=3
kern  :info  : [38103.531090] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38103.531094] hid-sensor-hub 0018:045E:0914.0021: sam_report: 
kern  :info  : [38103.531097] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304

# latch opened
kern  :info  : [38109.263944] hid-sensor-hub 0018:045E:0914.0021: sam_raw_event
kern  :info  : [38109.263957] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304
kern  :info  : [38109.263965] raw_data: 00000000: 24 02 03 01 01 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [38109.263970] raw_data: 00000010: 00 00
kern  :info  : [38109.263983] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38109.263991] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38109.263998] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452350, c_idx=31, u_idx=0
kern  :info  : [38109.264005] hid-sensor-hub 0018:045E:0914.0021:  value: 16843522
kern  :info  : [38109.264010] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38109.264017] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38109.264023] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452351, c_idx=31, u_idx=1
kern  :info  : [38109.264029] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38109.264034] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38109.264040] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38109.264046] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452352, c_idx=31, u_idx=2
kern  :info  : [38109.264051] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38109.264056] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38109.264063] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38109.264069] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452353, c_idx=31, u_idx=3
kern  :info  : [38109.264074] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38109.264080] hid-sensor-hub 0018:045E:0914.0021: sam_report: 
kern  :info  : [38109.264087] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304

# latch closed
kern  :info  : [38118.400097] hid-sensor-hub 0018:045E:0914.0021: sam_raw_event
kern  :info  : [38118.400104] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304
kern  :info  : [38118.400109] raw_data: 00000000: 24 02 03 00 00 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [38118.400112] raw_data: 00000010: 00 00
kern  :info  : [38118.400120] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38118.400123] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38118.400127] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452350, c_idx=31, u_idx=0
kern  :info  : [38118.400130] hid-sensor-hub 0018:045E:0914.0021:  value: 770
kern  :info  : [38118.400133] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38118.400136] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38118.400139] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452351, c_idx=31, u_idx=1
kern  :info  : [38118.400142] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38118.400144] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38118.400147] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38118.400150] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452352, c_idx=31, u_idx=2
kern  :info  : [38118.400153] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38118.400155] hid-sensor-hub 0018:045E:0914.0021: sam_event
kern  :info  : [38118.400159] hid-sensor-hub 0018:045E:0914.0021:  field: physical=0, logical=0, application=4278452304
kern  :info  : [38118.400162] hid-sensor-hub 0018:045E:0914.0021:  usage: hid=4278452353, c_idx=31, u_idx=3
kern  :info  : [38118.400164] hid-sensor-hub 0018:045E:0914.0021:  value: 0
kern  :info  : [38118.400168] hid-sensor-hub 0018:045E:0914.0021: sam_report: 
kern  :info  : [38118.400171] hid-sensor-hub 0018:045E:0914.0021:   report: id=36, type=0, application=4278452304

kitakar5525 avatar Nov 15 '19 22:11 kitakar5525

Then, I modified hid-sensor-hub again to use hidraw:

hidraw using hid-sensor-hub

diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index be92a6f79..29e1de8ef 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -626,7 +632,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
        }
        INIT_LIST_HEAD(&hdev->inputs);
 
-       ret = hid_hw_start(hdev, 0);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
        if (ret) {
                hid_err(hdev, "hw start failed\n");
                return ret;

and run the script (https://github.com/qzed/linux-surface-sam-hid)

# detach the base
$ sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x08
$ dmesg -xw
# sudo ./scripts/hidraw-scmd.py /dev/hidraw2 0x08
kern  :info  : [  582.239399] hid-sensor-hub 0018:045E:0914.0005: sam_raw_event
kern  :info  : [  582.239401] hid-sensor-hub 0018:045E:0914.0005:   report: id=36, type=0, application=4278452304
kern  :info  : [  582.239402] raw_data: 00000000: 24 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [  582.239403] raw_data: 00000010: 00 00

# latch opened
kern  :info  : [  587.973222] hid-sensor-hub 0018:045E:0914.0005: sam_raw_event
kern  :info  : [  587.973240] hid-sensor-hub 0018:045E:0914.0005:   report: id=36, type=0, application=4278452304
kern  :info  : [  587.973253] raw_data: 00000000: 24 02 03 01 01 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [  587.973260] raw_data: 00000010: 00 00

# latch closed
kern  :info  : [  596.952917] hid-sensor-hub 0018:045E:0914.0005: sam_raw_event
kern  :info  : [  596.952924] hid-sensor-hub 0018:045E:0914.0005:   report: id=36, type=0, application=4278452304
kern  :info  : [  596.952928] raw_data: 00000000: 24 02 03 00 00 00 00 00 00 00 00 00 00 00 00 00
kern  :info  : [  596.952931] raw_data: 00000010: 00 00

kitakar5525 avatar Nov 15 '19 22:11 kitakar5525

i7 SB1 here, wanting to do my part. Thank you for all your efforts thusfar.

Signed, installed, and booted the 5.3.7 kernel (with headers). Can't make it past that:

chiekku@surface:~$ sudo modprobe acpi_call
modprobe: FATAL: Module acpi_call not found in directory /lib/modules/5.3.7-linux-surface

I'm new to kernels so I looked up where to get the acpi_call module. Found this:

https://github.com/marcoDallas/acpi_call_GUI_systemd

Looks like it's got dGPU enablement in mind. When you try to install the acpi_call module, it redirects to this page:

http://hybrid-graphics-linux.tuxfamily.org/index.php?title=ACPI_calls

And that's where I stopped, because they warn you could brick the dGPU by putting in the wrong code.

I did go back and try that one I2C command and got a slightly different result:

chiekku@surface:~/acpi_call_GUI_systemd$ ls -lh /sys/bus/i2c/devices/ | grep "MSHW0030"
lrwxrwxrwx 1 root root 0 Dec 10 20:04 i2c-MSHW0030:00 -> ../../../devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-MSHW0030:00

Instead of "i2c-5" mine shows "i2c-0"; I'm wondering why it differs since you later use that number in other steps.

If someone could help me get the dGPU enabled I would be happy to do some logging or work on this issue. Looking to try something new with my C knowledge.

-chiekku

chiekku avatar Dec 11 '19 03:12 chiekku

Instead of "i2c-5" mine shows "i2c-0"; I'm wondering why it differs since you later use that number in other steps.

No worry about the number of i2c-X. The number X may vary.

kitakar5525 avatar Dec 11 '19 13:12 kitakar5525

Happy to help by testing also. Thank you all for your work!

jrevillard avatar Mar 29 '20 12:03 jrevillard