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