1 /* 2 * Atmel Atmegaxx Capacitive Touch Button Driver 3 * 4 * Copyright (C) 2016 Google, inc. 5 * 6 * This software is licensed under the terms of the GNU General Public 7 * License version 2, as published by the Free Software Foundation, and 8 * may be copied, distributed, and modified under those terms. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16 /* 17 * It's irrelevant that the HW used to develop captouch driver is based 18 * on Atmega88PA part and uses QtouchADC parts for sensing touch. 19 * Calling this driver "captouch" is an arbitrary way to distinguish 20 * the protocol this driver supported by other atmel/qtouch drivers. 21 * 22 * Captouch driver supports a newer/different version of the I2C 23 * registers/commands than the qt1070.c driver. 24 * Don't let the similarity of the general driver structure fool you. 25 * 26 * For raw i2c access from userspace, use i2cset/i2cget 27 * to poke at /dev/i2c-N devices. 28 */ 29 30 #include <linux/device.h> 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/init.h> 34 #include <linux/i2c.h> 35 #include <linux/input.h> 36 #include <linux/interrupt.h> 37 #include <linux/slab.h> 38 39 /* Maximum number of buttons supported */ 40 #define MAX_NUM_OF_BUTTONS 8 41 42 /* Registers */ 43 #define REG_KEY1_THRESHOLD 0x02 44 #define REG_KEY2_THRESHOLD 0x03 45 #define REG_KEY3_THRESHOLD 0x04 46 #define REG_KEY4_THRESHOLD 0x05 47 48 #define REG_KEY1_REF_H 0x20 49 #define REG_KEY1_REF_L 0x21 50 #define REG_KEY2_REF_H 0x22 51 #define REG_KEY2_REF_L 0x23 52 #define REG_KEY3_REF_H 0x24 53 #define REG_KEY3_REF_L 0x25 54 #define REG_KEY4_REF_H 0x26 55 #define REG_KEY4_REF_L 0x27 56 57 #define REG_KEY1_DLT_H 0x30 58 #define REG_KEY1_DLT_L 0x31 59 #define REG_KEY2_DLT_H 0x32 60 #define REG_KEY2_DLT_L 0x33 61 #define REG_KEY3_DLT_H 0x34 62 #define REG_KEY3_DLT_L 0x35 63 #define REG_KEY4_DLT_H 0x36 64 #define REG_KEY4_DLT_L 0x37 65 66 #define REG_KEY_STATE 0x3C 67 68 /* 69 * @i2c_client: I2C slave device client pointer 70 * @input: Input device pointer 71 * @num_btn: Number of buttons 72 * @keycodes: map of button# to KeyCode 73 * @prev_btn: Previous key state to detect button "press" or "release" 74 * @xfer_buf: I2C transfer buffer 75 */ 76 struct atmel_captouch_device { 77 struct i2c_client *client; 78 struct input_dev *input; 79 u32 num_btn; 80 u32 keycodes[MAX_NUM_OF_BUTTONS]; 81 u8 prev_btn; 82 u8 xfer_buf[8] ____cacheline_aligned; 83 }; 84 85 /* 86 * Read from I2C slave device 87 * The protocol is that the client has to provide both the register address 88 * and the length, and while reading back the device would prepend the data 89 * with address and length for verification. 90 */ 91 static int atmel_read(struct atmel_captouch_device *capdev, 92 u8 reg, u8 *data, size_t len) 93 { 94 struct i2c_client *client = capdev->client; 95 struct device *dev = &client->dev; 96 struct i2c_msg msg[2]; 97 int err; 98 99 if (len > sizeof(capdev->xfer_buf) - 2) 100 return -EINVAL; 101 102 capdev->xfer_buf[0] = reg; 103 capdev->xfer_buf[1] = len; 104 105 msg[0].addr = client->addr; 106 msg[0].flags = 0; 107 msg[0].buf = capdev->xfer_buf; 108 msg[0].len = 2; 109 110 msg[1].addr = client->addr; 111 msg[1].flags = I2C_M_RD; 112 msg[1].buf = capdev->xfer_buf; 113 msg[1].len = len + 2; 114 115 err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 116 if (err != ARRAY_SIZE(msg)) 117 return err < 0 ? err : -EIO; 118 119 if (capdev->xfer_buf[0] != reg) { 120 dev_err(dev, 121 "I2C read error: register address does not match (%#02x vs %02x)\n", 122 capdev->xfer_buf[0], reg); 123 return -ECOMM; 124 } 125 126 memcpy(data, &capdev->xfer_buf[2], len); 127 128 return 0; 129 } 130 131 /* 132 * Handle interrupt and report the key changes to the input system. 133 * Multi-touch can be supported; however, it really depends on whether 134 * the device can multi-touch. 135 */ 136 static irqreturn_t atmel_captouch_isr(int irq, void *data) 137 { 138 struct atmel_captouch_device *capdev = data; 139 struct device *dev = &capdev->client->dev; 140 int error; 141 int i; 142 u8 new_btn; 143 u8 changed_btn; 144 145 error = atmel_read(capdev, REG_KEY_STATE, &new_btn, 1); 146 if (error) { 147 dev_err(dev, "failed to read button state: %d\n", error); 148 goto out; 149 } 150 151 dev_dbg(dev, "%s: button state %#02x\n", __func__, new_btn); 152 153 changed_btn = new_btn ^ capdev->prev_btn; 154 capdev->prev_btn = new_btn; 155 156 for (i = 0; i < capdev->num_btn; i++) { 157 if (changed_btn & BIT(i)) 158 input_report_key(capdev->input, 159 capdev->keycodes[i], 160 new_btn & BIT(i)); 161 } 162 163 input_sync(capdev->input); 164 165 out: 166 return IRQ_HANDLED; 167 } 168 169 /* 170 * Probe function to setup the device, input system and interrupt 171 */ 172 static int atmel_captouch_probe(struct i2c_client *client, 173 const struct i2c_device_id *id) 174 { 175 struct atmel_captouch_device *capdev; 176 struct device *dev = &client->dev; 177 struct device_node *node; 178 int i; 179 int err; 180 181 if (!i2c_check_functionality(client->adapter, 182 I2C_FUNC_SMBUS_BYTE_DATA | 183 I2C_FUNC_SMBUS_WORD_DATA | 184 I2C_FUNC_SMBUS_I2C_BLOCK)) { 185 dev_err(dev, "needed i2c functionality is not supported\n"); 186 return -EINVAL; 187 } 188 189 capdev = devm_kzalloc(dev, sizeof(*capdev), GFP_KERNEL); 190 if (!capdev) 191 return -ENOMEM; 192 193 capdev->client = client; 194 195 err = atmel_read(capdev, REG_KEY_STATE, 196 &capdev->prev_btn, sizeof(capdev->prev_btn)); 197 if (err) { 198 dev_err(dev, "failed to read initial button state: %d\n", err); 199 return err; 200 } 201 202 capdev->input = devm_input_allocate_device(dev); 203 if (!capdev->input) { 204 dev_err(dev, "failed to allocate input device\n"); 205 return -ENOMEM; 206 } 207 208 capdev->input->id.bustype = BUS_I2C; 209 capdev->input->id.product = 0x880A; 210 capdev->input->id.version = 0; 211 capdev->input->name = "ATMegaXX Capacitive Button Controller"; 212 __set_bit(EV_KEY, capdev->input->evbit); 213 214 node = dev->of_node; 215 if (!node) { 216 dev_err(dev, "failed to find matching node in device tree\n"); 217 return -EINVAL; 218 } 219 220 if (of_property_read_bool(node, "autorepeat")) 221 __set_bit(EV_REP, capdev->input->evbit); 222 223 capdev->num_btn = of_property_count_u32_elems(node, "linux,keymap"); 224 if (capdev->num_btn > MAX_NUM_OF_BUTTONS) 225 capdev->num_btn = MAX_NUM_OF_BUTTONS; 226 227 err = of_property_read_u32_array(node, "linux,keycodes", 228 capdev->keycodes, 229 capdev->num_btn); 230 if (err) { 231 dev_err(dev, 232 "failed to read linux,keycode property: %d\n", err); 233 return err; 234 } 235 236 for (i = 0; i < capdev->num_btn; i++) 237 __set_bit(capdev->keycodes[i], capdev->input->keybit); 238 239 capdev->input->keycode = capdev->keycodes; 240 capdev->input->keycodesize = sizeof(capdev->keycodes[0]); 241 capdev->input->keycodemax = capdev->num_btn; 242 243 err = input_register_device(capdev->input); 244 if (err) 245 return err; 246 247 err = devm_request_threaded_irq(dev, client->irq, 248 NULL, atmel_captouch_isr, 249 IRQF_ONESHOT, 250 "atmel_captouch", capdev); 251 if (err) { 252 dev_err(dev, "failed to request irq %d: %d\n", 253 client->irq, err); 254 return err; 255 } 256 257 return 0; 258 } 259 260 #ifdef CONFIG_OF 261 static const struct of_device_id atmel_captouch_of_id[] = { 262 { 263 .compatible = "atmel,captouch", 264 }, 265 { /* sentinel */ } 266 }; 267 MODULE_DEVICE_TABLE(of, atmel_captouch_of_id); 268 #endif 269 270 static const struct i2c_device_id atmel_captouch_id[] = { 271 { "atmel_captouch", 0 }, 272 { } 273 }; 274 MODULE_DEVICE_TABLE(i2c, atmel_captouch_id); 275 276 static struct i2c_driver atmel_captouch_driver = { 277 .probe = atmel_captouch_probe, 278 .id_table = atmel_captouch_id, 279 .driver = { 280 .name = "atmel_captouch", 281 .of_match_table = of_match_ptr(atmel_captouch_of_id), 282 }, 283 }; 284 module_i2c_driver(atmel_captouch_driver); 285 286 /* Module information */ 287 MODULE_AUTHOR("Hung-yu Wu <hywu@google.com>"); 288 MODULE_DESCRIPTION("Atmel ATmegaXX Capacitance Touch Sensor I2C Driver"); 289 MODULE_LICENSE("GPL v2"); 290