Page MenuHomeFreeBSD

Add atopcase, the Apple HID over SPI input driver [WIP: Someone w/ Hardware Needed]
ClosedPublic

Authored by val_packett.cool on Apr 28 2023, 4:28 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Sep 25, 12:18 PM
Unknown Object (File)
Wed, Sep 18, 11:37 PM
Unknown Object (File)
Thu, Sep 12, 11:14 PM
Unknown Object (File)
Wed, Sep 11, 3:51 PM
Unknown Object (File)
Aug 19 2024, 7:43 AM
Unknown Object (File)
Aug 19 2024, 4:07 AM
Unknown Object (File)
Aug 12 2024, 2:52 AM
Unknown Object (File)
Jul 31 2024, 6:52 PM
Subscribers

Details

Summary

This is a (currently WIP) driver for Apple's custom HID-over-SPI transport (nothing to do with the new HID-over-SPI Microsoft spec, completely bespoke and predates it by half a decade).

First, a history lesson to understand which models this is for. Apple MacBooks have a "fun" history with HID transports…

  • initially: the input controller is just hanging off of good old USB
  • 2015, MacBookPro12,1: the input controller gained an SPI connection directly to the Intel SoC, but USB is still supported, an ACPI call switches the controller to start working on SPI instead of USB ← atopcase_acpi included here is for this
  • 2016-2018: the input controller only has an SPI connection ← atopcase_acpi included here is for this
  • 2018-2020: the input controller is no longer connected directly to the SoC and instead input goes through the Apple T2 security chip which apparently presents a custom USB host controller interface, see apple-bce-drv for Linux with its "vhci"
  • 2020-2021: the input controller is directly connected to the Apple M1 series SoC ← later someone will be able to write an atopcase_fdt attachment for this
  • 2022-now: the input controller is now *inside* the Apple M2 series SoC, so instead of a bus like SPI, a simple FIFO called "dockchannel" is used… with a complex completely new HID transport over it

Sadly I no longer have access to the machine I've been testing this on (a MacBookPro12,1).
Now that the prerequisites have landed (thanks @wulf), I am publishing the driver in its current state—basically as it was when I was still testing it, just with more comments and ifdefs, so it should *work* at least—to get some help finishing it.

To finish this driver, I need help from two kinds of people:

  • people with access to 2015-2018 (pre-T2) MacBooks for testing, with a -CURRENT install on some drive booting on that machine (message me using the discord/matrix/telegram linked on my website at the bottom)
  • kernel experts to take a look at the code, especially to deal with the big ACPI issue here – the problem is that our device (that we probe by the ACPI id APP000D) is a sibling of the spibus under which we actually need to be, and to make that attachment-at-a-distance work I needed to hack the acpi_pci_update_device because it was tripping an assertion. ugh.

(and if someone is both a kernel developer and an owner of such a machine, that would be a dream :D)

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kernel experts to take a look at the code, especially to deal with the big ACPI issue here – the problem is that our device (that we probe by the ACPI id APP000D) is a sibling of the spibus under which we actually need to be, and to make that attachment-at-a-distance work I needed to hack the acpi_pci_update_device because it was tripping an assertion. ugh.

The sibling should be deleted and recreated as child of spibus to get proper ivars like iicbus does: https://github.com/freebsd/freebsd-src/blob/main/sys/dev/iicbus/acpi_iicbus.c#L459
And I wonder, how it produces interrupts as intel_spi misses some resource handling bus methods

In D39863#907564, @wulf wrote:

The sibling should be deleted and recreated as child of spibus to get proper ivars like iicbus does: https://github.com/freebsd/freebsd-src/blob/main/sys/dev/iicbus/acpi_iicbus.c#L459
And I wonder, how it produces interrupts as intel_spi misses some resource handling bus methods

The interrupts don't touch intel_spi at all! The interrupt line is, I think, just a separate gpio or something – the IRQ is a resource on the APP000D node in the DSDT.
Which is one of the reasons nothing should be deleted…

I do already create a child of the spibus, the only problem is that doing that hits that "parent is not acpi0" kassert. That code should only ever get called on direct descendants of a PCI bridge. But ends up called on one of our things. Hm.
AcpiWalkNamespace is called with max depth 1 so it shouldn't be that. Actually we shouldn't even get to the acpi_pci_update_device point without a PCI slot/func match directly between an ACPI node and a scanned PCI device. Are we just somehow causing the ACPI-enumerated intel_spi to get more fully attached before the PCI-enumerated one or… what even

Finally, I got MacBook 14,1 for some time and tried to run this driver on it. It required some extra work and result can be found here: https://github.com/wulf7/freebsd/commits/atopcase

In D39863#937356, @wulf wrote:

Finally, I got MacBook 14,1 for some time and tried to run this driver on it. It required some extra work and result can be found here: https://github.com/wulf7/freebsd/commits/atopcase

Yaaaay, very cool! The changes look excellent.

This revision was not accepted when it landed; it landed in state Needs Review.Aug 20 2023, 9:55 AM
This revision was automatically updated to reflect the committed changes.