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

rmi_f3a.c (6176B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2012-2020 Synaptics Incorporated
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/rmi.h>
      8#include <linux/input.h>
      9#include <linux/slab.h>
     10#include "rmi_driver.h"
     11
     12#define RMI_F3A_MAX_GPIO_COUNT		128
     13#define RMI_F3A_MAX_REG_SIZE		DIV_ROUND_UP(RMI_F3A_MAX_GPIO_COUNT, 8)
     14
     15/* Defs for Query 0 */
     16#define RMI_F3A_GPIO_COUNT		0x7F
     17
     18#define RMI_F3A_DATA_REGS_MAX_SIZE	RMI_F3A_MAX_REG_SIZE
     19
     20#define TRACKSTICK_RANGE_START		3
     21#define TRACKSTICK_RANGE_END		6
     22
     23struct f3a_data {
     24	/* Query Data */
     25	u8 gpio_count;
     26
     27	u8 register_count;
     28
     29	u8 data_regs[RMI_F3A_DATA_REGS_MAX_SIZE];
     30	u16 *gpio_key_map;
     31
     32	struct input_dev *input;
     33
     34	struct rmi_function *f03;
     35	bool trackstick_buttons;
     36};
     37
     38static void rmi_f3a_report_button(struct rmi_function *fn,
     39				  struct f3a_data *f3a, unsigned int button)
     40{
     41	u16 key_code = f3a->gpio_key_map[button];
     42	bool key_down = !(f3a->data_regs[0] & BIT(button));
     43
     44	if (f3a->trackstick_buttons &&
     45		button >= TRACKSTICK_RANGE_START &&
     46		button <= TRACKSTICK_RANGE_END) {
     47		rmi_f03_overwrite_button(f3a->f03, key_code, key_down);
     48	} else {
     49		rmi_dbg(RMI_DEBUG_FN, &fn->dev,
     50			"%s: call input report key (0x%04x) value (0x%02x)",
     51			__func__, key_code, key_down);
     52		input_report_key(f3a->input, key_code, key_down);
     53	}
     54}
     55
     56static irqreturn_t rmi_f3a_attention(int irq, void *ctx)
     57{
     58	struct rmi_function *fn = ctx;
     59	struct f3a_data *f3a = dev_get_drvdata(&fn->dev);
     60	struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
     61	int error;
     62	int i;
     63
     64	if (drvdata->attn_data.data) {
     65		if (drvdata->attn_data.size < f3a->register_count) {
     66			dev_warn(&fn->dev,
     67				 "F3A interrupted, but data is missing\n");
     68			return IRQ_HANDLED;
     69		}
     70		memcpy(f3a->data_regs, drvdata->attn_data.data,
     71			f3a->register_count);
     72		drvdata->attn_data.data += f3a->register_count;
     73		drvdata->attn_data.size -= f3a->register_count;
     74	} else {
     75		error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
     76					f3a->data_regs, f3a->register_count);
     77		if (error) {
     78			dev_err(&fn->dev,
     79				"%s: Failed to read F3a data registers: %d\n",
     80				__func__, error);
     81			return IRQ_RETVAL(error);
     82		}
     83	}
     84
     85	for (i = 0; i < f3a->gpio_count; i++)
     86		if (f3a->gpio_key_map[i] != KEY_RESERVED)
     87			rmi_f3a_report_button(fn, f3a, i);
     88	if (f3a->trackstick_buttons)
     89		rmi_f03_commit_buttons(f3a->f03);
     90
     91	return IRQ_HANDLED;
     92}
     93
     94static int rmi_f3a_config(struct rmi_function *fn)
     95{
     96	struct f3a_data *f3a = dev_get_drvdata(&fn->dev);
     97	struct rmi_driver *drv = fn->rmi_dev->driver;
     98	const struct rmi_device_platform_data *pdata =
     99			rmi_get_platform_data(fn->rmi_dev);
    100
    101	if (!f3a)
    102		return 0;
    103
    104	if (pdata->gpio_data.trackstick_buttons) {
    105		/* Try [re-]establish link to F03. */
    106		f3a->f03 = rmi_find_function(fn->rmi_dev, 0x03);
    107		f3a->trackstick_buttons = f3a->f03 != NULL;
    108	}
    109
    110	drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
    111
    112	return 0;
    113}
    114
    115static bool rmi_f3a_is_valid_button(int button, struct f3a_data *f3a,
    116					u8 *query1_regs, u8 *ctrl1_regs)
    117{
    118	/* gpio exist && direction input */
    119	return (query1_regs[0] & BIT(button)) && !(ctrl1_regs[0] & BIT(button));
    120}
    121
    122static int rmi_f3a_map_gpios(struct rmi_function *fn, struct f3a_data *f3a,
    123				u8 *query1_regs, u8 *ctrl1_regs)
    124{
    125	const struct rmi_device_platform_data *pdata =
    126			rmi_get_platform_data(fn->rmi_dev);
    127	struct input_dev *input = f3a->input;
    128	unsigned int button = BTN_LEFT;
    129	unsigned int trackstick_button = BTN_LEFT;
    130	bool button_mapped = false;
    131	int i;
    132	int button_count = min_t(u8, f3a->gpio_count, TRACKSTICK_RANGE_END);
    133
    134	f3a->gpio_key_map = devm_kcalloc(&fn->dev,
    135						button_count,
    136						sizeof(f3a->gpio_key_map[0]),
    137						GFP_KERNEL);
    138	if (!f3a->gpio_key_map) {
    139		dev_err(&fn->dev, "Failed to allocate gpio map memory.\n");
    140		return -ENOMEM;
    141	}
    142
    143	for (i = 0; i < button_count; i++) {
    144		if (!rmi_f3a_is_valid_button(i, f3a, query1_regs, ctrl1_regs))
    145			continue;
    146
    147		if (pdata->gpio_data.trackstick_buttons &&
    148			i >= TRACKSTICK_RANGE_START &&
    149			i < TRACKSTICK_RANGE_END) {
    150			f3a->gpio_key_map[i] = trackstick_button++;
    151		} else if (!pdata->gpio_data.buttonpad || !button_mapped) {
    152			f3a->gpio_key_map[i] = button;
    153			input_set_capability(input, EV_KEY, button++);
    154			button_mapped = true;
    155		}
    156	}
    157	input->keycode = f3a->gpio_key_map;
    158	input->keycodesize = sizeof(f3a->gpio_key_map[0]);
    159	input->keycodemax = f3a->gpio_count;
    160
    161	if (pdata->gpio_data.buttonpad || (button - BTN_LEFT == 1))
    162		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
    163
    164	return 0;
    165}
    166
    167static int rmi_f3a_initialize(struct rmi_function *fn, struct f3a_data *f3a)
    168{
    169	u8 query1[RMI_F3A_MAX_REG_SIZE];
    170	u8 ctrl1[RMI_F3A_MAX_REG_SIZE];
    171	u8 buf;
    172	int error;
    173
    174	error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &buf);
    175	if (error < 0) {
    176		dev_err(&fn->dev, "Failed to read general info register: %d\n",
    177			error);
    178		return -ENODEV;
    179	}
    180
    181	f3a->gpio_count = buf & RMI_F3A_GPIO_COUNT;
    182	f3a->register_count = DIV_ROUND_UP(f3a->gpio_count, 8);
    183
    184	/* Query1 -> gpio exist */
    185	error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1,
    186				query1, f3a->register_count);
    187	if (error) {
    188		dev_err(&fn->dev, "Failed to read query1 register\n");
    189		return error;
    190	}
    191
    192	/* Ctrl1 -> gpio direction */
    193	error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr + 1,
    194				ctrl1, f3a->register_count);
    195	if (error) {
    196		dev_err(&fn->dev, "Failed to read control1 register\n");
    197		return error;
    198	}
    199
    200	error = rmi_f3a_map_gpios(fn, f3a, query1, ctrl1);
    201	if (error)
    202		return error;
    203
    204	return 0;
    205}
    206
    207static int rmi_f3a_probe(struct rmi_function *fn)
    208{
    209	struct rmi_device *rmi_dev = fn->rmi_dev;
    210	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
    211	struct f3a_data *f3a;
    212	int error;
    213
    214	if (!drv_data->input) {
    215		dev_info(&fn->dev, "F3A: no input device found, ignoring\n");
    216		return -ENXIO;
    217	}
    218
    219	f3a = devm_kzalloc(&fn->dev, sizeof(*f3a), GFP_KERNEL);
    220	if (!f3a)
    221		return -ENOMEM;
    222
    223	f3a->input = drv_data->input;
    224
    225	error = rmi_f3a_initialize(fn, f3a);
    226	if (error)
    227		return error;
    228
    229	dev_set_drvdata(&fn->dev, f3a);
    230	return 0;
    231}
    232
    233struct rmi_function_handler rmi_f3a_handler = {
    234	.driver = {
    235		.name = "rmi4_f3a",
    236	},
    237	.func = 0x3a,
    238	.probe = rmi_f3a_probe,
    239	.config = rmi_f3a_config,
    240	.attention = rmi_f3a_attention,
    241};