cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ektf2127.c (8893B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Driver for ELAN eKTF2127 i2c touchscreen controller
      4 *
      5 * For this driver the layout of the Chipone icn8318 i2c
      6 * touchscreencontroller is used.
      7 *
      8 * Author:
      9 * Michel Verlaan <michel.verl@gmail.com>
     10 * Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
     11 *
     12 * Original chipone_icn8318 driver:
     13 * Hans de Goede <hdegoede@redhat.com>
     14 */
     15
     16#include <linux/gpio/consumer.h>
     17#include <linux/interrupt.h>
     18#include <linux/i2c.h>
     19#include <linux/input.h>
     20#include <linux/input/mt.h>
     21#include <linux/input/touchscreen.h>
     22#include <linux/module.h>
     23#include <linux/of.h>
     24#include <linux/delay.h>
     25
     26/* Packet header defines (first byte of data send / received) */
     27#define EKTF2127_NOISE			0x40
     28#define EKTF2127_RESPONSE		0x52
     29#define EKTF2127_REQUEST		0x53
     30#define EKTF2127_HELLO			0x55
     31#define EKTF2127_REPORT2		0x5a
     32#define EKTF2127_REPORT			0x5d
     33#define EKTF2127_CALIB_DONE		0x66
     34
     35/* Register defines (second byte of data send / received) */
     36#define EKTF2127_ENV_NOISY		0x41
     37#define EKTF2127_HEIGHT			0x60
     38#define EKTF2127_WIDTH			0x63
     39
     40/* 2 bytes header + 5 * 3 bytes coordinates + 3 bytes pressure info + footer */
     41#define EKTF2127_TOUCH_REPORT_SIZE	21
     42#define EKTF2127_MAX_TOUCHES		5
     43
     44struct ektf2127_ts {
     45	struct i2c_client *client;
     46	struct input_dev *input;
     47	struct gpio_desc *power_gpios;
     48	struct touchscreen_properties prop;
     49};
     50
     51static void ektf2127_parse_coordinates(const u8 *buf, unsigned int touch_count,
     52				       struct input_mt_pos *touches)
     53{
     54	int index = 0;
     55	int i;
     56
     57	for (i = 0; i < touch_count; i++) {
     58		index = 2 + i * 3;
     59
     60		touches[i].x = (buf[index] & 0x0f);
     61		touches[i].x <<= 8;
     62		touches[i].x |= buf[index + 2];
     63
     64		touches[i].y = (buf[index] & 0xf0);
     65		touches[i].y <<= 4;
     66		touches[i].y |= buf[index + 1];
     67	}
     68}
     69
     70static void ektf2127_report_event(struct ektf2127_ts *ts, const u8 *buf)
     71{
     72	struct input_mt_pos touches[EKTF2127_MAX_TOUCHES];
     73	int slots[EKTF2127_MAX_TOUCHES];
     74	unsigned int touch_count, i;
     75
     76	touch_count = buf[1] & 0x07;
     77	if (touch_count > EKTF2127_MAX_TOUCHES) {
     78		dev_err(&ts->client->dev,
     79			"Too many touches %d > %d\n",
     80			touch_count, EKTF2127_MAX_TOUCHES);
     81		touch_count = EKTF2127_MAX_TOUCHES;
     82	}
     83
     84	ektf2127_parse_coordinates(buf, touch_count, touches);
     85	input_mt_assign_slots(ts->input, slots, touches,
     86			      touch_count, 0);
     87
     88	for (i = 0; i < touch_count; i++) {
     89		input_mt_slot(ts->input, slots[i]);
     90		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
     91		touchscreen_report_pos(ts->input, &ts->prop,
     92				       touches[i].x, touches[i].y, true);
     93	}
     94
     95	input_mt_sync_frame(ts->input);
     96	input_sync(ts->input);
     97}
     98
     99static void ektf2127_report2_contact(struct ektf2127_ts *ts, int slot,
    100				     const u8 *buf, bool active)
    101{
    102	input_mt_slot(ts->input, slot);
    103	input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, active);
    104
    105	if (active) {
    106		int x = (buf[0] & 0xf0) << 4 | buf[1];
    107		int y = (buf[0] & 0x0f) << 8 | buf[2];
    108
    109		touchscreen_report_pos(ts->input, &ts->prop, x, y, true);
    110	}
    111}
    112
    113static void ektf2127_report2_event(struct ektf2127_ts *ts, const u8 *buf)
    114{
    115	ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & 2));
    116	ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & 4));
    117
    118	input_mt_sync_frame(ts->input);
    119	input_sync(ts->input);
    120}
    121
    122static irqreturn_t ektf2127_irq(int irq, void *dev_id)
    123{
    124	struct ektf2127_ts *ts = dev_id;
    125	struct device *dev = &ts->client->dev;
    126	char buf[EKTF2127_TOUCH_REPORT_SIZE];
    127	int ret;
    128
    129	ret = i2c_master_recv(ts->client, buf, EKTF2127_TOUCH_REPORT_SIZE);
    130	if (ret != EKTF2127_TOUCH_REPORT_SIZE) {
    131		dev_err(dev, "Error reading touch data: %d\n", ret);
    132		goto out;
    133	}
    134
    135	switch (buf[0]) {
    136	case EKTF2127_REPORT:
    137		ektf2127_report_event(ts, buf);
    138		break;
    139
    140	case EKTF2127_REPORT2:
    141		ektf2127_report2_event(ts, buf);
    142		break;
    143
    144	case EKTF2127_NOISE:
    145		if (buf[1] == EKTF2127_ENV_NOISY)
    146			dev_dbg(dev, "Environment is electrically noisy\n");
    147		break;
    148
    149	case EKTF2127_HELLO:
    150	case EKTF2127_CALIB_DONE:
    151		break;
    152
    153	default:
    154		dev_err(dev, "Unexpected packet header byte %#02x\n", buf[0]);
    155		break;
    156	}
    157
    158out:
    159	return IRQ_HANDLED;
    160}
    161
    162static int ektf2127_start(struct input_dev *dev)
    163{
    164	struct ektf2127_ts *ts = input_get_drvdata(dev);
    165
    166	enable_irq(ts->client->irq);
    167	gpiod_set_value_cansleep(ts->power_gpios, 1);
    168
    169	return 0;
    170}
    171
    172static void ektf2127_stop(struct input_dev *dev)
    173{
    174	struct ektf2127_ts *ts = input_get_drvdata(dev);
    175
    176	disable_irq(ts->client->irq);
    177	gpiod_set_value_cansleep(ts->power_gpios, 0);
    178}
    179
    180static int __maybe_unused ektf2127_suspend(struct device *dev)
    181{
    182	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
    183
    184	mutex_lock(&ts->input->mutex);
    185	if (input_device_enabled(ts->input))
    186		ektf2127_stop(ts->input);
    187	mutex_unlock(&ts->input->mutex);
    188
    189	return 0;
    190}
    191
    192static int __maybe_unused ektf2127_resume(struct device *dev)
    193{
    194	struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
    195
    196	mutex_lock(&ts->input->mutex);
    197	if (input_device_enabled(ts->input))
    198		ektf2127_start(ts->input);
    199	mutex_unlock(&ts->input->mutex);
    200
    201	return 0;
    202}
    203
    204static SIMPLE_DEV_PM_OPS(ektf2127_pm_ops, ektf2127_suspend,
    205			 ektf2127_resume);
    206
    207static int ektf2127_query_dimension(struct i2c_client *client, bool width)
    208{
    209	struct device *dev = &client->dev;
    210	const char *what = width ? "width" : "height";
    211	u8 what_code = width ? EKTF2127_WIDTH : EKTF2127_HEIGHT;
    212	u8 buf[4];
    213	int ret;
    214	int error;
    215
    216	/* Request dimension */
    217	buf[0] = EKTF2127_REQUEST;
    218	buf[1] = width ? EKTF2127_WIDTH : EKTF2127_HEIGHT;
    219	buf[2] = 0x00;
    220	buf[3] = 0x00;
    221	ret = i2c_master_send(client, buf, sizeof(buf));
    222	if (ret != sizeof(buf)) {
    223		error = ret < 0 ? ret : -EIO;
    224		dev_err(dev, "Failed to request %s: %d\n", what, error);
    225		return error;
    226	}
    227
    228	msleep(20);
    229
    230	/* Read response */
    231	ret = i2c_master_recv(client, buf, sizeof(buf));
    232	if (ret != sizeof(buf)) {
    233		error = ret < 0 ? ret : -EIO;
    234		dev_err(dev, "Failed to receive %s data: %d\n", what, error);
    235		return error;
    236	}
    237
    238	if (buf[0] != EKTF2127_RESPONSE || buf[1] != what_code) {
    239		dev_err(dev, "Unexpected %s data: %#02x %#02x\n",
    240			what, buf[0], buf[1]);
    241		return -EIO;
    242	}
    243
    244	return (((buf[3] & 0xf0) << 4) | buf[2]) - 1;
    245}
    246
    247static int ektf2127_probe(struct i2c_client *client,
    248			  const struct i2c_device_id *id)
    249{
    250	struct device *dev = &client->dev;
    251	struct ektf2127_ts *ts;
    252	struct input_dev *input;
    253	u8 buf[4];
    254	int max_x, max_y;
    255	int error;
    256
    257	if (!client->irq) {
    258		dev_err(dev, "Error no irq specified\n");
    259		return -EINVAL;
    260	}
    261
    262	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
    263	if (!ts)
    264		return -ENOMEM;
    265
    266	/* This requests the gpio *and* turns on the touchscreen controller */
    267	ts->power_gpios = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
    268	if (IS_ERR(ts->power_gpios)) {
    269		error = PTR_ERR(ts->power_gpios);
    270		if (error != -EPROBE_DEFER)
    271			dev_err(dev, "Error getting power gpio: %d\n", error);
    272		return error;
    273	}
    274
    275	input = devm_input_allocate_device(dev);
    276	if (!input)
    277		return -ENOMEM;
    278
    279	input->name = client->name;
    280	input->id.bustype = BUS_I2C;
    281	input->open = ektf2127_start;
    282	input->close = ektf2127_stop;
    283
    284	ts->client = client;
    285
    286	/* Read hello (ignore result, depends on initial power state) */
    287	msleep(20);
    288	i2c_master_recv(ts->client, buf, sizeof(buf));
    289
    290	/* Read resolution from chip */
    291	max_x = ektf2127_query_dimension(client, true);
    292	if (max_x < 0)
    293		return max_x;
    294
    295	max_y = ektf2127_query_dimension(client, false);
    296	if (max_y < 0)
    297		return max_y;
    298
    299	input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
    300	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
    301	touchscreen_parse_properties(input, true, &ts->prop);
    302
    303	error = input_mt_init_slots(input, EKTF2127_MAX_TOUCHES,
    304				    INPUT_MT_DIRECT |
    305					INPUT_MT_DROP_UNUSED |
    306					INPUT_MT_TRACK);
    307	if (error)
    308		return error;
    309
    310	ts->input = input;
    311	input_set_drvdata(input, ts);
    312
    313	error = devm_request_threaded_irq(dev, client->irq,
    314					  NULL, ektf2127_irq,
    315					  IRQF_ONESHOT, client->name, ts);
    316	if (error) {
    317		dev_err(dev, "Error requesting irq: %d\n", error);
    318		return error;
    319	}
    320
    321	/* Stop device till opened */
    322	ektf2127_stop(ts->input);
    323
    324	error = input_register_device(input);
    325	if (error)
    326		return error;
    327
    328	i2c_set_clientdata(client, ts);
    329
    330	return 0;
    331}
    332
    333#ifdef CONFIG_OF
    334static const struct of_device_id ektf2127_of_match[] = {
    335	{ .compatible = "elan,ektf2127" },
    336	{ .compatible = "elan,ektf2132" },
    337	{}
    338};
    339MODULE_DEVICE_TABLE(of, ektf2127_of_match);
    340#endif
    341
    342static const struct i2c_device_id ektf2127_i2c_id[] = {
    343	{ "ektf2127", 0 },
    344	{ "ektf2132", 0 },
    345	{}
    346};
    347MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
    348
    349static struct i2c_driver ektf2127_driver = {
    350	.driver = {
    351		.name	= "elan_ektf2127",
    352		.pm	= &ektf2127_pm_ops,
    353		.of_match_table = of_match_ptr(ektf2127_of_match),
    354	},
    355	.probe = ektf2127_probe,
    356	.id_table = ektf2127_i2c_id,
    357};
    358module_i2c_driver(ektf2127_driver);
    359
    360MODULE_DESCRIPTION("ELAN eKTF2127/eKTF2132 I2C Touchscreen Driver");
    361MODULE_AUTHOR("Michel Verlaan, Siebren Vroegindeweij");
    362MODULE_LICENSE("GPL");