// SPDX-License-Identifier: GPL-2.0-only /* * Atmel Atmegaxx Capacitive Touch Button Driver * * Copyright (C) 2016 Google, inc. */ /* * It's irrelevant that the HW used to develop captouch driver is based * on Atmega88PA part and uses QtouchADC parts for sensing touch. * Calling this driver "captouch" is an arbitrary way to distinguish * the protocol this driver supported by other atmel/qtouch drivers. * * Captouch driver supports a newer/different version of the I2C * registers/commands than the qt1070.c driver. * Don't let the similarity of the general driver structure fool you. * * For raw i2c access from userspace, use i2cset/i2cget * to poke at /dev/i2c-N devices. */ #include <linux/device.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/slab.h> /* Maximum number of buttons supported */ #define MAX_NUM_OF_BUTTONS … /* Registers */ #define REG_KEY1_THRESHOLD … #define REG_KEY2_THRESHOLD … #define REG_KEY3_THRESHOLD … #define REG_KEY4_THRESHOLD … #define REG_KEY1_REF_H … #define REG_KEY1_REF_L … #define REG_KEY2_REF_H … #define REG_KEY2_REF_L … #define REG_KEY3_REF_H … #define REG_KEY3_REF_L … #define REG_KEY4_REF_H … #define REG_KEY4_REF_L … #define REG_KEY1_DLT_H … #define REG_KEY1_DLT_L … #define REG_KEY2_DLT_H … #define REG_KEY2_DLT_L … #define REG_KEY3_DLT_H … #define REG_KEY3_DLT_L … #define REG_KEY4_DLT_H … #define REG_KEY4_DLT_L … #define REG_KEY_STATE … /* * @i2c_client: I2C slave device client pointer * @input: Input device pointer * @num_btn: Number of buttons * @keycodes: map of button# to KeyCode * @prev_btn: Previous key state to detect button "press" or "release" * @xfer_buf: I2C transfer buffer */ struct atmel_captouch_device { … }; /* * Read from I2C slave device * The protocol is that the client has to provide both the register address * and the length, and while reading back the device would prepend the data * with address and length for verification. */ static int atmel_read(struct atmel_captouch_device *capdev, u8 reg, u8 *data, size_t len) { … } /* * Handle interrupt and report the key changes to the input system. * Multi-touch can be supported; however, it really depends on whether * the device can multi-touch. */ static irqreturn_t atmel_captouch_isr(int irq, void *data) { … } /* * Probe function to setup the device, input system and interrupt */ static int atmel_captouch_probe(struct i2c_client *client) { … } static const struct of_device_id atmel_captouch_of_id[] = …; MODULE_DEVICE_TABLE(of, atmel_captouch_of_id); static const struct i2c_device_id atmel_captouch_id[] = …; MODULE_DEVICE_TABLE(i2c, atmel_captouch_id); static struct i2c_driver atmel_captouch_driver = …; module_i2c_driver(…) …; /* Module information */ MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;