Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Atmel Atmegaxx Capacitive Touch Button Driver
0004  *
0005  * Copyright (C) 2016 Google, inc.
0006  */
0007 
0008 /*
0009  * It's irrelevant that the HW used to develop captouch driver is based
0010  * on Atmega88PA part and uses QtouchADC parts for sensing touch.
0011  * Calling this driver "captouch" is an arbitrary way to distinguish
0012  * the protocol this driver supported by other atmel/qtouch drivers.
0013  *
0014  * Captouch driver supports a newer/different version of the I2C
0015  * registers/commands than the qt1070.c driver.
0016  * Don't let the similarity of the general driver structure fool you.
0017  *
0018  * For raw i2c access from userspace, use i2cset/i2cget
0019  * to poke at /dev/i2c-N devices.
0020  */
0021 
0022 #include <linux/device.h>
0023 #include <linux/kernel.h>
0024 #include <linux/module.h>
0025 #include <linux/init.h>
0026 #include <linux/i2c.h>
0027 #include <linux/input.h>
0028 #include <linux/interrupt.h>
0029 #include <linux/slab.h>
0030 
0031 /* Maximum number of buttons supported */
0032 #define MAX_NUM_OF_BUTTONS      8
0033 
0034 /* Registers */
0035 #define REG_KEY1_THRESHOLD      0x02
0036 #define REG_KEY2_THRESHOLD      0x03
0037 #define REG_KEY3_THRESHOLD      0x04
0038 #define REG_KEY4_THRESHOLD      0x05
0039 
0040 #define REG_KEY1_REF_H          0x20
0041 #define REG_KEY1_REF_L          0x21
0042 #define REG_KEY2_REF_H          0x22
0043 #define REG_KEY2_REF_L          0x23
0044 #define REG_KEY3_REF_H          0x24
0045 #define REG_KEY3_REF_L          0x25
0046 #define REG_KEY4_REF_H          0x26
0047 #define REG_KEY4_REF_L          0x27
0048 
0049 #define REG_KEY1_DLT_H          0x30
0050 #define REG_KEY1_DLT_L          0x31
0051 #define REG_KEY2_DLT_H          0x32
0052 #define REG_KEY2_DLT_L          0x33
0053 #define REG_KEY3_DLT_H          0x34
0054 #define REG_KEY3_DLT_L          0x35
0055 #define REG_KEY4_DLT_H          0x36
0056 #define REG_KEY4_DLT_L          0x37
0057 
0058 #define REG_KEY_STATE           0x3C
0059 
0060 /*
0061  * @i2c_client: I2C slave device client pointer
0062  * @input: Input device pointer
0063  * @num_btn: Number of buttons
0064  * @keycodes: map of button# to KeyCode
0065  * @prev_btn: Previous key state to detect button "press" or "release"
0066  * @xfer_buf: I2C transfer buffer
0067  */
0068 struct atmel_captouch_device {
0069     struct i2c_client *client;
0070     struct input_dev *input;
0071     u32 num_btn;
0072     u32 keycodes[MAX_NUM_OF_BUTTONS];
0073     u8 prev_btn;
0074     u8 xfer_buf[8] ____cacheline_aligned;
0075 };
0076 
0077 /*
0078  * Read from I2C slave device
0079  * The protocol is that the client has to provide both the register address
0080  * and the length, and while reading back the device would prepend the data
0081  * with address and length for verification.
0082  */
0083 static int atmel_read(struct atmel_captouch_device *capdev,
0084              u8 reg, u8 *data, size_t len)
0085 {
0086     struct i2c_client *client = capdev->client;
0087     struct device *dev = &client->dev;
0088     struct i2c_msg msg[2];
0089     int err;
0090 
0091     if (len > sizeof(capdev->xfer_buf) - 2)
0092         return -EINVAL;
0093 
0094     capdev->xfer_buf[0] = reg;
0095     capdev->xfer_buf[1] = len;
0096 
0097     msg[0].addr = client->addr;
0098     msg[0].flags = 0;
0099     msg[0].buf = capdev->xfer_buf;
0100     msg[0].len = 2;
0101 
0102     msg[1].addr = client->addr;
0103     msg[1].flags = I2C_M_RD;
0104     msg[1].buf = capdev->xfer_buf;
0105     msg[1].len = len + 2;
0106 
0107     err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
0108     if (err != ARRAY_SIZE(msg))
0109         return err < 0 ? err : -EIO;
0110 
0111     if (capdev->xfer_buf[0] != reg) {
0112         dev_err(dev,
0113             "I2C read error: register address does not match (%#02x vs %02x)\n",
0114             capdev->xfer_buf[0], reg);
0115         return -ECOMM;
0116     }
0117 
0118     memcpy(data, &capdev->xfer_buf[2], len);
0119 
0120     return 0;
0121 }
0122 
0123 /*
0124  * Handle interrupt and report the key changes to the input system.
0125  * Multi-touch can be supported; however, it really depends on whether
0126  * the device can multi-touch.
0127  */
0128 static irqreturn_t atmel_captouch_isr(int irq, void *data)
0129 {
0130     struct atmel_captouch_device *capdev = data;
0131     struct device *dev = &capdev->client->dev;
0132     int error;
0133     int i;
0134     u8 new_btn;
0135     u8 changed_btn;
0136 
0137     error = atmel_read(capdev, REG_KEY_STATE, &new_btn, 1);
0138     if (error) {
0139         dev_err(dev, "failed to read button state: %d\n", error);
0140         goto out;
0141     }
0142 
0143     dev_dbg(dev, "%s: button state %#02x\n", __func__, new_btn);
0144 
0145     changed_btn = new_btn ^ capdev->prev_btn;
0146     capdev->prev_btn = new_btn;
0147 
0148     for (i = 0; i < capdev->num_btn; i++) {
0149         if (changed_btn & BIT(i))
0150             input_report_key(capdev->input,
0151                      capdev->keycodes[i],
0152                      new_btn & BIT(i));
0153     }
0154 
0155     input_sync(capdev->input);
0156 
0157 out:
0158     return IRQ_HANDLED;
0159 }
0160 
0161 /*
0162  * Probe function to setup the device, input system and interrupt
0163  */
0164 static int atmel_captouch_probe(struct i2c_client *client,
0165         const struct i2c_device_id *id)
0166 {
0167     struct atmel_captouch_device *capdev;
0168     struct device *dev = &client->dev;
0169     struct device_node *node;
0170     int i;
0171     int err;
0172 
0173     if (!i2c_check_functionality(client->adapter,
0174                      I2C_FUNC_SMBUS_BYTE_DATA |
0175                     I2C_FUNC_SMBUS_WORD_DATA |
0176                     I2C_FUNC_SMBUS_I2C_BLOCK)) {
0177         dev_err(dev, "needed i2c functionality is not supported\n");
0178         return -EINVAL;
0179     }
0180 
0181     capdev = devm_kzalloc(dev, sizeof(*capdev), GFP_KERNEL);
0182     if (!capdev)
0183         return -ENOMEM;
0184 
0185     capdev->client = client;
0186 
0187     err = atmel_read(capdev, REG_KEY_STATE,
0188                 &capdev->prev_btn, sizeof(capdev->prev_btn));
0189     if (err) {
0190         dev_err(dev, "failed to read initial button state: %d\n", err);
0191         return err;
0192     }
0193 
0194     capdev->input = devm_input_allocate_device(dev);
0195     if (!capdev->input) {
0196         dev_err(dev, "failed to allocate input device\n");
0197         return -ENOMEM;
0198     }
0199 
0200     capdev->input->id.bustype = BUS_I2C;
0201     capdev->input->id.product = 0x880A;
0202     capdev->input->id.version = 0;
0203     capdev->input->name = "ATMegaXX Capacitive Button Controller";
0204     __set_bit(EV_KEY, capdev->input->evbit);
0205 
0206     node = dev->of_node;
0207     if (!node) {
0208         dev_err(dev, "failed to find matching node in device tree\n");
0209         return -EINVAL;
0210     }
0211 
0212     if (of_property_read_bool(node, "autorepeat"))
0213         __set_bit(EV_REP, capdev->input->evbit);
0214 
0215     capdev->num_btn = of_property_count_u32_elems(node, "linux,keymap");
0216     if (capdev->num_btn > MAX_NUM_OF_BUTTONS)
0217         capdev->num_btn = MAX_NUM_OF_BUTTONS;
0218 
0219     err = of_property_read_u32_array(node, "linux,keycodes",
0220                      capdev->keycodes,
0221                      capdev->num_btn);
0222     if (err) {
0223         dev_err(dev,
0224             "failed to read linux,keycode property: %d\n", err);
0225         return err;
0226     }
0227 
0228     for (i = 0; i < capdev->num_btn; i++)
0229         __set_bit(capdev->keycodes[i], capdev->input->keybit);
0230 
0231     capdev->input->keycode = capdev->keycodes;
0232     capdev->input->keycodesize = sizeof(capdev->keycodes[0]);
0233     capdev->input->keycodemax = capdev->num_btn;
0234 
0235     err = input_register_device(capdev->input);
0236     if (err)
0237         return err;
0238 
0239     err = devm_request_threaded_irq(dev, client->irq,
0240                     NULL, atmel_captouch_isr,
0241                     IRQF_ONESHOT,
0242                     "atmel_captouch", capdev);
0243     if (err) {
0244         dev_err(dev, "failed to request irq %d: %d\n",
0245             client->irq, err);
0246         return err;
0247     }
0248 
0249     return 0;
0250 }
0251 
0252 #ifdef CONFIG_OF
0253 static const struct of_device_id atmel_captouch_of_id[] = {
0254     {
0255         .compatible = "atmel,captouch",
0256     },
0257     { /* sentinel */ }
0258 };
0259 MODULE_DEVICE_TABLE(of, atmel_captouch_of_id);
0260 #endif
0261 
0262 static const struct i2c_device_id atmel_captouch_id[] = {
0263     { "atmel_captouch", 0 },
0264     { }
0265 };
0266 MODULE_DEVICE_TABLE(i2c, atmel_captouch_id);
0267 
0268 static struct i2c_driver atmel_captouch_driver = {
0269     .probe      = atmel_captouch_probe,
0270     .id_table   = atmel_captouch_id,
0271     .driver     = {
0272         .name   = "atmel_captouch",
0273         .of_match_table = of_match_ptr(atmel_captouch_of_id),
0274     },
0275 };
0276 module_i2c_driver(atmel_captouch_driver);
0277 
0278 /* Module information */
0279 MODULE_AUTHOR("Hung-yu Wu <hywu@google.com>");
0280 MODULE_DESCRIPTION("Atmel ATmegaXX Capacitance Touch Sensor I2C Driver");
0281 MODULE_LICENSE("GPL v2");