Bug 108331

Summary: Macbook 12'' 2015: can't start keyboard
Product: Drivers Reporter: Dmitry (linuxover)
Component: Input DevicesAssignee: drivers_input-devices
Status: CLOSED INSUFFICIENT_DATA    
Severity: normal CC: adborden, aicommander, andy.shevchenko, brent, bugzilla, cavoegele, danielroschka+kernel, davidsvasak, florenzi+kernel, forum.addr, gicmo, hellohellodon, hfink, janboe.ye, john, johnbrisbois, jonathan, leif.liddy, lkml2819, lukas, m, mail, mail, oalonso, scramble, shops, stereo, szg00000, timothylui84, unera, wes
Priority: P1    
Hardware: x86-64   
OS: Linux   
Kernel Version: 4.4-rc[12] Subsystem:
Regression: No Bisected commit-id:
Attachments: dmesg, lspci, etc
OSX - IORegistry contents
ACPI DSDT table
Patch adding 9ce6 device to spi-pxa2xx-pci.c
Patch: adding 9ce6 device to spi-pxa2xx-pci.c
Patch: adding 9ce6 device to spi-pxa2xx-pci.c
DMA - IRQ testing
MacBook9,1 DSDT

Description Dmitry 2015-11-23 15:46:39 UTC
Created attachment 195231 [details]
dmesg, lspci, etc

I've tried to start linux on Macbook 2015.

But keyboard doesn't work (kernel starts, etc, but local keyboard doesn't work)

/proc/bus/input/devices doesnt contain any keyboard records.

dmesg contains several xhci_hcd timeouts:

dmesg|egrep 'xhci|hub'
[    2.340822] usbcore: registered new interface driver hub
[    2.341882] xhci_hcd 0000:00:14.0: xHCI Host Controller
[    2.341888] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1
[    2.342962] xhci_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x100 quirks 0x00009810
[    2.342969] xhci_hcd 0000:00:14.0: cache line size of 256 is not supported
[    2.343143] usb usb1: Manufacturer: Linux 4.4.0-rc1unera-next-20151123+ xhci-hcd
[    2.343287] hub 1-0:1.0: USB hub found
[    2.343299] hub 1-0:1.0: 11 ports detected
[    2.343582] xhci_hcd 0000:00:14.0: xHCI Host Controller
[    2.343587] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 2
[    2.343619] usb usb2: Manufacturer: Linux 4.4.0-rc1unera-next-20151123+ xhci-hcd
[    2.343756] hub 2-0:1.0: USB hub found
[    2.343763] hub 2-0:1.0: 4 ports detected
[    2.651787] usb 1-1: new high-speed USB device number 2 using xhci_hcd
[    7.559578] xhci_hcd 0000:00:14.0: Command completion event does not match command
[    7.559584] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   12.567382] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   12.567394] usb 1-1: hub failed to enable device, error -62
[   17.575183] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   17.687152] usb 1-1: new high-speed USB device number 3 using xhci_hcd
[   17.820478] hub 1-1:1.0: USB hub found
[   17.820948] hub 1-1:1.0: 2 ports detected
[   18.095138] usb 1-1.1: new high-speed USB device number 4 using xhci_hcd
[   18.259134] usb 1-1.2: new low-speed USB device number 5 using xhci_hcd


I've seen the patch http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dbe08116b87cdc2217f11a78b5b70e29068b7efd
It is applied and compiled, but keyboard don't work yet.
Unfortunately I can't find ticket about keyboard and macbook 2015.
Comment 1 Dmitry 2015-11-23 15:57:14 UTC
external USB keyboard works fine.
Comment 2 Greg Kroah-Hartman 2015-11-23 16:01:31 UTC
On Mon, Nov 23, 2015 at 03:46:39PM +0000, bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=108331
> 
>             Bug ID: 108331
>            Summary: Macbook 12'' 2015: can't start keyboard

Please send to the linux-input@vger.kernel.org mailing list.
Comment 3 unera 2015-11-23 16:24:40 UTC
Also the latest kernel (4.4rc[12]) can't detect internal HDD: only external USB flash.
Comment 4 Mathias Nyman 2016-01-21 10:32:53 UTC
[    2.346213] usbcore: registered new interface driver brcmfmac
[    2.360430] usbcore: registered new interface driver bcm5974
[    2.464329] brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac4350-pcie.bin failed with error -2
[    2.651787] usb 1-1: new high-speed USB device number 2 using xhci_hcd
[    3.279955] clocksource: Switched to clocksource tsc
[    7.559578] xhci_hcd 0000:00:14.0: Command completion event does not match command
[    7.559584] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   12.567382] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   12.567394] usb 1-1: hub failed to enable device, error -62
[   17.575183] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command
[   17.687152] usb 1-1: new high-speed USB device number 3 using xhci_hcd
[   17.779162] usb 2-1: device not accepting address 2, error -62

Looks like a usb interface drive is loaded for the broadcom wireless device. 
It tries to load firmware but fails already at finding/opening the file. (interal hdd access?) 

A bit suspicious that a usb interface driver wants to load a firmware named *-pcie.bin.

Is the Broadcom device really connected to USB?
Comment 5 Leif Liddy 2016-01-21 13:51:15 UTC
Internal HDD is working with latest kernel. 

Wireless card works after following instructions in comment #36 on this page:
https://forums.opensuse.org/showthread.php/507933-openSUSE-on-the-2015-Apple-12-Inch-Retina-MacBook/page4
Comment 6 unera 2016-01-21 15:13:47 UTC
My situation:

