Input: add Apple SPI keyboard and trackpad driver

The keyboard and trackpad on recent MacBook's (since 8,1) and
MacBookPro's (13,* and 14,*) are attached to an SPI controller instead
of USB, as previously. The higher level protocol is not publicly
documented and hence has been reverse engineered. As a consequence there
are still a number of unknown fields and commands. However, the known
parts have been working well and received extensive testing and use.

In order for this driver to work, the proper SPI drivers need to be
loaded too; for MB8,1 these are spi_pxa2xx_platform and spi_pxa2xx_pci;
for all others they are spi_pxa2xx_platform and intel_lpss_pci.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=99891
Link: https://bugzilla.kernel.org/show_bug.cgi?id=108331
Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Ronald Tschalär 2019-07-15 10:30:11 -07:00 committed by Dmitry Torokhov
parent 7e4935ccc3
commit 038b1a05ea
5 changed files with 2117 additions and 0 deletions

View File

@ -71,6 +71,22 @@ config KEYBOARD_AMIGA
config ATARI_KBD_CORE
bool
config KEYBOARD_APPLESPI
tristate "Apple SPI keyboard and trackpad"
depends on ACPI && EFI
depends on SPI
depends on X86 || COMPILE_TEST
help
Say Y here if you are running Linux on any Apple MacBook8,1 or later,
or any MacBookPro13,* or MacBookPro14,*.
You will also need to enable appropriate SPI master controllers:
spi_pxa2xx_platform and spi_pxa2xx_pci for MacBook8,1, and
spi_pxa2xx_platform and intel_lpss_pci for the rest.
To compile this driver as a module, choose M here: the
module will be called applespi.
config KEYBOARD_ATARI
tristate "Atari keyboard"
depends on ATARI

View File

@ -10,6 +10,7 @@ obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
obj-$(CONFIG_KEYBOARD_ADP5589) += adp5589-keys.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
obj-$(CONFIG_KEYBOARD_APPLESPI) += applespi.o
obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_BCM) += bcm-keypad.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* MacBook (Pro) SPI keyboard and touchpad driver
*
* Copyright (c) 2015-2019 Federico Lorenzi
* Copyright (c) 2017-2019 Ronald Tschalär
*/
#ifndef _APPLESPI_H_
#define _APPLESPI_H_
enum applespi_evt_type {
ET_CMD_TP_INI = BIT(0),
ET_CMD_BL = BIT(1),
ET_CMD_CL = BIT(2),
ET_RD_KEYB = BIT(8),
ET_RD_TPAD = BIT(9),
ET_RD_UNKN = BIT(10),
ET_RD_IRQ = BIT(11),
ET_RD_CRC = BIT(12),
};
enum applespi_pkt_type {
PT_READ,
PT_WRITE,
PT_STATUS,
};
#endif /* _APPLESPI_H_ */

View File

@ -0,0 +1,93 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* MacBook (Pro) SPI keyboard and touchpad driver
*
* Copyright (c) 2015-2019 Federico Lorenzi
* Copyright (c) 2017-2019 Ronald Tschalär
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM applespi
#if !defined(_APPLESPI_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
#define _APPLESPI_TRACE_H_
#include <linux/types.h>
#include <linux/tracepoint.h>
#include "applespi.h"
DECLARE_EVENT_CLASS(dump_message_template,
TP_PROTO(enum applespi_evt_type evt_type,
enum applespi_pkt_type pkt_type,
u8 *buf,
size_t len),
TP_ARGS(evt_type, pkt_type, buf, len),
TP_STRUCT__entry(
__field(enum applespi_evt_type, evt_type)
__field(enum applespi_pkt_type, pkt_type)
__field(size_t, len)
__dynamic_array(u8, buf, len)
),
TP_fast_assign(
__entry->evt_type = evt_type;
__entry->pkt_type = pkt_type;
__entry->len = len;
memcpy(__get_dynamic_array(buf), buf, len);
),
TP_printk("%-6s: %s",
__print_symbolic(__entry->pkt_type,
{ PT_READ, "read" },
{ PT_WRITE, "write" },
{ PT_STATUS, "status" }
),
__print_hex(__get_dynamic_array(buf), __entry->len))
);
#define DEFINE_DUMP_MESSAGE_EVENT(name) \
DEFINE_EVENT(dump_message_template, name, \
TP_PROTO(enum applespi_evt_type evt_type, \
enum applespi_pkt_type pkt_type, \
u8 *buf, \
size_t len), \
TP_ARGS(evt_type, pkt_type, buf, len) \
)
DEFINE_DUMP_MESSAGE_EVENT(applespi_tp_ini_cmd);
DEFINE_DUMP_MESSAGE_EVENT(applespi_backlight_cmd);
DEFINE_DUMP_MESSAGE_EVENT(applespi_caps_lock_cmd);
DEFINE_DUMP_MESSAGE_EVENT(applespi_keyboard_data);
DEFINE_DUMP_MESSAGE_EVENT(applespi_touchpad_data);
DEFINE_DUMP_MESSAGE_EVENT(applespi_unknown_data);
DEFINE_DUMP_MESSAGE_EVENT(applespi_bad_crc);
TRACE_EVENT(applespi_irq_received,
TP_PROTO(enum applespi_evt_type evt_type,
enum applespi_pkt_type pkt_type),
TP_ARGS(evt_type, pkt_type),
TP_STRUCT__entry(
__field(enum applespi_evt_type, evt_type)
__field(enum applespi_pkt_type, pkt_type)
),
TP_fast_assign(
__entry->evt_type = evt_type;
__entry->pkt_type = pkt_type;
),
"\n"
);
#endif /* _APPLESPI_TRACE_H_ */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH ../../drivers/input/keyboard
#define TRACE_INCLUDE_FILE applespi_trace
#include <trace/define_trace.h>