Xiashangning / BigSurface

A proposition for a fully intergrated kext for all Surface Pro hardwares
GNU General Public License v3.0
309 stars 23 forks source link

Cameras on SP4 - Enhancement #65

Open billabongbruno opened 2 years ago

billabongbruno commented 2 years ago

Hey there, again.

So, regarding this:

"TODO Cameras Impossible so far ACPI devices: CAMR,CAMF,CAM3(infrared camera)

Corresponding device id: OV8865,OV5693,OV7251

Even Linux failed to drive the cameras on SP7 (IPU4), SP6 and before (IPU3) might be possible but I do not have the device."

I have a Surface Pro 4 and have multiple OSes installed, including Linux distributions. If you want to me test out something for you, I can follow your instructions to see if I can be of any help on how to get the cameras to work (on SP4 / 5 / 6).

Just let me know.

Best regards, Bruno.

billabongbruno commented 2 years ago

EDIT 1:

Camera is already mapped and working on Linux distributions using Surface Kernel, which I have installed.

More on it here:

https://github.com/linux-surface/linux-surface/issues/91

and

https://github.com/linux-surface/linux-surface/issues/907#issuecomment-1238763264

Xiashangning commented 2 years ago

Sadly it is the least priority, because I basically know nothing about camera drivers, both on linux side and macOS side, not to mention I haven't got device on my hand. Porting the code to macOS and debugging it remotely is way too difficult and time consuming. I know that Linux have already supported the camera with IPU3 hardware. Let's just hope someone with this kind of knowledge and process a SP 4/5/6 to develop it. :(

MetalChris87 commented 2 years ago

I found a guy who has a working webcam on Surface Laptop 3. https://github.com/rchiruma/SurfaceLaptop3-OpenCore

I believe he mapped it using USB Mapping. I gave it a try last night on my Surface Book 3, but didn't manage to map the camera, however it's possible someone with more knowledge can do it. If you open the plist for the USBMAP kext you will see the camera is listed.

SheltangW commented 2 years ago

I have a surface laptop go, and the camera is on: HD Camera:

型号ID: UVC Camera VendorID_1032 ProductID_4368 唯一ID: 0x1460000004081110

I don't know why but something works. It was not driven previously.

billabongbruno commented 2 years ago

Some progress has been achieved (under Linux):

https://github.com/linux-surface/linux-surface/wiki/Camera-Support

billabongbruno commented 2 years ago

This bit is important, in particular, for the process of being able to map the cameras:

Reverse engineering tips

For some of the work to build camera support, reverse engineering the settings made by the Windows drivers for either the camera devices or their supporting ICs is necessary. One way to do this is to talk to the i2c devices directly and read the registers to discover the settings. A mandatory first step is informing Windows that direct user access to those devices is allowed.

To perform that operation you will first need the microsoft asl compiler tool. This lets you extract and insert modified DSDT tables in Windows.

Once you've got that tool built, you need to edit the DSDT table to tell Windows to expose the I2C device for the PMIC. Run asl.exe /tab=DSDT to get a file named DSDT.asl in the current directory. You then need to make edits following this guide to add a section to the DSDT that creates an MSFT8000 dummy device and adds an I2cSerialBus entry describing the I2C Bus that the target device sits on, for example:

Device(RHPX)
{
    Name(_HID, "MSFT8000")
    Name(_CID, "MSFT8000")
    Name(_UID, 1)

    Name(_CRS, ResourceTemplate()
    {
        I2CSerialBus(0xFFFF, , 0, , "\\_SB.PCI0.I2C2", , ,) // in this case, we want to grant access to the I2C2 bus
    })

    Name(_DSD, Package()
    {
        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
        Package()
        {
            Package(2) { "bus-I2C-I2C2", Package() { 0 }}, // The 0 here is the index of the related resource in _CRS
        }
    })
}

You also need to increase the version number of the table in the `DefinitionBlock() or the edits will be ignored

Once that's done, compile the edited DSDT.asl using asl.exe DSDT.ASL. If it throws compiler errors you'll have to fix them. If you can't get it working using this tool you can actually boot Linux and try using iasl, which is Intel's equivalent and seems to work a lot better. You'd have to transfer the compiled file back to Windows somehow.

Once the file's compiled, you insert it using asl.exe /loadtable -v DSDT.AML. Pay attention to the output of the command as you may need to enable test signing mode (bcdedit /set testsigning on) and disable secure boot. Finally, you need to reboot.

To talk to the I2C devices themselves, use the I2cTestTool. Build that and run I2cTestTool <> <> to connect to the device. For example to connect to the device at 0x4d on I2C bus 2 the command would be I2cTestTool 0x4d I2C2. You can then perform read and write operations over I2C. To read a register value you use the writeread command, sending the address of the register followed by the number of registers you want to read, for example writeread {30 0a} 2 to read 0x300a and 0x300b, which on Omnivision sensors is usually the chip's ID.