1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2012-2015 Synaptics Incorporated
4*4882a593Smuzhiyun * Copyright (C) 2016 Zodiac Inflight Innovations
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/bitops.h>
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/rmi.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include "rmi_driver.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define F55_NAME "rmi4_f55"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /* F55 data offsets */
16*4882a593Smuzhiyun #define F55_NUM_RX_OFFSET 0
17*4882a593Smuzhiyun #define F55_NUM_TX_OFFSET 1
18*4882a593Smuzhiyun #define F55_PHYS_CHAR_OFFSET 2
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* Only read required query registers */
21*4882a593Smuzhiyun #define F55_QUERY_LEN 3
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* F55 capabilities */
24*4882a593Smuzhiyun #define F55_CAP_SENSOR_ASSIGN BIT(0)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun struct f55_data {
27*4882a593Smuzhiyun struct rmi_function *fn;
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun u8 qry[F55_QUERY_LEN];
30*4882a593Smuzhiyun u8 num_rx_electrodes;
31*4882a593Smuzhiyun u8 cfg_num_rx_electrodes;
32*4882a593Smuzhiyun u8 num_tx_electrodes;
33*4882a593Smuzhiyun u8 cfg_num_tx_electrodes;
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
rmi_f55_detect(struct rmi_function * fn)36*4882a593Smuzhiyun static int rmi_f55_detect(struct rmi_function *fn)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun struct rmi_device *rmi_dev = fn->rmi_dev;
39*4882a593Smuzhiyun struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
40*4882a593Smuzhiyun struct f55_data *f55;
41*4882a593Smuzhiyun int error;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun f55 = dev_get_drvdata(&fn->dev);
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
46*4882a593Smuzhiyun &f55->qry, sizeof(f55->qry));
47*4882a593Smuzhiyun if (error) {
48*4882a593Smuzhiyun dev_err(&fn->dev, "%s: Failed to query F55 properties\n",
49*4882a593Smuzhiyun __func__);
50*4882a593Smuzhiyun return error;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun f55->num_rx_electrodes = f55->qry[F55_NUM_RX_OFFSET];
54*4882a593Smuzhiyun f55->num_tx_electrodes = f55->qry[F55_NUM_TX_OFFSET];
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun f55->cfg_num_rx_electrodes = f55->num_rx_electrodes;
57*4882a593Smuzhiyun f55->cfg_num_tx_electrodes = f55->num_rx_electrodes;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun drv_data->num_rx_electrodes = f55->cfg_num_rx_electrodes;
60*4882a593Smuzhiyun drv_data->num_tx_electrodes = f55->cfg_num_rx_electrodes;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun if (f55->qry[F55_PHYS_CHAR_OFFSET] & F55_CAP_SENSOR_ASSIGN) {
63*4882a593Smuzhiyun int i, total;
64*4882a593Smuzhiyun u8 buf[256];
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun * Calculate the number of enabled receive and transmit
68*4882a593Smuzhiyun * electrodes by reading F55:Ctrl1 (sensor receiver assignment)
69*4882a593Smuzhiyun * and F55:Ctrl2 (sensor transmitter assignment). The number of
70*4882a593Smuzhiyun * enabled electrodes is the sum of all field entries with a
71*4882a593Smuzhiyun * value other than 0xff.
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun error = rmi_read_block(fn->rmi_dev,
74*4882a593Smuzhiyun fn->fd.control_base_addr + 1,
75*4882a593Smuzhiyun buf, f55->num_rx_electrodes);
76*4882a593Smuzhiyun if (!error) {
77*4882a593Smuzhiyun total = 0;
78*4882a593Smuzhiyun for (i = 0; i < f55->num_rx_electrodes; i++) {
79*4882a593Smuzhiyun if (buf[i] != 0xff)
80*4882a593Smuzhiyun total++;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun f55->cfg_num_rx_electrodes = total;
83*4882a593Smuzhiyun drv_data->num_rx_electrodes = total;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun error = rmi_read_block(fn->rmi_dev,
87*4882a593Smuzhiyun fn->fd.control_base_addr + 2,
88*4882a593Smuzhiyun buf, f55->num_tx_electrodes);
89*4882a593Smuzhiyun if (!error) {
90*4882a593Smuzhiyun total = 0;
91*4882a593Smuzhiyun for (i = 0; i < f55->num_tx_electrodes; i++) {
92*4882a593Smuzhiyun if (buf[i] != 0xff)
93*4882a593Smuzhiyun total++;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun f55->cfg_num_tx_electrodes = total;
96*4882a593Smuzhiyun drv_data->num_tx_electrodes = total;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_rx_electrodes: %d (raw %d)\n",
101*4882a593Smuzhiyun f55->cfg_num_rx_electrodes, f55->num_rx_electrodes);
102*4882a593Smuzhiyun rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_tx_electrodes: %d (raw %d)\n",
103*4882a593Smuzhiyun f55->cfg_num_tx_electrodes, f55->num_tx_electrodes);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun return 0;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
rmi_f55_probe(struct rmi_function * fn)108*4882a593Smuzhiyun static int rmi_f55_probe(struct rmi_function *fn)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun struct f55_data *f55;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun f55 = devm_kzalloc(&fn->dev, sizeof(struct f55_data), GFP_KERNEL);
113*4882a593Smuzhiyun if (!f55)
114*4882a593Smuzhiyun return -ENOMEM;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun f55->fn = fn;
117*4882a593Smuzhiyun dev_set_drvdata(&fn->dev, f55);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun return rmi_f55_detect(fn);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun struct rmi_function_handler rmi_f55_handler = {
123*4882a593Smuzhiyun .driver = {
124*4882a593Smuzhiyun .name = F55_NAME,
125*4882a593Smuzhiyun },
126*4882a593Smuzhiyun .func = 0x55,
127*4882a593Smuzhiyun .probe = rmi_f55_probe,
128*4882a593Smuzhiyun };
129