Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2012-2015 Synaptics Incorporated
0004  * Copyright (C) 2016 Zodiac Inflight Innovations
0005  */
0006 
0007 #include <linux/bitops.h>
0008 #include <linux/kernel.h>
0009 #include <linux/rmi.h>
0010 #include <linux/slab.h>
0011 #include "rmi_driver.h"
0012 
0013 #define F55_NAME        "rmi4_f55"
0014 
0015 /* F55 data offsets */
0016 #define F55_NUM_RX_OFFSET   0
0017 #define F55_NUM_TX_OFFSET   1
0018 #define F55_PHYS_CHAR_OFFSET    2
0019 
0020 /* Only read required query registers */
0021 #define F55_QUERY_LEN       3
0022 
0023 /* F55 capabilities */
0024 #define F55_CAP_SENSOR_ASSIGN   BIT(0)
0025 
0026 struct f55_data {
0027     struct rmi_function *fn;
0028 
0029     u8 qry[F55_QUERY_LEN];
0030     u8 num_rx_electrodes;
0031     u8 cfg_num_rx_electrodes;
0032     u8 num_tx_electrodes;
0033     u8 cfg_num_tx_electrodes;
0034 };
0035 
0036 static int rmi_f55_detect(struct rmi_function *fn)
0037 {
0038     struct rmi_device *rmi_dev = fn->rmi_dev;
0039     struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
0040     struct f55_data *f55;
0041     int error;
0042 
0043     f55 = dev_get_drvdata(&fn->dev);
0044 
0045     error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
0046                    &f55->qry, sizeof(f55->qry));
0047     if (error) {
0048         dev_err(&fn->dev, "%s: Failed to query F55 properties\n",
0049             __func__);
0050         return error;
0051     }
0052 
0053     f55->num_rx_electrodes = f55->qry[F55_NUM_RX_OFFSET];
0054     f55->num_tx_electrodes = f55->qry[F55_NUM_TX_OFFSET];
0055 
0056     f55->cfg_num_rx_electrodes = f55->num_rx_electrodes;
0057     f55->cfg_num_tx_electrodes = f55->num_rx_electrodes;
0058 
0059     drv_data->num_rx_electrodes = f55->cfg_num_rx_electrodes;
0060     drv_data->num_tx_electrodes = f55->cfg_num_rx_electrodes;
0061 
0062     if (f55->qry[F55_PHYS_CHAR_OFFSET] & F55_CAP_SENSOR_ASSIGN) {
0063         int i, total;
0064         u8 buf[256];
0065 
0066         /*
0067          * Calculate the number of enabled receive and transmit
0068          * electrodes by reading F55:Ctrl1 (sensor receiver assignment)
0069          * and F55:Ctrl2 (sensor transmitter assignment). The number of
0070          * enabled electrodes is the sum of all field entries with a
0071          * value other than 0xff.
0072          */
0073         error = rmi_read_block(fn->rmi_dev,
0074                        fn->fd.control_base_addr + 1,
0075                        buf, f55->num_rx_electrodes);
0076         if (!error) {
0077             total = 0;
0078             for (i = 0; i < f55->num_rx_electrodes; i++) {
0079                 if (buf[i] != 0xff)
0080                     total++;
0081             }
0082             f55->cfg_num_rx_electrodes = total;
0083             drv_data->num_rx_electrodes = total;
0084         }
0085 
0086         error = rmi_read_block(fn->rmi_dev,
0087                        fn->fd.control_base_addr + 2,
0088                        buf, f55->num_tx_electrodes);
0089         if (!error) {
0090             total = 0;
0091             for (i = 0; i < f55->num_tx_electrodes; i++) {
0092                 if (buf[i] != 0xff)
0093                     total++;
0094             }
0095             f55->cfg_num_tx_electrodes = total;
0096             drv_data->num_tx_electrodes = total;
0097         }
0098     }
0099 
0100     rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_rx_electrodes: %d (raw %d)\n",
0101         f55->cfg_num_rx_electrodes, f55->num_rx_electrodes);
0102     rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_tx_electrodes: %d (raw %d)\n",
0103         f55->cfg_num_tx_electrodes, f55->num_tx_electrodes);
0104 
0105     return 0;
0106 }
0107 
0108 static int rmi_f55_probe(struct rmi_function *fn)
0109 {
0110     struct f55_data *f55;
0111 
0112     f55 = devm_kzalloc(&fn->dev, sizeof(struct f55_data), GFP_KERNEL);
0113     if (!f55)
0114         return -ENOMEM;
0115 
0116     f55->fn = fn;
0117     dev_set_drvdata(&fn->dev, f55);
0118 
0119     return rmi_f55_detect(fn);
0120 }
0121 
0122 struct rmi_function_handler rmi_f55_handler = {
0123     .driver = {
0124         .name = F55_NAME,
0125     },
0126     .func = 0x55,
0127     .probe = rmi_f55_probe,
0128 };