Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6696777c authored by Duson Lin's avatar Duson Lin Committed by Dmitry Torokhov
Browse files

Input: add driver for Elan I2C/SMbus touchpad



This driver supports Elan I2C/SMbus touchpads found in some laptops and
also in many Chromebooks.

Signed-off-by: default avatarDuson Lin <dusonlin@emc.com.tw>
Reviewed-by: default avatarBenson Leung <bleung@chromium.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent dae7aa8d
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
Elantech I2C Touchpad

Required properties:
- compatible: must be "elan,ekth3000".
- reg: I2C address of the chip.
- interrupt-parent: a phandle for the interrupt controller (see interrupt
  binding[0]).
- interrupts: interrupt to which the chip is connected (see interrupt
  binding[0]).

Optional properties:
- wakeup-source: touchpad can be used as a wakeup source.
- pinctrl-names: should be "default" (see pinctrl binding [1]).
- pinctrl-0: a phandle pointing to the pin settings for the device (see
  pinctrl binding [1]).
- vcc-supply: a phandle for the regulator supplying 3.3V power.

[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
[1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

Example:
	&i2c1 {
		/* ... */

		touchpad@15 {
			compatible = "elan,ekth3000";
			reg = <0x15>;
			interrupt-parent = <&gpio4>;
			interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>;
			wakeup-source;
		};

		/* ... */
	};
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ dlink D-Link Corporation
dmo	Data Modul AG
ebv	EBV Elektronik
edt	Emerging Display Technologies
elan	Elan Microelectronic Corp.
emmicro	EM Microelectronic
epcos	EPCOS AG
epfl	Ecole Polytechnique Fédérale de Lausanne
+30 −0
Original line number Diff line number Diff line
@@ -215,6 +215,36 @@ config MOUSE_CYAPA
	  To compile this driver as a module, choose M here: the module will be
	  called cyapa.

config MOUSE_ELAN_I2C
	tristate "ELAN I2C Touchpad support"
	depends on I2C
	help
	  This driver adds support for Elan I2C/SMbus Trackpads.

	  Say Y here if you have a ELAN I2C/SMbus Touchpad.

	  To compile this driver as a module, choose M here: the module will be
	  called elan_i2c.

config MOUSE_ELAN_I2C_I2C
	bool "Enable I2C support"
	depends on MOUSE_ELAN_I2C
	default y
	help
	   Say Y here if Elan Touchpad in your system is connected to
	   a standard I2C controller.

	   If unsure, say Y.

config MOUSE_ELAN_I2C_SMBUS
	bool "Enable SMbus support"
	depends on MOUSE_ELAN_I2C
	help
	   Say Y here if Elan Touchpad in your system is connected to
	   a SMbus adapter.

	   If unsure, say Y.

config MOUSE_INPORT
	tristate "InPort/MS/ATIXL busmouse"
	depends on ISA
+5 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI)		+= atarimouse.o
obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
obj-$(CONFIG_MOUSE_CYAPA)		+= cyapa.o
obj-$(CONFIG_MOUSE_ELAN_I2C)		+= elan_i2c.o
obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
obj-$(CONFIG_MOUSE_INPORT)		+= inport.o
obj-$(CONFIG_MOUSE_LOGIBM)		+= logibm.o
@@ -34,3 +35,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT)	+= trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)	+= touchkit_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_CYPRESS)	+= cypress_ps2.o

elan_i2c-objs := elan_i2c_core.o
elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C)	+= elan_i2c_i2c.o
elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_SMBUS)	+= elan_i2c_smbus.o
+86 −0
Original line number Diff line number Diff line
/*
 * Elan I2C/SMBus Touchpad driver
 *
 * Copyright (c) 2013 ELAN Microelectronics Corp.
 *
 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
 * Version: 1.5.5
 *
 * Based on cyapa driver:
 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
 * copyright (c) 2011-2012 Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Trademarks are the property of their respective owners.
 */

#ifndef _ELAN_I2C_H
#define _ELAN_i2C_H

#include <linux/types.h>

#define ETP_ENABLE_ABS		0x0001
#define ETP_ENABLE_CALIBRATE	0x0002
#define ETP_DISABLE_CALIBRATE	0x0000
#define ETP_DISABLE_POWER	0x0001

/* IAP Firmware handling */
#define ETP_FW_NAME		"elan_i2c.bin"
#define ETP_IAP_START_ADDR	0x0083
#define ETP_FW_IAP_PAGE_ERR	(1 << 5)
#define ETP_FW_IAP_INTF_ERR	(1 << 4)
#define ETP_FW_PAGE_SIZE	64
#define ETP_FW_PAGE_COUNT	768
#define ETP_FW_SIZE		(ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT)

struct i2c_client;
struct completion;

enum tp_mode {
	IAP_MODE = 1,
	MAIN_MODE
};

struct elan_transport_ops {
	int (*initialize)(struct i2c_client *client);
	int (*sleep_control)(struct i2c_client *, bool sleep);
	int (*power_control)(struct i2c_client *, bool enable);
	int (*set_mode)(struct i2c_client *client, u8 mode);

	int (*calibrate)(struct i2c_client *client);
	int (*calibrate_result)(struct i2c_client *client, u8 *val);

	int (*get_baseline_data)(struct i2c_client *client,
				 bool max_baseliune, u8 *value);

	int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
	int (*get_sm_version)(struct i2c_client *client, u8 *version);
	int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum);
	int (*get_product_id)(struct i2c_client *client, u8 *id);

	int (*get_max)(struct i2c_client *client,
		       unsigned int *max_x, unsigned int *max_y);
	int (*get_resolution)(struct i2c_client *client,
			      u8 *hw_res_x, u8 *hw_res_y);
	int (*get_num_traces)(struct i2c_client *client,
			      unsigned int *x_tracenum,
			      unsigned int *y_tracenum);

	int (*iap_get_mode)(struct i2c_client *client, enum tp_mode *mode);
	int (*iap_reset)(struct i2c_client *client);

	int (*prepare_fw_update)(struct i2c_client *client);
	int (*write_fw_block)(struct i2c_client *client,
			      const u8 *page, u16 checksum, int idx);
	int (*finish_fw_update)(struct i2c_client *client,
				struct completion *reset_done);

	int (*get_report)(struct i2c_client *client, u8 *report);
};

extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops;

#endif /* _ELAN_I2C_H */
Loading