xref: /openbmc/linux/drivers/input/rmi4/rmi_f55.c (revision d2912cb1)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
26adba43fSGuenter Roeck /*
36adba43fSGuenter Roeck  * Copyright (c) 2012-2015 Synaptics Incorporated
46adba43fSGuenter Roeck  * Copyright (C) 2016 Zodiac Inflight Innovations
56adba43fSGuenter Roeck  */
66adba43fSGuenter Roeck 
76adba43fSGuenter Roeck #include <linux/bitops.h>
86adba43fSGuenter Roeck #include <linux/kernel.h>
96adba43fSGuenter Roeck #include <linux/rmi.h>
106adba43fSGuenter Roeck #include <linux/slab.h>
116adba43fSGuenter Roeck #include "rmi_driver.h"
126adba43fSGuenter Roeck 
136adba43fSGuenter Roeck #define F55_NAME		"rmi4_f55"
146adba43fSGuenter Roeck 
156adba43fSGuenter Roeck /* F55 data offsets */
166adba43fSGuenter Roeck #define F55_NUM_RX_OFFSET	0
176adba43fSGuenter Roeck #define F55_NUM_TX_OFFSET	1
186adba43fSGuenter Roeck #define F55_PHYS_CHAR_OFFSET	2
196adba43fSGuenter Roeck 
206adba43fSGuenter Roeck /* Only read required query registers */
216adba43fSGuenter Roeck #define F55_QUERY_LEN		3
226adba43fSGuenter Roeck 
236adba43fSGuenter Roeck /* F55 capabilities */
246adba43fSGuenter Roeck #define F55_CAP_SENSOR_ASSIGN	BIT(0)
256adba43fSGuenter Roeck 
266adba43fSGuenter Roeck struct f55_data {
276adba43fSGuenter Roeck 	struct rmi_function *fn;
286adba43fSGuenter Roeck 
296adba43fSGuenter Roeck 	u8 qry[F55_QUERY_LEN];
306adba43fSGuenter Roeck 	u8 num_rx_electrodes;
316adba43fSGuenter Roeck 	u8 cfg_num_rx_electrodes;
326adba43fSGuenter Roeck 	u8 num_tx_electrodes;
336adba43fSGuenter Roeck 	u8 cfg_num_tx_electrodes;
346adba43fSGuenter Roeck };
356adba43fSGuenter Roeck 
rmi_f55_detect(struct rmi_function * fn)366adba43fSGuenter Roeck static int rmi_f55_detect(struct rmi_function *fn)
376adba43fSGuenter Roeck {
38c762cc68SGuenter Roeck 	struct rmi_device *rmi_dev = fn->rmi_dev;
39c762cc68SGuenter Roeck 	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
406adba43fSGuenter Roeck 	struct f55_data *f55;
416adba43fSGuenter Roeck 	int error;
426adba43fSGuenter Roeck 
436adba43fSGuenter Roeck 	f55 = dev_get_drvdata(&fn->dev);
446adba43fSGuenter Roeck 
456adba43fSGuenter Roeck 	error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
466adba43fSGuenter Roeck 			       &f55->qry, sizeof(f55->qry));
476adba43fSGuenter Roeck 	if (error) {
486adba43fSGuenter Roeck 		dev_err(&fn->dev, "%s: Failed to query F55 properties\n",
496adba43fSGuenter Roeck 			__func__);
506adba43fSGuenter Roeck 		return error;
516adba43fSGuenter Roeck 	}
526adba43fSGuenter Roeck 
536adba43fSGuenter Roeck 	f55->num_rx_electrodes = f55->qry[F55_NUM_RX_OFFSET];
546adba43fSGuenter Roeck 	f55->num_tx_electrodes = f55->qry[F55_NUM_TX_OFFSET];
556adba43fSGuenter Roeck 
566adba43fSGuenter Roeck 	f55->cfg_num_rx_electrodes = f55->num_rx_electrodes;
576adba43fSGuenter Roeck 	f55->cfg_num_tx_electrodes = f55->num_rx_electrodes;
586adba43fSGuenter Roeck 
59c762cc68SGuenter Roeck 	drv_data->num_rx_electrodes = f55->cfg_num_rx_electrodes;
60c762cc68SGuenter Roeck 	drv_data->num_tx_electrodes = f55->cfg_num_rx_electrodes;
61c762cc68SGuenter Roeck 
626adba43fSGuenter Roeck 	if (f55->qry[F55_PHYS_CHAR_OFFSET] & F55_CAP_SENSOR_ASSIGN) {
636adba43fSGuenter Roeck 		int i, total;
646adba43fSGuenter Roeck 		u8 buf[256];
656adba43fSGuenter Roeck 
666adba43fSGuenter Roeck 		/*
676adba43fSGuenter Roeck 		 * Calculate the number of enabled receive and transmit
686adba43fSGuenter Roeck 		 * electrodes by reading F55:Ctrl1 (sensor receiver assignment)
696adba43fSGuenter Roeck 		 * and F55:Ctrl2 (sensor transmitter assignment). The number of
706adba43fSGuenter Roeck 		 * enabled electrodes is the sum of all field entries with a
716adba43fSGuenter Roeck 		 * value other than 0xff.
726adba43fSGuenter Roeck 		 */
736adba43fSGuenter Roeck 		error = rmi_read_block(fn->rmi_dev,
746adba43fSGuenter Roeck 				       fn->fd.control_base_addr + 1,
756adba43fSGuenter Roeck 				       buf, f55->num_rx_electrodes);
766adba43fSGuenter Roeck 		if (!error) {
776adba43fSGuenter Roeck 			total = 0;
786adba43fSGuenter Roeck 			for (i = 0; i < f55->num_rx_electrodes; i++) {
796adba43fSGuenter Roeck 				if (buf[i] != 0xff)
806adba43fSGuenter Roeck 					total++;
816adba43fSGuenter Roeck 			}
826adba43fSGuenter Roeck 			f55->cfg_num_rx_electrodes = total;
83c762cc68SGuenter Roeck 			drv_data->num_rx_electrodes = total;
846adba43fSGuenter Roeck 		}
856adba43fSGuenter Roeck 
866adba43fSGuenter Roeck 		error = rmi_read_block(fn->rmi_dev,
876adba43fSGuenter Roeck 				       fn->fd.control_base_addr + 2,
886adba43fSGuenter Roeck 				       buf, f55->num_tx_electrodes);
896adba43fSGuenter Roeck 		if (!error) {
906adba43fSGuenter Roeck 			total = 0;
916adba43fSGuenter Roeck 			for (i = 0; i < f55->num_tx_electrodes; i++) {
926adba43fSGuenter Roeck 				if (buf[i] != 0xff)
936adba43fSGuenter Roeck 					total++;
946adba43fSGuenter Roeck 			}
956adba43fSGuenter Roeck 			f55->cfg_num_tx_electrodes = total;
96c762cc68SGuenter Roeck 			drv_data->num_tx_electrodes = total;
976adba43fSGuenter Roeck 		}
986adba43fSGuenter Roeck 	}
996adba43fSGuenter Roeck 
1006adba43fSGuenter Roeck 	rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_rx_electrodes: %d (raw %d)\n",
1016adba43fSGuenter Roeck 		f55->cfg_num_rx_electrodes, f55->num_rx_electrodes);
1026adba43fSGuenter Roeck 	rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_tx_electrodes: %d (raw %d)\n",
1036adba43fSGuenter Roeck 		f55->cfg_num_tx_electrodes, f55->num_tx_electrodes);
1046adba43fSGuenter Roeck 
1056adba43fSGuenter Roeck 	return 0;
1066adba43fSGuenter Roeck }
1076adba43fSGuenter Roeck 
rmi_f55_probe(struct rmi_function * fn)1086adba43fSGuenter Roeck static int rmi_f55_probe(struct rmi_function *fn)
1096adba43fSGuenter Roeck {
1106adba43fSGuenter Roeck 	struct f55_data *f55;
1116adba43fSGuenter Roeck 
1126adba43fSGuenter Roeck 	f55 = devm_kzalloc(&fn->dev, sizeof(struct f55_data), GFP_KERNEL);
1136adba43fSGuenter Roeck 	if (!f55)
1146adba43fSGuenter Roeck 		return -ENOMEM;
1156adba43fSGuenter Roeck 
1166adba43fSGuenter Roeck 	f55->fn = fn;
1176adba43fSGuenter Roeck 	dev_set_drvdata(&fn->dev, f55);
1186adba43fSGuenter Roeck 
1196adba43fSGuenter Roeck 	return rmi_f55_detect(fn);
1206adba43fSGuenter Roeck }
1216adba43fSGuenter Roeck 
1226adba43fSGuenter Roeck struct rmi_function_handler rmi_f55_handler = {
1236adba43fSGuenter Roeck 	.driver = {
1246adba43fSGuenter Roeck 		.name = F55_NAME,
1256adba43fSGuenter Roeck 	},
1266adba43fSGuenter Roeck 	.func = 0x55,
1276adba43fSGuenter Roeck 	.probe = rmi_f55_probe,
1286adba43fSGuenter Roeck };
129