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