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 f55_data *f55; 42 int error; 43 44 f55 = dev_get_drvdata(&fn->dev); 45 46 error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, 47 &f55->qry, sizeof(f55->qry)); 48 if (error) { 49 dev_err(&fn->dev, "%s: Failed to query F55 properties\n", 50 __func__); 51 return error; 52 } 53 54 f55->num_rx_electrodes = f55->qry[F55_NUM_RX_OFFSET]; 55 f55->num_tx_electrodes = f55->qry[F55_NUM_TX_OFFSET]; 56 57 f55->cfg_num_rx_electrodes = f55->num_rx_electrodes; 58 f55->cfg_num_tx_electrodes = f55->num_rx_electrodes; 59 60 if (f55->qry[F55_PHYS_CHAR_OFFSET] & F55_CAP_SENSOR_ASSIGN) { 61 int i, total; 62 u8 buf[256]; 63 64 /* 65 * Calculate the number of enabled receive and transmit 66 * electrodes by reading F55:Ctrl1 (sensor receiver assignment) 67 * and F55:Ctrl2 (sensor transmitter assignment). The number of 68 * enabled electrodes is the sum of all field entries with a 69 * value other than 0xff. 70 */ 71 error = rmi_read_block(fn->rmi_dev, 72 fn->fd.control_base_addr + 1, 73 buf, f55->num_rx_electrodes); 74 if (!error) { 75 total = 0; 76 for (i = 0; i < f55->num_rx_electrodes; i++) { 77 if (buf[i] != 0xff) 78 total++; 79 } 80 f55->cfg_num_rx_electrodes = total; 81 } 82 83 error = rmi_read_block(fn->rmi_dev, 84 fn->fd.control_base_addr + 2, 85 buf, f55->num_tx_electrodes); 86 if (!error) { 87 total = 0; 88 for (i = 0; i < f55->num_tx_electrodes; i++) { 89 if (buf[i] != 0xff) 90 total++; 91 } 92 f55->cfg_num_tx_electrodes = total; 93 } 94 } 95 96 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_rx_electrodes: %d (raw %d)\n", 97 f55->cfg_num_rx_electrodes, f55->num_rx_electrodes); 98 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F55 num_tx_electrodes: %d (raw %d)\n", 99 f55->cfg_num_tx_electrodes, f55->num_tx_electrodes); 100 101 return 0; 102 } 103 104 static int rmi_f55_probe(struct rmi_function *fn) 105 { 106 struct f55_data *f55; 107 108 f55 = devm_kzalloc(&fn->dev, sizeof(struct f55_data), GFP_KERNEL); 109 if (!f55) 110 return -ENOMEM; 111 112 f55->fn = fn; 113 dev_set_drvdata(&fn->dev, f55); 114 115 return rmi_f55_detect(fn); 116 } 117 118 struct rmi_function_handler rmi_f55_handler = { 119 .driver = { 120 .name = F55_NAME, 121 }, 122 .func = 0x55, 123 .probe = rmi_f55_probe, 124 }; 125