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