linux/drivers/input/mouse/bcm5974.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver
 *
 * Copyright (C) 2008	   Henrik Rydberg ([email protected])
 * Copyright (C) 2015      John Horan ([email protected])
 *
 * The USB initialization and package decoding was made by
 * Scott Shawcroft as part of the touchd user-space driver project:
 * Copyright (C) 2008	   Scott Shawcroft ([email protected])
 *
 * The BCM5974 driver is based on the appletouch driver:
 * Copyright (C) 2001-2004 Greg Kroah-Hartman ([email protected])
 * Copyright (C) 2005      Johannes Berg ([email protected])
 * Copyright (C) 2005	   Stelian Pop ([email protected])
 * Copyright (C) 2005	   Frank Arnold ([email protected])
 * Copyright (C) 2005	   Peter Osterlund ([email protected])
 * Copyright (C) 2005	   Michael Hanselmann ([email protected])
 * Copyright (C) 2006	   Nicolas Boichat ([email protected])
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/input/mt.h>

#define USB_VENDOR_ID_APPLE

/* MacbookAir, aka wellspring */
#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS
/* MacbookProPenryn, aka wellspring2 */
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS
/* Macbook5,1 (unibody), aka wellspring3 */
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS
/* MacbookAir3,2 (unibody), aka wellspring5 */
#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS
/* MacbookAir3,1 (unibody), aka wellspring4 */
#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS
/* Macbook8 (unibody, March 2011) */
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS
/* MacbookAir4,1 (unibody, July 2011) */
#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS
/* MacbookAir4,2 (unibody, July 2011) */
#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS
/* Macbook8,2 (unibody) */
#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS
/* MacbookPro10,1 (unibody, June 2012) */
#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS
/* MacbookPro10,2 (unibody, October 2012) */
#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS
/* MacbookAir6,2 (unibody, June 2013) */
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS
/* MacbookPro12,1 (2015) */
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS

#define BCM5974_DEVICE(prod)

/* table of devices that work with this driver */
static const struct usb_device_id bcm5974_table[] =;
MODULE_DEVICE_TABLE(usb, bcm5974_table);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

#define dprintk(level, format, a...)

static int debug =;
module_param(debug, int, 0644);
MODULE_PARM_DESC();

/* button data structure */
struct bt_data {};

/* trackpad header types */
enum tp_type {};

/* trackpad finger data offsets, le16-aligned */
#define HEADER_TYPE1
#define HEADER_TYPE2
#define HEADER_TYPE3
#define HEADER_TYPE4

/* trackpad button data offsets */
#define BUTTON_TYPE1
#define BUTTON_TYPE2
#define BUTTON_TYPE3
#define BUTTON_TYPE4

/* list of device capability bits */
#define HAS_INTEGRATED_BUTTON

/* trackpad finger data block size */
#define FSIZE_TYPE1
#define FSIZE_TYPE2
#define FSIZE_TYPE3
#define FSIZE_TYPE4

/* offset from header to finger struct */
#define DELTA_TYPE1
#define DELTA_TYPE2
#define DELTA_TYPE3
#define DELTA_TYPE4

/* usb control message mode switch data */
#define USBMSG_TYPE1
#define USBMSG_TYPE2
#define USBMSG_TYPE3
#define USBMSG_TYPE4

/* Wellspring initialization constants */
#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID
#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID

/* trackpad finger structure, le16-aligned */
struct tp_finger {} __attribute__((packed,aligned));

/* trackpad finger data size, empirically at least ten fingers */
#define MAX_FINGERS
#define MAX_FINGER_ORIENTATION

/* device-specific parameters */
struct bcm5974_param {};

/* device-specific configuration */
struct bcm5974_config {};

/* logical device structure */
struct bcm5974 {};

/* trackpad finger block data, le16-aligned */
static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i)
{}

#define DATAFORMAT(type)

/* logical signal quality */
#define SN_PRESSURE
#define SN_WIDTH
#define SN_COORD
#define SN_ORIENT

/* device constants */
static const struct bcm5974_config bcm5974_config_table[] =;

/* return the device-specific configuration by device */
static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev)
{}

/* convert 16-bit little endian to signed integer */
static inline int raw2int(__le16 x)
{}

static void set_abs(struct input_dev *input, unsigned int code,
		    const struct bcm5974_param *p)
{}

/* setup which logical events to report */
static void setup_events_to_report(struct input_dev *input_dev,
				   const struct bcm5974_config *cfg)
{}

/* report button data as logical button state */
static int report_bt_state(struct bcm5974 *dev, int size)
{}

static void report_finger_data(struct input_dev *input, int slot,
			       const struct input_mt_pos *pos,
			       const struct tp_finger *f)
{}

static void report_synaptics_data(struct input_dev *input,
				  const struct bcm5974_config *cfg,
				  const struct tp_finger *f, int raw_n)
{}

/* report trackpad data as logical trackpad state */
static int report_tp_state(struct bcm5974 *dev, int size)
{}

static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
{}

static void bcm5974_irq_button(struct urb *urb)
{}

static void bcm5974_irq_trackpad(struct urb *urb)
{}

/*
 * The Wellspring trackpad, like many recent Apple trackpads, share
 * the usb device with the keyboard. Since keyboards are usually
 * handled by the HID system, the device ends up being handled by two
 * modules. Setting up the device therefore becomes slightly
 * complicated. To enable multitouch features, a mode switch is
 * required, which is usually applied via the control interface of the
 * device.  It can be argued where this switch should take place. In
 * some drivers, like appletouch, the switch is made during
 * probe. However, the hid module may also alter the state of the
 * device, resulting in trackpad malfunction under certain
 * circumstances. To get around this problem, there is at least one
 * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to
 * receive a reset_resume request rather than the normal resume.
 * Since the implementation of reset_resume is equal to mode switch
 * plus start_traffic, it seems easier to always do the switch when
 * starting traffic on the device.
 */
static int bcm5974_start_traffic(struct bcm5974 *dev)
{}

static void bcm5974_pause_traffic(struct bcm5974 *dev)
{}

/*
 * The code below implements open/close and manual suspend/resume.
 * All functions may be called in random order.
 *
 * Opening a suspended device fails with EACCES - permission denied.
 *
 * Failing a resume leaves the device resumed but closed.
 */
static int bcm5974_open(struct input_dev *input)
{}

static void bcm5974_close(struct input_dev *input)
{}

static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message)
{}

static int bcm5974_resume(struct usb_interface *iface)
{}

static int bcm5974_probe(struct usb_interface *iface,
			 const struct usb_device_id *id)
{}

static void bcm5974_disconnect(struct usb_interface *iface)
{}

static struct usb_driver bcm5974_driver =;

module_usb_driver();