on Linux 4.4 works:

 - hdd
 - xorg
 - external usb
 - power suspend/hibrnate, etc
 - wifi (works fine using firmware brcmfmac4350c2-pcie.bin, brcmfmac4350-pcie.bin - doesn't work)

don't work:

 - internal keyboard
 - internal touchpad
 - internal bluetooth

don't checked:
  - sound and speaker
  - camera
Comment 7 Leif Liddy 2016-01-21 15:31:56 UTC
It looks like usbcore does discover the wireless interface

Jan 21 16:15:01 mac.example.com kernel: usbcore: registered new interface driver brcmfmac
Jan 21 16:15:01 mac.example.com kernel: brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac4350-pcie.txt failed with error -2
Jan 21 16:15:01 mac.example.com kernel: brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Nov 26 2015 03:48:57 version 7.35.180.133 (r602372) FWID 01-c45b39d6
Jan 21 16:15:01 mac.example.com kernel: brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code
Jan 21 16:15:01 mac.example.com kernel: brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code
Jan 21 16:15:01 mac.example.com kernel: brcmfmac 0000:01:00.0 wlp1s0: renamed from wlan0
Comment 8 Andy Shevchenko 2016-01-21 15:43:26 UTC
So, you have managed to attach binary, but forgot a text file (have no idea what is about, only looking to what you post here) ?
Comment 9 Leif Liddy 2016-01-21 16:34:01 UTC
The exact steps to get the wireless interface working are:

lynx -dump -dont_wrap_pre http://www.spinics.net/lists/linux-wireless/msg144980.html > bcm4350_firmware.txt

git apply --exclude=WHENCE bcm4350_firmware.txt

*this produces the file:
brcm/brcmfmac4350c2-pcie.bin

mv brcm/brcmfmac4350c2-pcie.bin /lib/firmware/brcm/brcmfmac4350-pcie.bin

Although brcmfmac attempts to load the nvram file "brcm/brcmfmac4350-pcie.txt", it's not needed apparently --the wireless works fine without it.
Comment 10 Dmitry 2016-01-22 07:57:47 UTC
I use wifi with firmware from the mail:

http://article.gmane.org/gmane.linux.kernel.wireless.general/146956/match=add+firmware+bcm4350+rev+5

WiFi works fine (including 5GHz networks)
Comment 11 Leif Liddy 2016-01-23 18:15:53 UTC
Created attachment 201111 [details]
OSX - IORegistry contents

I've attached a copy of the IORegistry contents from OSX
that shows the "Apple Internal Keyboard / Trackpad" are connected via the SPI bus. 

Windows also uses SPI drivers to access these devices {AppleSPIDevice, AppleSPIKeyboard, AppleSPITrackpad}


Maybe we could start with getting the SPI controller working by editing:
./drivers/spi/spi-pxa2xx-pci.c

I don't know much about SPI and am not sure what edits need to be made to get the SPI controller working properly. 

**I did get the DMA controller working --by editing 
./drivers/dma/dw/pci.c 
+ { PCI_VDEVICE(INTEL, 0x9ce0) },
Comment 12 Andy Shevchenko 2016-01-25 09:38:39 UTC
So, if you add just ID to the PCI driver, what happens?
Comment 13 Leif Liddy 2016-01-25 18:06:14 UTC
I've added this to line 250 of spi-pxa2xx-pci.c (kernel 4.5.0.rc1)
	{ PCI_VDEVICE(INTEL, 0x9ce6), PORT_BSW0 },

It looks like it's now binding to the controller....
**lshw output
 *-serial:1
             description: Serial bus controller
             product: Wildcat Point-LP Serial IO GSPI Controller #1
             vendor: Intel Corporation
             physical id: 15.4
             bus info: pci@0000:00:15.4
             version: 03
             width: 32 bits
             clock: 33MHz
             capabilities: pm bus_master cap_list
             configuration: driver=pxa2xx_spi_pci latency=0
             resources: irq:21 memory:c181a000-c181afff
**udev
P: /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0
E: DEVPATH=/devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0
E: SUBSYSTEM=spi_master

Is there a way that I can probe for SPI slave devices? I would imagine the step would be quite tricky. An SPI HID driver would likely need to be created to interface with the keyboard/trackpad. If anyone has ideas on how to proceed, let me know.
Comment 14 Andy Shevchenko 2016-01-27 19:06:51 UTC
So, reassign to Input devices since SPI seems responsive now.
Comment 15 Leif Liddy 2016-01-27 22:23:53 UTC
Created attachment 202141 [details]
ACPI DSDT table

attached ACPI dsdt.dsl file --shows ACPI SPI device information.
Comment 16 Leif Liddy 2016-01-31 20:16:16 UTC
Created attachment 202491 [details]
Patch adding 9ce6 device to spi-pxa2xx-pci.c

something's still not right with the way the SPI device is configured. 

In spi-pxa2xx.c we see the line:
static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
      	..
        { "INT33C1", LPSS_LPT_SSP },

INT33C1 is the acpi name for the SPI contoller on this macbook, and according to this it should correspond to the LPSS_LPT_SSP platform. 

I've wrote a patch for spi-pxa2xx-pci.c to get the 09ce6 device to use the values in the LPSS_LPT_SSP structure. There's still work to do, but this is a step in the right direction.
Comment 17 Leif Liddy 2016-02-04 03:54:05 UTC
It looks like the SPI master controller is represented by:
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00

And the slave device is represented by: 
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00/APP000D:00

./INT33C1:00/APP000D:00/path 	--contains:
\_SB_.PCI0.SPI1.SPIT

./INT33C1:00/APP000D:00/modalias    --contains:
acpi:APP000D:APPLE-SPI-TOPCASE:


Documentation/acpi/enumeration.txt	--contains the following:
##############################################################################
SPI serial bus support
~~~~~~~~~~~~~~~~~~~~~~
Slave devices behind SPI bus have SpiSerialBus resource attached to them.
This is extracted automatically by the SPI core and the slave devices are
enumerated once spi_register_master() is called by the bus driver.

Here is what the ACPI namespace for a SPI slave might look like:

	Device (EEP0)
	{
		Name (_ADR, 1)
		Name (_CID, Package() {
			"ATML0025",
			"AT25",
		})
		...
		Method (_CRS, 0, NotSerialized)
		{
			SPISerialBus(1, PolarityLow, FourWireMode, 8,
				ControllerInitiated, 1000000, ClockPolarityLow,
				ClockPhaseFirst, "\\_SB.PCI0.SPI1",)
		}
		...

The SPI device drivers only need to add ACPI IDs in a similar way than with
the platform device drivers. Below is an example where we add ACPI support
to at25 SPI eeprom driver (this is meant for the above ACPI snippet):

	#ifdef CONFIG_ACPI
	static const struct acpi_device_id at25_acpi_match[] = {
		{ "AT25", 0 },/acpi
		{ },
	};
	MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
	#endif

	static struct spi_driver at25_driver = {
		.driver = {
			...
			.acpi_match_table = ACPI_PTR(at25_acpi_match),
		},
	};
##############################################################################


The ACPI tables for the macbook8,1 looks similar:
*******************************************************************************
 Scope (\_SB.PCI0.SPI1)
     {
         Device (SPIT)
        {
             Name (_HID, EisaId ("APP000D"))  // _HID: Hardware ID
             Name (_CID, "apple-spi-topcase")  // _CID: Compatible ID
             ....
                  
             Method (_CRS, 0, Serialized)  // _CRS: Current Resource Settings
             {
                 Name (UBUF, ResourceTemplate ()
                 {
                     SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
                         ControllerInitiated, 0x007A1200, ClockPolarityLow,
                         ClockPhaseFirst, "\\_SB.PCI0.SPI1",
                         0x00, ResourceConsumer, ,
                         }
*******************************************************************************

So my question is would a device driver only need to reference APP000D as the device?
Comment 18 Leif Liddy 2016-02-04 03:57:03 UTC
This guy's running linux on an (unknown) macbook platform
https://bbs.archlinux.org/viewtopic.php?id=194264

His /proc/acpi/wakeup --shows the following 
SPIT	  S3	*disabled  platform:APP000D:00

My macbook8,1 shows:

Device	S-state	  Status   Sysfs node
PEG0	  S3	*disabled
EC	  S4	*disabled  platform:PNP0C09:00
HDEF	  S3	*disabled  pci:0000:00:1b.0
RP01	  S3	*disabled  pci:0000:00:1c.0
RP03	  S3	*disabled  pci:0000:00:1c.2
ARPT	  S4	*enabled   pci:0000:01:00.0
RP04	  S3	*disabled  pci:0000:00:1c.3
RP05	  S3	*disabled  pci:0000:00:1c.4
SPIT	  S3	*disabled
XHC1	  S3	*enabled   pci:0000:00:14.0
ADP1	  S4	*disabled  platform:ACPI0003:00
LID0	  S4	*enabled   platform:PNP0C0D:00


--shouldn't the SPIT device be associated with the APP000D:00 sysfs node?
Comment 19 Leif Liddy 2016-02-16 19:37:33 UTC
Created attachment 203771 [details]
Patch: adding 9ce6 device to spi-pxa2xx-pci.c

Andrew, 

Can you please review this patch and send it up if it's good? It'll be much easier for someone to create a protocol driver when the SPI master controller driver is working. 

modprobe spi_pxa2xx_pci     --dmesg log

[  232.335262] dma dma0chan0: dwc_alloc_chan_resources: allocated 64 descriptors
[  232.335270] dmaengine: __dma_request_channel: success (dma0chan0)
[  232.335275] dmaengine: private_candidate: dma0chan0 busy
[  232.335377] dma dma0chan1: dwc_alloc_chan_resources: allocated 64 descriptors
[  232.335379] dmaengine: __dma_request_channel: success (dma0chan1)
[  232.335959] pxa2xx-spi pxa2xx-spi.0: registered master spi0

there might be an issue with the TX channel dma0chan0, as it always listed as "busy". I'm not sure if that's normal of not. I don't know to test this driver as there's no protocol driver to communicate with the slave device(s). From what I gather from the ACPI tables and OSX IORegistry contents, the keyboard and mouse are viewed as a single device --and are connected to to a single SPI slave chip. 

Let me know if there's any additional information you need to confirm this driver is configured properly.
Comment 20 Andy Shevchenko 2016-02-16 20:00:17 UTC
(In reply to Leif Liddy from comment #19)
> Created attachment 203771 [details]
> Patch: adding 9ce6 device to spi-pxa2xx-pci.c
> 
> Andrew, 
> 
> Can you please review this patch and send it up if it's good?

No, it's wrong.

1. It's nothing to do with LPT, it must be BYT.

+                .type = LPSS_LPT_SSP,

2. The request lines are wrong.

Name (DBUF, ResourceTemplate ()
                {
                    FixedDMA (0x0010, 0x0006, Width32bit, )
                    FixedDMA (0x0011, 0x0007, Width32bit, )
                })

More correct patch should take parameters from ACPI, it would be also nice to check if they have CSRT table.

> It'll be much
> easier for someone to create a protocol driver when the SPI master
> controller driver is working. 
> 
> modprobe spi_pxa2xx_pci     --dmesg log
> 
> [  232.335262] dma dma0chan0: dwc_alloc_chan_resources: allocated 64
> descriptors
> [  232.335270] dmaengine: __dma_request_channel: success (dma0chan0)
> [  232.335275] dmaengine: private_candidate: dma0chan0 busy
> [  232.335377] dma dma0chan1: dwc_alloc_chan_resources: allocated 64
> descriptors
> [  232.335379] dmaengine: __dma_request_channel: success (dma0chan1)
> [  232.335959] pxa2xx-spi pxa2xx-spi.0: registered master spi0
> 
> there might be an issue with the TX channel dma0chan0, as it always listed
> as "busy".

You didn't get the message. It is a loop until channel will be found or no channels left to check. Both directions got channels (see success message).

> I'm not sure if that's normal of not. I don't know to test this
> driver as there's no protocol driver to communicate with the slave
> device(s). From what I gather from the ACPI tables and OSX IORegistry
> contents, the keyboard and mouse are viewed as a single device --and are
> connected to to a single SPI slave chip. 
> 
> Let me know if there's any additional information you need to confirm this
> driver is configured properly.

CSRT
Comment 21 Leif Liddy 2016-02-16 22:06:49 UTC
The reason I used LPSS_LPT_SSP was because spi-pxa2xx.c contained this:

static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
...
{ "INT33C1", LPSS_LPT_SSP },

**INT33C1 is the ACPI name for the SPI controller on this macbook. 

Ok, so I've added this line to spi-pxa2xx-pci.c    (I didn't touch spi-pxa2xx.c)

static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
        ....
+       { PCI_VDEVICE(INTEL, 0x9ce6), PORT_BYT },

When the spi_pxa2xx_pci module is loaded, the dmesg log is exactly the same as in my previous comment. 

There is no CSRT table under /sys/firmware/acpi/tables
Here are the tables I do have:
APIC  DSDT  FACP   FACS2  MCFG  SSDT1  SSDT3  SSDT5  SSDT7
DMAR  ECDT  FACS1  HPET   SBST  SSDT2  SSDT4  SSDT6

..and two dynamic tables: SSDT8  SSDT9
Comment 22 Andy Shevchenko 2016-02-17 08:43:43 UTC
(In reply to Leif Liddy from comment #21)
> The reason I used LPSS_LPT_SSP was because spi-pxa2xx.c contained this:
> 
> static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
> ...
> { "INT33C1", LPSS_LPT_SSP },

Ah, sorry, seems you are right. This actually defines private register space offset.

> There is no CSRT table under /sys/firmware/acpi/tables
> Here are the tables I do have:
> APIC  DSDT  FACP   FACS2  MCFG  SSDT1  SSDT3  SSDT5  SSDT7
> DMAR  ECDT  FACS1  HPET   SBST  SSDT2  SSDT4  SSDT6
> 
> ..and two dynamic tables: SSDT8  SSDT9

So, I suppose you may try those request IDs you put in your patch.
Comment 23 Leif Liddy 2016-02-17 17:16:27 UTC
Nice!!! Then I'll submit it soon. Just need to go over a few tutorials on how to submit a kernel patch.
Comment 24 Leif Liddy 2016-02-19 22:26:44 UTC
Created attachment 203941 [details]
Patch: adding 9ce6 device to spi-pxa2xx-pci.c

This is the final version of the patch submitted to the maintainers email list. 

*******related udev info***********

P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00
E: DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00
E: ID_VENDOR_FROM_DATABASE=Interphase Corporation
E: MODALIAS=acpi:INT33C1:
E: SUBSYSTEM=acpi
E: USEC_INITIALIZED=13525763

P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00/APP000D:00
E: DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT33C1:00/APP000D:00
E: ID_VENDOR_FROM_DATABASE=Apple Computer Inc
E: MODALIAS=acpi:APP000D:APPLE-SPI-TOPCASE:
E: SUBSYSTEM=acpi
E: USEC_INITIALIZED=13574842

P: /devices/pci0000:00/0000:00:15.4
E: DEVPATH=/devices/pci0000:00/0000:00:15.4
E: DRIVER=pxa2xx_spi_pci
E: ID_MODEL_FROM_DATABASE=Wildcat Point-LP Serial IO GSPI Controller
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d00009CE6sv00008086sd00009CE6bc0Csc80i00
E: PCI_CLASS=C8000
E: PCI_ID=8086:9CE6
E: PCI_SLOT_NAME=0000:00:15.4
E: PCI_SUBSYS_ID=8086:9CE6
E: SUBSYSTEM=pci
E: USEC_INITIALIZED=13434299

P: /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0
E: DEVPATH=/devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0
E: DRIVER=pxa2xx-spi
E: MODALIAS=platform:pxa2xx-spi
E: SUBSYSTEM=platform

P: /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0
E: DEVPATH=/devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0
E: SUBSYSTEM=spi_master
Comment 25 Leif Liddy 2016-02-25 02:23:23 UTC
Apparently spi_pxa2xx_platform should by able to setup the SPI controller with APCI ID INT33C1 without the need for spi_pxa2xx_pci, but fails for some reason and "pxa2xx_spi_probe" never gets called. 

Setting up the controller with spi_pxa2xx_pci presents it's own set of challenges, as noted by this post:

https://www.mail-archive.com/linux-yocto@yoctoproject.org/msg04044.html

"Slave devices were not enumerated by ACPI data because the ACPI handle
for the spi-pxa2xx controller was NULL if it was itself enumerated by
PCI.

Upstream-status: Inappropriate, real fix forthcoming"

I applied the patch mentioned in the post to spi_pxa2xx_pci
+       pi.fwnode = dev->dev.fwnode;

Now when I modprobe spi_pxa2xx_pci, I see this:
pxa2xx-spi pxa2xx-spi.0: found DMA channel "tx" at index 0
dma dma0chan0: dwc_alloc_chan_resources: allocated 64 descriptors
dmaengine: __dma_request_channel: success (dma0chan0)
pxa2xx-spi pxa2xx-spi.0: found DMA channel "rx" at index 1
dmaengine: private_candidate: dma0chan0 busy
dma dma0chan1: dwc_alloc_chan_resources: allocated 64 descriptors
dmaengine: __dma_request_channel: success (dma0chan1)


The lines containing "tx" at index 0 and "rx" at index 1 are new, but I'm not sure how to use them in a driver without the slave device enumerating.

What's odd is is that "acpi_walk_namespace" in spi.c (used to enumerate slave devices) returns a value, which means it must have found something. 

In acpi_lpss.c, if I comment out the line:
{ "INT33C1", LPSS_ADDR(lpt_dev_desc) }

UDEV will show this:
P: /devices/pci0000:00/0000:00:15.4/APP000D:00
E: DEVPATH=/devices/pci0000:00/0000:00:15.4/APP000D:00
E: ID_VENDOR_FROM_DATABASE=Apple Computer Inc
E: MODALIAS=acpi:APP000D:APPLE-SPI-TOPCASE:
E: SUBSYSTEM=platform
E: USEC_INITIALIZED=13710574

/proc/acpi/wakeup  --shows this
SPIT	  S3	*disabled   platform:APP000D:00

**With this setup, spi.c throws "failed to enumerate SPI slaves"
And this device never gets registered as an SPI slave.

This whole issue is related to ACPI. If anyone has ANY idea on how to setup APP000D as an SPI slave device, please let me know.
Comment 26 Leif Liddy 2016-02-29 00:03:51 UTC
I'm trying to sort out why spi-pxx2xx.c is not performing a platform_driver_register() for the INT33C1 controller. 

(I believe) in order for spi-pxx2xx.c to register a platform_driver, a platform device be must first created beforehand. In this case, that's the job of acpi_lpss.c 

In acpi_lpss.c: acpi_lpss_create_device() calls acpi_dev_get_resources() --which returns 0 (ret value). (it should return a positive number)

resource.c: acpi_dev_get_resources() checks to ensure there is a __CRS Method associated with the acpi device handle, then calls:

status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, acpi_dev_process_resource, &c);

&c holds the int value of the number of resources found, but it never gets incremented. 

I wonder if someone could take a look at the DSDT tables...

Device (SDMA)
     {
        Name (_ADR, 0x00150000)  // _ADR: Address
        Name (_UID, 0x01)  // _UID: Unique ID
        Name (RBUF, ResourceTemplate ()
        ...
        Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
        {
             Return (RBUF) /* \_SB_.PCI0.SDMA.RBUF */
        }
		...
Device (SPI1)
    {
       Name (_ADR, 0x00150004)  // _ADR: Address
       Name (_CID, "INT33C1" /* Intel Serial I/O SPI Host Controller */) 
		..
       Name (WBUF, ResourceTemplate ()
       {
       })
       Name (DBUF, ResourceTemplate ()
       {
            FixedDMA (0x0010, 0x0006, Width32bit, )
            FixedDMA (0x0011, 0x0007, Width32bit, )
       })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          If (!OSDW ())
          {
              Return (WBUF) /* \_SB_.PCI0.SPI1.WBUF */
          }

              Return (ConcatenateResTemplate (RBUF, DBUF))
          }
     }
	    ......

If not sure how accurately acpica follows the logic of these tables. According this, if the system is not running OSX (_OSI vendor string "OSDW" not found) then return WBUF --which is nothing.

Another potential issue could be that since the DMA controller is not a platform device, then perhaps its _CRS methods wouldn't be discovered by acpica (just a guess, still learning....)
Comment 27 Andy Shevchenko 2016-02-29 08:36:46 UTC
acpi_lpss.c has nothing to do with PCI enumerated devices. Since you have entire LPSS enumerated through PCI you have to cope this and (customarily) update each.
Do you have ACPI handle set for this device? In any case you may access methods directly, though it will look a bit hackish (in some cases).
Comment 28 Leif Liddy 2016-02-29 16:08:38 UTC
Yes, there is an ACPI handle for INT33C1. I know the SPI controller is PCI enumerated, but I think we'd have a better chance of enumerating the SPI slave device if we register the the controller as a platform device/driver. I could use some advice on specific things I could do at this point.  
I don't mind how hacky things get --it helps with the learning process 

The ACPI handle for INT33C1 returns the same address with every system boot. How can I use this to access methods directly?
Comment 29 Leif Liddy 2016-03-01 23:54:36 UTC
After applying the patch in comment #25, all acpi_handle information gets passed properly. This patch won't make it into the kernel, the real fix involves passing the ACPI handle to the platform device --which will likely be forthcoming. For our purposes the comment #25 patch accomplishes the same thing.

With that patch applied, we can properly diagnose why the slave device is not enumerating. 

I added a few printk statments to spi.c and resource.c (begin with xxx) 
It looks like the root cause of the issue is that the
"ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS" check is failing.

modprobe pxa2xx-spi-pci

pxa2xx-spi pxa2xx-spi.0: found DMA channel "tx" at index 0
xxx resource.c acpi_dev_get_resources acpi_name=INT33C1:00 returns c.count 0...
dma dma0chan0: dwc_alloc_chan_resources: allocated 64 descriptors
dmaengine: __dma_request_channel: success (dma0chan0)
pxa2xx-spi pxa2xx-spi.0: found DMA channel "rx" at index 1
xxx resource.c acpi_dev_get_resources acpi_name=INT33C1:00 returns c.count 0...
dmaengine: private_candidate: dma0chan0 busy
dma dma0chan1: dwc_alloc_chan_resources: allocated 64 descriptors
dmaengine: __dma_request_channel: success (dma0chan1)
pxa2xx-spi pxa2xx-spi.0: registered master spi0
xxx spi.c acpi_register_spi_devices acpi_handle is ffff8802650bdcd0 (INT33C1:00)
xxx spi.c acpi_spi_add_device() start
xxx spi.c *spi_alloc_device() start
xxx spi.c acpi_spi_add_device acpi_name=APP000D:00
xxx spi.c acpi_spi_add_resource() start
xxx spi.c acpi_spi_add_resource spi->irq = -1
xxx spi.c failed check: ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS
xxx spi.c acpi_spi_add_resource :else if (spi->irq < 0)
xxx spi.c acpi_spi_add_resource return 1
xxx resource.c acpi_dev_get_resources acpi_name=APP000D:00 returns c.count 0...
xxx spi.c acpi_spi_add_device ret returns 0
xxx spi.c acpi_spi_add_device spi->max_speed_hz is 0
xxx spi.c acpi_spi_add_device (ret < 0 || !spi->max_speed_hz) --->
spi_dev_put(spi) --> return AE_OK


I assume it's looking for SpiSerialBus in the _CRS method,  not sure
why it can't find it. I wonder if there's a way to just manually
configure the slave device.


 Device (SPIT)
   {
     Name (_HID, EisaId ("APP000D"))  // _HID: Hardware ID
     .....

    Method (_CRS, 0, Serialized)  // _CRS: Current Resource Settings
    {
        Name (UBUF, ResourceTemplate ()
        {
            SpiSerialBus (0x0000, PolarityLow, FourWireMode, 0x08,
                ControllerInitiated, 0x007A1200, ClockPolarityLow,
                ClockPhaseFirst, "\\_SB.PCI0.SPI1",
                0x00, ResourceConsumer, ,
                )
            Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
            {
                0x0000001E,
            }
        })
        Name (ABUF, ResourceTemplate ()
        {
        })
        If (!OSDW ())
        {
            Return (UBUF) /* \_SB_.PCI0.SPI1.SPIT._CRS.UBUF */
        }

       Return (ABUF) /* \_SB_.PCI0.SPI1.SPIT._CRS.ABUF */
   }
Comment 30 Leif Liddy 2016-03-02 03:08:56 UTC
I finally got the SPI slave enumerated....by modifying the DSDT table

P: /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0/spi-APP000D:00
E: DEVPATH=/devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0/spi-APP000D:00
E: ID_VENDOR_FROM_DATABASE=Apple Computer Inc
E: MODALIAS=acpi:APP000D:APPLE-SPI-TOPCASE:
E: SUBSYSTEM=spi
E: USEC_INITIALIZED=27944872

/proc/acpi/wakeup 
Device	S-state	  Status   Sysfs node
SPIT	  S3	*disabled   spi:spi-APP000D:00


I'll post more tomorrow, need to evaluate the changes I made --but I think the change that did it was changing this:

Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
{
    If (!OSDW ())
    {
        Return (WBUF) /* \_SB_.PCI0.SPI1.WBUF */
    }

    Return (ConcatenateResTemplate (RBUF, DBUF))
}

to:

Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
{
      Return (ConcatenateResTemplate (RBUF, DBUF))
}
Comment 31 Leif Liddy 2016-03-02 16:15:13 UTC
the change to the DSDT table that allowed the SPI slave to be enumerated was:

If (!OSDW ())
 {
     Return (UBUF) /* \_SB_.PCI0.SPI1.SPIT._CRS.UBUF */
 }
Return (ABUF) /* \_SB_.PCI0.SPI1.SPIT._CRS.ABUF */
}

Just change !OSDW to OSDW  (or equivalent function) 

the default behavior it seems is for Linux to identify itself as OSX. For this method that behavior is undesirable as it causes UBUF to not be returned.
Comment 32 Leif Liddy 2016-03-05 03:12:54 UTC
I've modified spidev and I'm trying to trying to perform a loopback test, but 
it looks like there's something wrong with the IRQ configuration

./spidev_test -D /dev/spidev0.0 
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)

Message from syslogd@mac at Mar  5 03:58:00 ...
 kernel:Disabling IRQ #21

---IRQ table------
0: IR-IO-APIC 2-edge timer  
8: IR-IO-APIC 8-edge rtc0  
9: IR-IO-APIC 9-fasteoi acpi  
16: IR-IO-APIC 16-fasteoi   
18: IR-IO-APIC 18-fasteoi i801_smbus  
20: IR-IO-APIC 20-fasteoi dw_dmac  
21: IR-IO-APIC 21-fasteoi pxa2xx-spi.0  
40: DMAR-MSI 0-edge dmar0  
41: DMAR-MSI 1-edge dmar1  
42: IR-PCI-MSI 327680-edge xhci_hcd  
43: IR-PCI-MSI 1572864-edge nvme0q0, nvme0q1 
44: IR-PCI-MSI 32768-edge i915  
45: IR-PCI-MSI 360448-edge mei_me  
46: IR-PCI-MSI 49152-edge snd_hda_intel:card0  
47: IR-PCI-MSI 442368-edge snd_hda_intel:card1  
48: IR-PCI-MSI 524288-edge brcmf_pcie_intr 


xxx spi.c acpi_spi_add_resource :spi->irq < 0
xxx spi.c acpi_spi_add_resource :if (acpi_dev_resource_interrupt(ares, 0, &r))
spi.c acpi_spi_add_resource spi->irq = r.start --is equal to 30
spi.c acpi_spi_add_resource --start
xxx spi.c spi->irq = 30
.....
spidev spi-APP000D:00: setup mode 0, 8 bits/w, 8000000 Hz max --> 0
spidev spi-APP000D:00: 8 bits per word
xxx spi.c spi_setup --start
spidev spi-APP000D:00: setup mode 0, 8 bits/w, 500000 Hz max --> 0
spi.c __spi_validate --start
spi.c __spi_validate message->status = -EINPROGRESS;
spi-pxa2xx-dma.c pxa2xx_spi_dma_prepare() --start
spi-pxa2xx-dma.c pxa2xx_spi_dma_start() --start
irq 21: nobody cared (try booting with the "irqpoll" option)
Comment 33 Leif Liddy 2016-03-05 03:23:35 UTC
the spi slave is deriving it's IRQ value of 30 from ACPI. I'm not sure what it should be set to. The SPI controller's IRQ value is 21. 

The problem starts right after pxa2xx_spi_dma_start() is called.

void pxa2xx_spi_dma_start(struct driver_data *drv_data)
       dma_async_issue_pending(drv_data->rx_chan);
       dma_async_issue_pending(drv_data->tx_chan);

       atomic_set(&drv_data->dma_running, 1);
}
Comment 34 Leif Liddy 2016-03-06 20:49:43 UTC
Created attachment 207871 [details]
DMA - IRQ testing

I think that issue is the DMA controller is being assigned an IRQ of 20. 
I believe it should be assigned an IRQ of 21 --it would then share the IRQ with 
pxa2xx-spi.0


the DSDT tables shows the DMA controller and SPI1 as having the same IRQ of 21. 

Device (SDMA) 
and 
Device (SPI1)

Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
{
     0x00000015,
}

/proc/interrupts 
20:	dw_dmac
21: 	pxa2xx-spi.0

I performed a series of dma tests and have attached the results. 
Andy, could you please review the attachment?
Comment 35 Andy Shevchenko 2016-03-07 08:58:15 UTC
(In reply to Leif Liddy from comment #34)
> I performed a series of dma tests and have attached the results. 
> Andy, could you please review the attachment?

Indeed, this is interesting result. I have no idea how they could miss that? How does it work in OS X?

Btw, instead of custom printk:s I recommend to use ftracer (CONFIG_FUNCTIONAL_TRACER=y). It might require an additional instrumentation / trace points, but you may upstream that. Actually it would be nice if someone can instrument DMAengine API.
Comment 36 Leif Liddy 2016-03-14 20:56:27 UTC
I'm not a big OSX user, I know hardly anything about how it operates. A cursory google search didn't turn up much.

What I do know is that the DSDT table shows the following controllers are all listed as having an IRQ of 21

DMA, I2C1, SPI, URT0


the IRQ of 20 for the DMA controller gets assigned after drivers/dma/dw/pci.c calls: 
ret = pcim_enable_device(pdev);


These are some IRQ-related messages in the log file:

DMAR-IR: x2apic is disabled because BIOS sets x2apic opt out bit.
DMAR-IR: Use 'intremap=no_x2apic_optout' to override the BIOS setting.
DMAR-IR: Enabled IRQ remapping in xapic mode
kernel: x2apic: IRQ remapping doesn't support X2APIC mode
kernel: PCI: Using ACPI for IRQ routing
Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled


I've been playing around with trace-cmd over the last few days. It's really useful tool

It looks like I just need to create the header file.
include/trace/events/dmaengine.h

define the macros, and then create the tracepoints in dmaengine.c

I'm still just a beginner when it comes to the kernel. I just need to a bit of time to work out how to define the macros. Thankfully, there's some decent documentation online.
Comment 37 Andreas Jonsson 2016-06-19 20:45:13 UTC
https://bugzilla.kernel.org/show_bug.cgi?id=99891

Let us know if we can help with testing.
Comment 38 Wes 2016-06-20 00:05:12 UTC
Would love to see these old 'new' bugs changed to 'confirmed' and some signs of progress.  Should we raise a bounty?
Comment 39 scramble 2016-06-20 00:23:48 UTC
Let me know if I can help with any dumps.
Comment 40 Jon 2016-06-23 08:53:53 UTC
I got one of these 12-inch macbooks -- model A1534 -- the day they were released and am still waiting for a keyboard driver for Linux.

Normally I run Gentoo GNU/Linux and the lack of a keyboard driver has prevented me from using this 12-inch macbook as much as I originally intended to.

Let me know if there is anything I can do to help with testing.


>> Should we raise a bounty?

I will happily pledge $200 USD out of pocket for working keyboard and trackpad drivers for the 12-inch macbooks, specifically the A1534 model.
Comment 41 noobermin 2016-07-02 21:37:33 UTC
Reposting this[0] here. There exists a bounty for this currently at 495 usd

[0] https://www.bountysource.com/issues/35422234-macbook8-1-12-inch-early-2015-keyboard-and-trackpad-don-t-work
Comment 42 kernel.wnkfo 2016-07-06 18:26:16 UTC
I guess we will have to wait until the new Macbook Pros will be released, they might be all-on-one-board laptops too and might run into the same issues, then more people will be motivated to fix this.
Comment 43 noobermin 2016-07-06 21:29:25 UTC
(In reply to janoschpelzer from comment #42)
> I guess we will have to wait until the new Macbook Pros will be released,
> they might be all-on-one-board laptops too and might run into the same
> issues, then more people will be motivated to fix this.

I really don't think there is "no motivation"...more like the two or three people who were working on it and were in the know disappeared. For example, above seems to suggest Leif Liddy has made a lot of progress, he has just disappeared. Perhaps that could be seen as a lack of motivation, no idea.
Comment 44 Federico Lorenzi 2016-07-13 19:56:43 UTC
(In reply to noobermin from comment #43)
> I really don't think there is "no motivation"...more like the two or three
> people who were working on it and were in the know disappeared. For example,
> above seems to suggest Leif Liddy has made a lot of progress, he has just
> disappeared. Perhaps that could be seen as a lack of motivation, no idea.

I recently got a 2016 12" MacBook, and have just got it to the point where
the underlying SPI slave can be exposed under Linux. Things are slightly 
different than the 2015 model that Leif was working on.

After many red herrings, it seems that you have to boot with the 
intremap=nosid - everything that I found mentioned noapic, but the
APIC is needed to have a working SPI controller. Without it you get a
bogus interrupt. I'm not entirely sure what the implications of this option
are, however.

Once that's done, the intel-lpss module takes care of setting everything else
up. You can bind an spidev to the controller by slightly tweaking the module
at [1], setting the bus to 2, and the clock speed to 8000000. Then:

./spidev_test  -D /dev/spidev2.0 -v -s 8000000
spi mode: 0x0
bits per word: 8
max speed: 8000000 Hz (8000 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF ...
RX | 20 00 00 00 00 00 0F 00 10 E0 00 00 00 00 05 00 E0 10 00 00 00 6C 78 ...

Allows you to communicate with the SPI keyboard / touchpad device.

Unfortunately, I've already tried just 'reading' continuously from this device
and seeing if any keypresses or mouse events cause any change, but it doesn't
seem so. There are some bytes later on that do change, but they seem to do so
at random.

Decompiling the AppleHSSPIHIDDriver kext from Mac OS did yield a few
interesting bits, but I'm not nearly familiar enough with reverse engineering
to make too much sense of it. You probably have to read data from the SPI
device with a certain packet, and/or use command packets to enable interrupts
from the slave device (so you can know when to read properly)

[1] https://raw.githubusercontent.com/MinnowBoard/minnow-max-extras/master/modules/low-speed-spidev/low-speed-spidev.c
Comment 45 Wes 2016-07-14 03:37:10 UTC
(In reply to Federico Lorenzi from comment #44)
> I recently got a 2016 12" MacBook, and have just got it to the point where
> the underlying SPI slave can be exposed under Linux. Things are slightly 
> different than the 2015 model that Leif was working on.
> 
> After many red herrings, it seems that you have to boot with the 
> intremap=nosid 
> 
> You can bind an spidev to the controller by slightly tweaking the module
> at [1], setting the bus to 2, and the clock speed to 8000000.
> 
> Unfortunately, I've already tried just 'reading' continuously from this
> device
> and seeing if any keypresses or mouse events cause any change, but it doesn't
> seem so. There are some bytes later on that do change, but they seem to do so
> at random.

I have a 2015 12" macbook here, I'll try to replicate this tonight and see if I get any different results, thanks
Comment 46 Wes 2016-07-14 10:40:10 UTC
@Federico Lorenzi,

I tested this on the 2015 12" macbook using a 4.6.4 kernel (which includes Leif Liddy's patches for spi-pxa2xx-pci) but I don't get an spi bus 2.  With or without loading intel-lpss I only ever have 1 spi bus at 0x0 and no data at all running spidev_test with spidev.ko + your provided (with bus at 0) low-speed-spidev.ko

When I try to load it with bus at any other value it says no such device.  Do I need a newer intel_lpss.ko than what ships with 4.6.4?

Cheers,
Wes
Comment 47 Federico Lorenzi 2016-07-14 22:09:41 UTC
(In reply to Wes from comment #46)
> @Federico Lorenzi,
> 
> I tested this on the 2015 12" macbook using a 4.6.4 kernel (which includes
> Leif Liddy's patches for spi-pxa2xx-pci) but I don't get an spi bus 2.  With
> or without loading intel-lpss I only ever have 1 spi bus at 0x0 and no data
> at all running spidev_test with spidev.ko + your provided (with bus at 0)
> low-speed-spidev.ko
> 
> When I try to load it with bus at any other value it says no such device. 
> Do I need a newer intel_lpss.ko than what ships with 4.6.4?
> 
> Cheers,
> Wes

Unfortunately I don't know enough about the 2015 model to tell what could be causing that. I'm sure I recall a post from Leif Liddy that included him running spidev and getting output, but I can't seem to find it now. I believe there were some issues caused by the fact that the DMA controller wasn't built in (whereas on the 2016 model it uses iDMA). For reference, I'm also on 4.6.4.

On a much more positive note, I've figured out how to get data out of the slave device! You have to read exactly 256 bytes at a time. I haven't yet decoded the response fully, but now when pressing keys / moving a finger on the touchpad there are clear SPI responses that I can sort of decode well enough to say that an "a" was pressed or the touchpad is clicked.
Comment 48 Wes 2016-07-14 22:17:08 UTC
Leif Liddy, if you're still around, could you please comment on the DMA issue?  Were you able to get the SPI bus visible at all?

Cheers,
Wes
Comment 49 Leif Liddy 2016-07-14 23:36:18 UTC
Sorry, I’ve been on vacation for a while. I’ve since sold my macbook, but will consider getting another one now that there’s more interest in solving this issue. I’m not really sure where things are now, but regarding the DMA issue (see DMA – IRQ testing attachment TEST 3). I needed to modify drivers/dma/dw/pci.c to assign the DMA controller irq value to 21 (which is what is listed in the ACPI table) for it to work. The DMA controller was being assigned an irq value of 20 for some reason. TEST 4 is where I ran the spidev_test, but I was never able to communicate with the device.

I remember there was something to do with the ACPI methods SIEN and SIST. I believe SIEN needed to be called in order to enable the SPI device, and SIST just returned the status (on|off). I had modified spidev_test to call SIEN to enable the device. After that, I did get some data returned from spidev_test, but was mostly zero’s. I no longer have the modified version of spidev_test, I just have this from my notes (from an early version)

static int spi_hid_probe(struct spi_device *spi)
{
        struct acpi_object_list input;
        union acpi_object param[1];
        acpi_status status;
        param[0].type = ACPI_TYPE_INTEGER;
        param[0].integer.value = 0x01;
        input.count = 1;
        input.pointer = param;

        status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "SIEN", &input, NULL);
        if (ACPI_FAILURE(status))
                printk("xxx mb81_spi_probe --ACPI_FAILURE\n");

        return 0;
}


static const struct acpi_device_id spi_hid_acpi_match[] = {
        { "APP000D", 0 },
        { },
};

The result from spidev_test was this:
./spidev_test -D /dev/spidev0.0  -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF F0 0D  | ......@....�..................�.
RX | 20 D0 00 00 00 00 04 00 A0 80 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00  | .�......��....................
Comment 50 Wes 2016-07-14 23:43:30 UTC
   Thanks heaps, I'll see what I can do with this.

   Cheers,
   Wes
Comment 51 Federico Lorenzi 2016-07-16 20:52:58 UTC
@Leif Liddy:
Interesting - on mine it just works out the box without requiring SIEN to be enabled. I did toy around with it, and SIEN does allow me to disable and then reenable successfully.

I've started writing a basic SPI protocol driver for the SPI device (requires the DSDT modification / ACPI to probe successfully). I've also extracted the commands required to switch the touchpad into proper multitouch mode, and those work.

I'm having trouble getting the interrupt to work, however. I've registered the IRQ handler for the slave in my driver, and it shows up correctly under /proc/interrupts:

 14:          0          0          0          0  IR-IO-APIC  14-fasteoi   applespi

but as you can see, no interrupts occur. I'm wondering if perhaps interrupts only occur when the device is in a low power state, otherwise it gets continuously polled. I actually have all of the commands the Windows driver sends to the SPI module, but none of those seem to do the trick on getting interrupts to come through.

I could just be missing something obvious though, will do some more digging.

As an aside, for anyone interested in helping reverse engineer things:
It's possible to get Windows to dump everything it sends on what it calls SPB - basically SPI & I2C. Open the Event Viewer and enable View -> Show Analytic and Debug Logs. Then head to Application and Services Logs -> Microsoft -> Windows -> SPB-ClassExtension. Right click on Analytic and enable it - all events will be logged. Disable it when done, and look for the 1023 events, and view the details tab - they'll give you the full buffer contents. Other events will let you know things like the direction of the transfer, etc.
Comment 52 Federico Lorenzi 2016-07-30 21:05:35 UTC
Still no progress on interrupts unfortunately, but I've managed to get a work in progress driver up and running at [1].

The keyboard works, and so do basic touchpad facilities. However, it drains power like crazy, being a polled input device running once every ms. The code is also slight mess, but it does work!

Good news is that the touchpad protocol does seem to line up with the BCM5974 driver, so that was simple enough. It's just a question of getting interrupts working to have the basis for a properly functioning device driver.

[1] https://github.com/cb22/macbook12-spi-driver
Comment 53 Leif Liddy 2016-07-31 01:02:11 UTC
Great work on that driver Federico!!! Reading through the comments, it seems like the main difference between the 2015 and 2016 models is the SPI controller driver being used. The 2015 model uses the spi-pxa2xx driver, while the 2016 model uses the intel-lpss driver. Intel Lynxpoint support (and by extension Wildcat point) was added (at a later date) to the spi-pxa2xx driver because the hardware was mostly compliant  https://lwn.net/Articles/533556/
However, the intel-lpss driver was built from the ground up to support Intel Sunrisepoint MFD (spi,i2c,uart combo) devices. That's why it's been a bit more of a struggle getting the spi-pxa2xx driver working properly on the 2015 model, especially considering that Wildcat Point SPI hardware isn't really all that common.
Comment 54 lkml2819 2016-08-02 04:08:14 UTC
Great work!  

On Sat, Jul 30, 2016 at 09:05:35PM +0000, bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=108331
> 
> --- Comment #52 from Federico Lorenzi <florenzi+kernel@gmail.com> ---
> Still no progress on interrupts unfortunately, but I've managed to get a work
> in progress driver up and running at [1].
> 
> The keyboard works, and so do basic touchpad facilities. However, it drains
> power like crazy, being a polled input device running once every ms. The code
> is also slight mess, but it does work!

I can confirm that the keyboard is working on the 2016 12" MacBook model
with the Linux 4.7.0 kernel and the driver you provided.  `

> Good news is that the touchpad protocol does seem to line up with the
> BCM5974 driver, so that was simple enough. It's just a question of
> getting interrupts working to have the basis for a properly
> functioning device driver.

The trackpad responds to click events but not motion, i.e. the pointer
doesn't move.

I also have the 2015 12" MacBook and can probably find time to test on
that as well if needed.

Derrick
Comment 55 Federico Lorenzi 2016-08-02 15:37:41 UTC
(In reply to lkml2819 from comment #54)
> I can confirm that the keyboard is working on the 2016 12" MacBook model
> with the Linux 4.7.0 kernel and the driver you provided.  `
Good to hear! I actually had some trouble getting it to work on 4.7, but I think that was just due to the DSDT overriding not working properly for some reason.

> The trackpad responds to click events but not motion, i.e. the pointer
> doesn't move.
Hmm; strange. Are you using xf86-input-libinput? I've only tested it with that, and not evdev or synaptics. What happens if you run evtest /dev/input/<touchpad event device>?

> 
> I also have the 2015 12" MacBook and can probably find time to test on
> that as well if needed.
It seems like Leif did manage to get the SPI side of things sorted through quite a series of steps, but he no longer has one. It would be great if you could reproduce this. Once an APP000D device exists, the driver should bind to it automatically.
Comment 56 David Vasak 2016-08-02 15:58:13 UTC
Really great to see some progress on this! I also have a 2016 12" MacBook. Would it be helpful for me to test the patch too? Additionally, is there any way I could assist in the development of this? I've never really touched the kernel before though so I don't have much of a clue where to start looking.
Comment 57 Federico Lorenzi 2016-08-13 10:20:42 UTC
Created attachment 228521 [details]
MacBook9,1 DSDT
Comment 58 OddJob 2016-09-17 22:18:40 UTC
I also have a 2015 model running 4.6 and am happy to test if anyone has the steps to get the spi-pxa2xx driver working.
Comment 59 John Morton 2016-09-17 22:20:30 UTC
Likewise, I too have the 2015 model and am more than willing to assist test efforts with whatever might be required.
Comment 60 Denver 2016-09-27 09:40:19 UTC
Hi, looks like some amazing progress has gone on since I last looked here! Thanks to everyone for their work!

I have a macbook 2015 model, just installed Ubuntu 16.10 (wifi works out of the box!! - also usb hotswap is more reliable), recompiled kernel 4.7-rc7 with the modified DSDT, and can confirm the spi device now enumerates. 

When I load the keyboard module I get the following:

[  278.907319] applespi: loading out-of-tree module taints kernel.
[  278.907321] applespi: module license 'unspecified' taints kernel.
[  278.907341] applespi: module verification failed: signature and/or required key missing - tainting kernel
[  278.907370] applespi: Unknown symbol init_module (err 0)
[  278.907382] applespi: Unknown symbol cleanup_module (err 0)
[  298.943891] applespi: Unknown symbol init_module (err 0)
[  298.943905] applespi: Unknown symbol cleanup_module (err 0)
[  496.676910] input: Apple SPI Keyboard as /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0/spi-APP000D:00/input/input12
[  496.677189] input: Apple SPI Touchpad as /devices/pci0000:00/0000:00:15.4/pxa2xx-spi.0/spi_master/spi0/spi-APP000D:00/input/input13
[  497.287421] irq 21: nobody cared (try booting with the "irqpoll" option)
[  497.287425] CPU: 2 PID: 0 Comm: swapper/2 Tainted: P       A   OE   4.8.0-rc7-custom #2
[  497.287426] Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC, BIOS MB81.88Z.0164.B18.1608121416 08/12/2016
[  497.287427]  0000000000000086 7be37d526990816d ffffffff92b738d4 ffff902a640ef600
[  497.287429]  ffff902a640ef69c ffffffff928dc6d0 ffff902a640ef600 0000000000000000
[  497.287430]  ffffffff93571bc0 00000000000000a1 ffffffff928dca52 ffff902a640ef600
[  497.287432] Call Trace:
[  497.287433]  <IRQ>  [<ffffffff92b738d4>] ? dump_stack+0x5c/0x78
[  497.287439]  [<ffffffff928dc6d0>] ? __report_bad_irq+0x30/0xc0
[  497.287441]  [<ffffffff928dca52>] ? note_interrupt+0x232/0x270
[  497.287442]  [<ffffffff928d9d81>] ? handle_irq_event_percpu+0x51/0x70
[  497.287444]  [<ffffffff928d9dd6>] ? handle_irq_event+0x36/0x60
[  497.287444]  [<ffffffff928dd05a>] ? handle_fasteoi_irq+0x8a/0x140
[  497.287446]  [<ffffffff928305c6>] ? handle_irq+0x16/0x20
[  497.287448]  [<ffffffff92efe716>] ? do_IRQ+0x46/0xd0
[  497.287449]  [<ffffffff92efc842>] ? common_interrupt+0x82/0x82
[  497.287449]  <EOI>  [<ffffffff92d8f2cc>] ? poll_idle+0x3c/0x70
[  497.287452]  [<ffffffff92837055>] ? sched_clock+0x5/0x10
[  497.287454]  [<ffffffff92d8eb1f>] ? cpuidle_enter_state+0xef/0x320
[  497.287455]  [<ffffffff928c37f6>] ? cpu_startup_entry+0x2d6/0x410
[  497.287457]  [<ffffffff92851c4c>] ? start_secondary+0x16c/0x200
[  497.287457] handlers:
[  497.287461] [<ffffffffc0568370>] ssp_int [spi_pxa2xx_platform]
[  497.287462] Disabling IRQ #21
[  726.069607] INFO: task insmod:7916 blocked for more than 120 seconds.
[  726.069614]       Tainted: P       A   OE   4.8.0-rc7-custom #2
[  726.069616] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  726.069618] insmod          D ffff902a642dbfc0     0  7916   7915 0x00000000
[  726.069625]  ffff902a64dd2a80 ffff902a642dbfc0 ffff902a6ec58f40 ffff902a299d0000
[  726.069629]  ffff902a299cf9c8 ffff902a299cfa48 ffff902a642dbfc0 ffff902a5f33e320
[  726.069632]  ffffffffc080a0c0 ffffffff92ef7a91 ffff902a299cfa50 ffffffff92efaf80
[  726.069647] Call Trace:
[  726.069659]  [<ffffffff92ef7a91>] ? schedule+0x31/0x80
[  726.069663]  [<ffffffff92efaf80>] ? schedule_timeout+0x2d0/0x490
[  726.069668]  [<ffffffff928a8e64>] ? ttwu_do_wakeup+0x14/0x100
[  726.069671]  [<ffffffff928a9c63>] ? try_to_wake_up+0x53/0x3c0
[  726.069675]  [<ffffffff92ef84b1>] ? wait_for_completion+0xf1/0x130
[  726.069678]  [<ffffffff928aa060>] ? wake_up_q+0x70/0x70
[  726.069683]  [<ffffffff92d562cf>] ? __spi_sync+0x10f/0x220
[  726.069686]  [<ffffffff92d5640b>] ? spi_sync+0x2b/0x50
[  726.069691]  [<ffffffffc080850b>] ? applespi_sync_read+0x9b/0xd0 [applespi]
[  726.069695]  [<ffffffff92d52e20>] ? spi_finalize_current_transfer+0x20/0x20
[  726.069698]  [<ffffffffc08089db>] ? applespi_probe+0x32b/0x4e4 [applespi]
[  726.069702]  [<ffffffff92c0d0df>] ? acpi_dev_pm_attach+0x85/0xa0
[  726.069705]  [<ffffffff92d52b95>] ? spi_drv_probe+0x75/0xc0
[  726.069708]  [<ffffffff92cc4e46>] ? devices_kset_move_last+0x46/0x90
[  726.069712]  [<ffffffff92cc8baa>] ? driver_probe_device+0x21a/0x420
[  726.069714]  [<ffffffff92cc8e8a>] ? __driver_attach+0xda/0xe0
[  726.069717]  [<ffffffff92cc8db0>] ? driver_probe_device+0x420/0x420
[  726.069720]  [<ffffffff92cc66c7>] ? bus_for_each_dev+0x67/0xb0
[  726.069723]  [<ffffffff92cc7d7a>] ? bus_add_driver+0x16a/0x260
[  726.069726]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  726.069729]  [<ffffffff92cc97e7>] ? driver_register+0x57/0xc0
[  726.069730]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  726.069733]  [<ffffffff9280218b>] ? do_one_initcall+0x4b/0x190
[  726.069737]  [<ffffffff929f1540>] ? kmem_cache_alloc_trace+0x150/0x1d0
[  726.069741]  [<ffffffff92987eeb>] ? do_init_module+0x5b/0x1ed
[  726.069744]  [<ffffffff9290b764>] ? load_module+0x2934/0x2bd0
[  726.069748]  [<ffffffff929076b0>] ? m_show+0x1b0/0x1b0
[  726.069752]  [<ffffffff9290bc46>] ? SYSC_finit_module+0xc6/0xf0
[  726.069755]  [<ffffffff92efbef6>] ? entry_SYSCALL_64_fastpath+0x1e/0xa8
[  846.914906] INFO: task insmod:7916 blocked for more than 120 seconds.
[  846.914913]       Tainted: P       A   OE   4.8.0-rc7-custom #2
[  846.914915] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  846.914917] insmod          D ffff902a642dbfc0     0  7916   7915 0x00000000
[  846.914924]  ffff902a64dd2a80 ffff902a642dbfc0 ffff902a6ec58f40 ffff902a299d0000
[  846.914928]  ffff902a299cf9c8 ffff902a299cfa48 ffff902a642dbfc0 ffff902a5f33e320
[  846.914932]  ffffffffc080a0c0 ffffffff92ef7a91 ffff902a299cfa50 ffffffff92efaf80
[  846.914935] Call Trace:
[  846.914946]  [<ffffffff92ef7a91>] ? schedule+0x31/0x80
[  846.914951]  [<ffffffff92efaf80>] ? schedule_timeout+0x2d0/0x490
[  846.914955]  [<ffffffff928a8e64>] ? ttwu_do_wakeup+0x14/0x100
[  846.914958]  [<ffffffff928a9c63>] ? try_to_wake_up+0x53/0x3c0
[  846.914962]  [<ffffffff92ef84b1>] ? wait_for_completion+0xf1/0x130
[  846.914965]  [<ffffffff928aa060>] ? wake_up_q+0x70/0x70
[  846.914970]  [<ffffffff92d562cf>] ? __spi_sync+0x10f/0x220
[  846.914974]  [<ffffffff92d5640b>] ? spi_sync+0x2b/0x50
[  846.914978]  [<ffffffffc080850b>] ? applespi_sync_read+0x9b/0xd0 [applespi]
[  846.914982]  [<ffffffff92d52e20>] ? spi_finalize_current_transfer+0x20/0x20
[  846.914986]  [<ffffffffc08089db>] ? applespi_probe+0x32b/0x4e4 [applespi]
[  846.914989]  [<ffffffff92c0d0df>] ? acpi_dev_pm_attach+0x85/0xa0
[  846.914993]  [<ffffffff92d52b95>] ? spi_drv_probe+0x75/0xc0
[  846.914995]  [<ffffffff92cc4e46>] ? devices_kset_move_last+0x46/0x90
[  846.914999]  [<ffffffff92cc8baa>] ? driver_probe_device+0x21a/0x420
[  846.915002]  [<ffffffff92cc8e8a>] ? __driver_attach+0xda/0xe0
[  846.915004]  [<ffffffff92cc8db0>] ? driver_probe_device+0x420/0x420
[  846.915007]  [<ffffffff92cc66c7>] ? bus_for_each_dev+0x67/0xb0
[  846.915010]  [<ffffffff92cc7d7a>] ? bus_add_driver+0x16a/0x260
[  846.915013]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  846.915016]  [<ffffffff92cc97e7>] ? driver_register+0x57/0xc0
[  846.915017]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  846.915020]  [<ffffffff9280218b>] ? do_one_initcall+0x4b/0x190
[  846.915025]  [<ffffffff929f1540>] ? kmem_cache_alloc_trace+0x150/0x1d0
[  846.915028]  [<ffffffff92987eeb>] ? do_init_module+0x5b/0x1ed
[  846.915031]  [<ffffffff9290b764>] ? load_module+0x2934/0x2bd0
[  846.915035]  [<ffffffff929076b0>] ? m_show+0x1b0/0x1b0
[  846.915039]  [<ffffffff9290bc46>] ? SYSC_finit_module+0xc6/0xf0
[  846.915042]  [<ffffffff92efbef6>] ? entry_SYSCALL_64_fastpath+0x1e/0xa8
[  967.759983] INFO: task insmod:7916 blocked for more than 120 seconds.
[  967.759990]       Tainted: P       A   OE   4.8.0-rc7-custom #2
[  967.759992] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  967.759994] insmod          D ffff902a642dbfc0     0  7916   7915 0x00000000
[  967.760002]  ffff902a64dd2a80 ffff902a642dbfc0 ffff902a6ec58f40 ffff902a299d0000
[  967.760005]  ffff902a299cf9c8 ffff902a299cfa48 ffff902a642dbfc0 ffff902a5f33e320
[  967.760009]  ffffffffc080a0c0 ffffffff92ef7a91 ffff902a299cfa50 ffffffff92efaf80
[  967.760013] Call Trace:
[  967.760024]  [<ffffffff92ef7a91>] ? schedule+0x31/0x80
[  967.760029]  [<ffffffff92efaf80>] ? schedule_timeout+0x2d0/0x490
[  967.760033]  [<ffffffff928a8e64>] ? ttwu_do_wakeup+0x14/0x100
[  967.760036]  [<ffffffff928a9c63>] ? try_to_wake_up+0x53/0x3c0
[  967.760040]  [<ffffffff92ef84b1>] ? wait_for_completion+0xf1/0x130
[  967.760043]  [<ffffffff928aa060>] ? wake_up_q+0x70/0x70
[  967.760048]  [<ffffffff92d562cf>] ? __spi_sync+0x10f/0x220
[  967.760052]  [<ffffffff92d5640b>] ? spi_sync+0x2b/0x50
[  967.760056]  [<ffffffffc080850b>] ? applespi_sync_read+0x9b/0xd0 [applespi]
[  967.760060]  [<ffffffff92d52e20>] ? spi_finalize_current_transfer+0x20/0x20
[  967.760064]  [<ffffffffc08089db>] ? applespi_probe+0x32b/0x4e4 [applespi]
[  967.760067]  [<ffffffff92c0d0df>] ? acpi_dev_pm_attach+0x85/0xa0
[  967.760070]  [<ffffffff92d52b95>] ? spi_drv_probe+0x75/0xc0
[  967.760073]  [<ffffffff92cc4e46>] ? devices_kset_move_last+0x46/0x90
[  967.760076]  [<ffffffff92cc8baa>] ? driver_probe_device+0x21a/0x420
[  967.760079]  [<ffffffff92cc8e8a>] ? __driver_attach+0xda/0xe0
[  967.760082]  [<ffffffff92cc8db0>] ? driver_probe_device+0x420/0x420
[  967.760085]  [<ffffffff92cc66c7>] ? bus_for_each_dev+0x67/0xb0
[  967.760088]  [<ffffffff92cc7d7a>] ? bus_add_driver+0x16a/0x260
[  967.760091]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  967.760094]  [<ffffffff92cc97e7>] ? driver_register+0x57/0xc0
[  967.760095]  [<ffffffffc0213000>] ? 0xffffffffc0213000
[  967.760098]  [<ffffffff9280218b>] ? do_one_initcall+0x4b/0x190
[  967.760102]  [<ffffffff929f1540>] ? kmem_cache_alloc_trace+0x150/0x1d0
[  967.760106]  [<ffffffff92987eeb>] ? do_init_module+0x5b/0x1ed
[  967.760109]  [<ffffffff9290b764>] ? load_module+0x2934/0x2bd0
[  967.760113]  [<ffffffff929076b0>] ? m_show+0x1b0/0x1b0
[  967.760117]  [<ffffffff9290bc46>] ? SYSC_finit_module+0xc6/0xf0
[  967.760120]  [<ffffffff92efbef6>] ? entry_SYSCALL_64_fastpath+0x1e/0xa8

Please let me know what I can do to help next!
Comment 61 Federico Lorenzi 2016-10-02 09:57:49 UTC
(In reply to Denver from comment #60)

> I have a macbook 2015 model, just installed Ubuntu 16.10 (wifi works out of
> the box!! - also usb hotswap is more reliable), recompiled kernel 4.7-rc7
> with the modified DSDT, and can confirm the spi device now enumerates. 
> 
> When I load the keyboard module I get the following:

Hmm - interesting, did you have to do anything else to get SPI to work? I don't actually know what the status of SPI on the 2015 MacBook is, could you perhaps post a full dmesg?

Another good testing option is to grab a simple spidev binding module from [1] and modify the #defines to suit the MacBook (You can set the hz to 8000000, not sure what the spi_bus and spi_cs should be for the 2015 model, but perhaps try 0 0 or 2 0). You'll also want to do this with an unmodified DSDT. To compile this as a module you'll want to create a small Makefile so you can just compile it out of tree. See [2] for an example

You can then grab [3] and compile and run it. It should give you some output similar to below:

./spidev_test -D /dev/spidev2.0 -v -s 8000000
spi mode: 0x0
bits per word: 8
max speed: 8000000 Hz (8000 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF ...
RX | 20 00 00 00 00 00 0F 00 10 E0 00 00 00 00 05 00 E0 10 00 00 00 6C 78 ...

[1] https://raw.githubusercontent.com/MinnowBoard/minnow-max-extras/master/modules/low-speed-spidev/low-speed-spidev.c
[2] http://stackoverflow.com/questions/4133338/makefile-for-linux-kernel-module
[3] https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c
Comment 62 Cameron Gutman 2016-10-02 18:26:17 UTC
(In reply to Denver from comment #60)
> Hi, looks like some amazing progress has gone on since I last looked here!
> Thanks to everyone for their work!
> 
> I have a macbook 2015 model, just installed Ubuntu 16.10 (wifi works out of
> the box!! - also usb hotswap is more reliable), recompiled kernel 4.7-rc7
> with the modified DSDT, and can confirm the spi device now enumerates. 
> 
> When I load the keyboard module I get the following:
> 

This looks like it could be related to Leif's finding that the SPI controller was assigned IRQ 20 instead of 21. Since the interrupt didn't get hooked up properly, the SPI driver hung waiting for completion of the initial transfer.
Comment 63 Denver 2016-10-27 18:19:21 UTC
Hi, 

It's been a busy month, sorry. But now I've tried the spidev stuff from comment #61...

Using a vanilla ubuntu 4.8.0-17-generic kernel (no modified DSDT)....

SPI_BUS = 2 doesn't work ('Failed to register SPI device')

But with: 
#define LOW_SPEED_SPIDEV_SPI_BUS 0
#define LOW_SPEED_SPIDEV_SPI_CS 0
#define LOW_SPEED_SPIDEV_MAX_CLK_HZ 8000000
I get:

spi mode: 0x0
bits per word: 8
max speed: 8000000 Hz (8000 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  | ......@....�..................�.
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  | ................................

cat /proc/interupts gives: 
           CPU0       CPU1       CPU2       CPU3       
  0:         28          0          0          0  IR-IO-APIC   2-edge      timer
  8:          0          0          1          0  IR-IO-APIC   8-edge      rtc0
  9:        166        201       1026        145  IR-IO-APIC   9-fasteoi   acpi
 20:          0          0          0          0  IR-IO-APIC  20-fasteoi   dw_dmac
 21:          0          0         12          1  IR-IO-APIC  21-fasteoi   pxa2xx-spi.0
 40:          0          0          0          0  DMAR-MSI   0-edge      dmar0
 41:          0          0          0          0  DMAR-MSI   1-edge      dmar1
 42:        568        209      14909        302  IR-PCI-MSI 327680-edge      xhci_hcd
 43:      11477       6854     123582      10682  IR-PCI-MSI 1572864-edge      nvme0q0, nvme0q1
 44:        528      52615        115         39  IR-PCI-MSI 32768-edge      i915
 45:          1          0         11          0  IR-PCI-MSI 360448-edge      mei_me
 47:        132         78         47        150  IR-PCI-MSI 442368-edge      snd_hda_intel:card1
 48:        344        170        573        127  IR-PCI-MSI 49152-edge      snd_hda_intel:card0
 49:         39          8         91       1162  IR-PCI-MSI 524288-edge      brcmf_pcie_intr
NMI:         13         15         11         10   Non-maskable interrupts
LOC:      24419      26519      21407      21619   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:         13         15         11         10   Performance monitoring interrupts
IWI:          0          0          0          0   IRQ work interrupts
RTR:          3          0          0          0   APIC ICR read retries
RES:       5230       5635       4537       4730   Rescheduling interrupts
CAL:       2059       1204       1626       1431   Function call interrupts
TLB:        190        168        225        178   TLB shootdowns
TRM:          4          4          4          4   Thermal event interrupts
THR:          0          0          0          0   Threshold APIC interrupts
DFR:          0          0          0          0   Deferred Error APIC interrupts
MCE:          0          0          0          0   Machine check exceptions
MCP:          4          3          3          3   Machine check polls
ERR:          0
MIS:          0
PIN:          0          0          0          0   Posted-interrupt notification event
PIW:          0          0          0          0   Posted-interrupt wakeup event
... so I'm not sure about the IRQ 20 rather than 21 as mentioned in #62.  Also /sys/device...pxa2.../irq == 21

I'm free to tinker this weekend, so welcome any suggestions.. 

In the keyboard source I can't see where/if the SPI BUS/CS settings are made, what am I missing?

Also, I notice that the pxa2xx-spi.0 driver  seems to have a max speed of 1000000Hz, not 4000000 or 8000000 does that matter?
Comment 64 Denver 2016-10-27 18:19:38 UTC
Hi, 

It's been a busy month, sorry. But now I've tried the spidev stuff from comment #61...

Using a vanilla ubuntu 4.8.0-17-generic kernel (no modified DSDT)....

SPI_BUS = 2 doesn't work ('Failed to register SPI device')

But with: 
#define LOW_SPEED_SPIDEV_SPI_BUS 0
#define LOW_SPEED_SPIDEV_SPI_CS 0
#define LOW_SPEED_SPIDEV_MAX_CLK_HZ 8000000
I get:

spi mode: 0x0
bits per word: 8
max speed: 8000000 Hz (8000 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  | ......@....�..................�.
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  | ................................

cat /proc/interupts gives: 
           CPU0       CPU1       CPU2       CPU3       
  0:         28          0          0          0  IR-IO-APIC   2-edge      timer
  8:          0          0          1          0  IR-IO-APIC   8-edge      rtc0
  9:        166        201       1026        145  IR-IO-APIC   9-fasteoi   acpi
 20:          0          0          0          0  IR-IO-APIC  20-fasteoi   dw_dmac
 21:          0          0         12          1  IR-IO-APIC  21-fasteoi   pxa2xx-spi.0
 40:          0          0          0          0  DMAR-MSI   0-edge      dmar0
 41:          0          0          0          0  DMAR-MSI   1-edge      dmar1
 42:        568        209      14909        302  IR-PCI-MSI 327680-edge      xhci_hcd
 43:      11477       6854     123582      10682  IR-PCI-MSI 1572864-edge      nvme0q0, nvme0q1
 44:        528      52615        115         39  IR-PCI-MSI 32768-edge      i915
 45:          1          0         11          0  IR-PCI-MSI 360448-edge      mei_me
 47:        132         78         47        150  IR-PCI-MSI 442368-edge      snd_hda_intel:card1
 48:        344        170        573        127  IR-PCI-MSI 49152-edge      snd_hda_intel:card0
 49:         39          8         91       1162  IR-PCI-MSI 524288-edge      brcmf_pcie_intr
NMI:         13         15         11         10   Non-maskable interrupts
LOC:      24419      26519      21407      21619   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:         13         15         11         10   Performance monitoring interrupts
IWI:          0          0          0          0   IRQ work interrupts
RTR:          3          0          0          0   APIC ICR read retries
RES:       5230       5635       4537       4730   Rescheduling interrupts
CAL:       2059       1204       1626       1431   Function call interrupts
TLB:        190        168        225        178   TLB shootdowns
TRM:          4          4          4          4   Thermal event interrupts
THR:          0          0          0          0   Threshold APIC interrupts
DFR:          0          0          0          0   Deferred Error APIC interrupts
MCE:          0          0          0          0   Machine check exceptions
MCP:          4          3          3          3   Machine check polls
ERR:          0
MIS:          0
PIN:          0          0          0          0   Posted-interrupt notification event
PIW:          0          0          0          0   Posted-interrupt wakeup event
... so I'm not sure about the IRQ 20 rather than 21 as mentioned in #62.  Also /sys/device...pxa2.../irq == 21

I'm free to tinker this weekend, so welcome any suggestions.. 

In the keyboard source I can't see where/if the SPI BUS/CS settings are made, what am I missing?

Also, I notice that the pxa2xx-spi.0 driver  seems to have a max speed of 1000000Hz, not 4000000 or 8000000 does that matter?
Comment 65 noobermin 2016-10-29 19:27:31 UTC
Hopefully now that the new Macbook Pro is out with what looks like a similar keyboard, more eyes will reach this issue. But with all likelihood, it will not use Wildcat.
Comment 66 Federico Lorenzi 2016-10-29 21:32:56 UTC
(In reply to Denver from comment #64)
> 
> But with: 
> #define LOW_SPEED_SPIDEV_SPI_BUS 0
> #define LOW_SPEED_SPIDEV_SPI_CS 0
> #define LOW_SPEED_SPIDEV_MAX_CLK_HZ 8000000
> I get:
> 
> spi mode: 0x0
> bits per word: 8
> max speed: 8000000 Hz (8000 KHz)
> TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF
> FF FF FF FF FF FF F0 0D  | ......@....�..................�.
> RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00  | ................................
> 
Interesting, that looks to me like you're communicating with the touchpad just fine. Can you make spidev_test read 256 bytes? You can do this by running spidev_test with the -p argument, and specifying \x00 256 times (although there might be a better way!)

The reason I say this, the keyboard / touchpad doesn't require any special initialization for basic use, but it will send the same packet over and over again unless the full packet of 256 bytes is read out. You should be able to run this command a few times, then hit a key and run it again and notice a change in output.

> 
> In the keyboard source I can't see where/if the SPI BUS/CS settings are
> made, what am I missing?
So the driver automatically attaches based on ACPI, it matches the "APP000D" device and gets parameters from there. It would be handy to be able to bind it manually to a specific SPI device; I'll see if I can add that as an option, for debugging at least.

> 
> Also, I notice that the pxa2xx-spi.0 driver  seems to have a max speed of
> 1000000Hz, not 4000000 or 8000000 does that matter?
Interesting; the driver operates at 400000 (400kHz) but the DSDT suggests 8MHz is what should be used to drive it. Changing the speed didn't really seem to affect it too much - above 400kHz it was erratic, but going slower didn't have any effects. SPI clock speeds don't have to "match" since it's the master that drives the slave (within any timing requirements the slave has, of course)
Comment 67 Denver 2016-10-31 20:09:25 UTC
I'm afraid it looks like bad news to me: I don't think I am connecting to the touchpad :(
After running spidev several times with 256 bytes it kept returning zeros. 

Also, I notice that if I boot into the kernel with the modified dsdt and 
ls /sys/devices/pci0000\:00/0000\:00\:15.4/pxa2xx-spi.0/spi_master/spi0/spi-APP000D\:00/ there is no 'input' directory, so presumably that's why the driver is failing to bind?
Comment 68 Daniel Roschka 2017-01-18 00:10:35 UTC
MacBook Pro 2016 Touch Bar (MacBookPro13,2) owner here. Keyboard works fine with the DSDT-patch and the experimental driver written by Federico. It doesn't cover the Touch Bar, which doesn't work at all so far.

What's not working right now as well is the touchpad. Any idea what could be the issue there when the keyboard is already working? According to the driver output it properly found the touchpad:

[   56.371988] applespi: loading out-of-tree module taints kernel.
[   56.372027] applespi: module verification failed: signature and/or required key missing - tainting kernel
[   56.372408] input: Apple SPI Keyboard as /devices/pci0000:00/0000:00:1e.3/pxa2xx-spi.3/spi_master/spi2/spi-APP000D:00/input/input9
[   56.372642] input: Apple SPI Touchpad as /devices/pci0000:00/0000:00:1e.3/pxa2xx-spi.3/spi_master/spi2/spi-APP000D:00/input/input10
[   56.406423] applespi: modeswitch done.
[   56.406443] applespi: module probe done.

This touchpad is also mentioned in Xorg.0.log:

[  1021.393] (II) config/udev: Adding input device Apple SPI Touchpad (/dev/input/event10)
[  1021.393] (**) Apple SPI Touchpad: Applying InputClass "evdev touchpad catchall"
[  1021.393] (**) Apple SPI Touchpad: Applying InputClass "touchpad catchall"
[  1021.393] (**) Apple SPI Touchpad: Applying InputClass "Default clickpad buttons"
[  1021.393] (**) Apple SPI Touchpad: Applying InputClass "Disable clickpad buttons on Apple touchpads"
[  1021.393] (II) LoadModule: "synaptics"
[  1021.393] (II) Loading /usr/lib/xorg/modules/input/synaptics_drv.so
[  1021.393] (II) Module synaptics: vendor="X.Org Foundation"
[  1021.393]    compiled for 1.18.3, module version = 1.8.3
[  1021.393]    Module class: X.Org XInput Driver
[  1021.393]    ABI class: X.Org XInput driver, version 22.1
[  1021.393] (II) Using input driver 'synaptics' for 'Apple SPI Touchpad'
[  1021.393] (**) Apple SPI Touchpad: always reports core events
[  1021.393] (**) Option "Device" "/dev/input/event10"
[  1021.500] (II) synaptics: Apple SPI Touchpad: found clickpad property
[  1021.500] (--) synaptics: Apple SPI Touchpad: x-axis range -4828 - 5345 (res 0)
[  1021.500] (--) synaptics: Apple SPI Touchpad: y-axis range -203 - 6803 (res 0)
[  1021.500] (II) synaptics: Apple SPI Touchpad: device does not report pressure, will use touch data.
[  1021.500] (II) synaptics: Apple SPI Touchpad: device does not report finger width.
[  1021.500] (--) synaptics: Apple SPI Touchpad: buttons: left double triple
[  1021.500] (--) synaptics: Apple SPI Touchpad: Vendor 0 Product 0
[  1021.500] (--) synaptics: Apple SPI Touchpad: invalid pressure range.  defaulting to 0 - 255
[  1021.500] (--) synaptics: Apple SPI Touchpad: invalid finger width range.  defaulting to 0 - 15
[  1021.500] (**) Option "SoftButtonAreas" "0 0 0 0 0 0 0 0"
[  1021.500] (--) synaptics: Apple SPI Touchpad: touchpad found
[  1021.500] (**) Apple SPI Touchpad: always reports core events
[  1021.552] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:1e.3/pxa2xx-spi.3/spi_master/spi2/spi-APP000D:00/input/input10/event10"
[  1021.552] (II) XINPUT: Adding extended input device "Apple SPI Touchpad" (type: TOUCHPAD, id 13)
[  1021.552] (**) synaptics: Apple SPI Touchpad: (accel) MinSpeed is now constant deceleration 2.5
[  1021.552] (**) synaptics: Apple SPI Touchpad: (accel) MaxSpeed is now 1.75
[  1021.552] (**) synaptics: Apple SPI Touchpad: (accel) AccelFactor is now 0.016
[  1021.552] (**) Apple SPI Touchpad: (accel) keeping acceleration scheme 1
[  1021.552] (**) Apple SPI Touchpad: (accel) acceleration profile 1
[  1021.552] (**) Apple SPI Touchpad: (accel) acceleration factor: 2.000
[  1021.552] (**) Apple SPI Touchpad: (accel) acceleration threshold: 4
[  1021.552] (--) synaptics: Apple SPI Touchpad: touchpad found
[  1021.552] (II) config/udev: Adding input device Apple SPI Touchpad (/dev/input/mouse1)
[  1021.552] (**) Apple SPI Touchpad: Ignoring device from InputClass "touchpad ignore duplicates"
Comment 69 Federico Lorenzi 2017-01-18 08:13:52 UTC
(In reply to Daniel Roschka from comment #68)
> MacBook Pro 2016 Touch Bar (MacBookPro13,2) owner here. Keyboard works fine
> with the DSDT-patch and the experimental driver written by Federico. It
> doesn't cover the Touch Bar, which doesn't work at all so far.
> 
> What's not working right now as well is the touchpad. Any idea what could be
> the issue there when the keyboard is already working? According to the
> driver output it properly found the touchpad:

Glad to hear the driver somewhat works with the new MBPs. Regarding the touchpad, perhaps try duplicate line 173 (the entry in applespi_init_commands) a few times. I've noticed that sometimes the modeswitch doesn't happen properly (the driver should probably wait for an ACK or similar from the touchpad).

One way to confirm this is the case is by running evtest on the touchpad event device.  If the modeswitch hasn't taken place (but everything else is working) you'll only get button click events.
Comment 70 Daniel Roschka 2017-01-18 20:24:59 UTC
All right, today it started to work right out of the box, without further modifications to the driver.
I'll keep an eye on the touchpad initialization and will report back if the problem appears again.
Comment 71 littlejokee 2017-05-07 09:43:29 UTC
Are there any news for any of the recent kernels?

I realised that some of the patches are integrated but neither mouse nor keyboard are working out of the box.
Testing the apple-spi driver from Federico did not work either. From what I saw, the device was not enumerated, but I didn't figure out why yet.
Comment 72 Chatty 2018-12-30 20:25:13 UTC
As documented here (https://github.com/cb22/macbook12-spi-driver/issues/71) you need to boot with `irqfixup` and applespi module.
Comment 73 Andy Shevchenko 2020-10-12 14:19:32 UTC
I'm about to close this bug since nobody appear to test and confirm the state.
So I leave it in need info state for a while (day or two) and then close.