linux/drivers/input/keyboard/qt1070.c
<<
>>
Prefs
   1/*
   2 *  Atmel AT42QT1070 QTouch Sensor Controller
   3 *
   4 *  Copyright (C) 2011 Atmel
   5 *
   6 *  Authors: Bo Shen <voice.shen@atmel.com>
   7 *
   8 *  Base on AT42QT2160 driver by:
   9 *  Raphael Derosso Pereira <raphaelpereira@gmail.com>
  10 *  Copyright (C) 2009
  11 *
  12 *  This program is free software; you can redistribute it and/or modify
  13 *  it under the terms of the GNU General Public License as published by
  14 *  the Free Software Foundation; either version 2 of the License, or
  15 *  (at your option) any later version.
  16 *
  17 *  This program is distributed in the hope that it will be useful,
  18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 *  GNU General Public License for more details.
  21 *
  22 *  You should have received a copy of the GNU General Public License
  23 *  along with this program; if not, write to the Free Software
  24 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25 */
  26#include <linux/kernel.h>
  27#include <linux/module.h>
  28#include <linux/init.h>
  29#include <linux/i2c.h>
  30#include <linux/input.h>
  31#include <linux/slab.h>
  32#include <linux/irq.h>
  33#include <linux/interrupt.h>
  34#include <linux/jiffies.h>
  35#include <linux/delay.h>
  36
  37/* Address for each register */
  38#define CHIP_ID            0x00
  39#define QT1070_CHIP_ID     0x2E
  40
  41#define FW_VERSION         0x01
  42#define QT1070_FW_VERSION  0x15
  43
  44#define DET_STATUS         0x02
  45
  46#define KEY_STATUS         0x03
  47
  48/* Calibrate */
  49#define CALIBRATE_CMD      0x38
  50#define QT1070_CAL_TIME    200
  51
  52/* Reset */
  53#define RESET              0x39
  54#define QT1070_RESET_TIME  255
  55
  56/* AT42QT1070 support up to 7 keys */
  57static const unsigned short qt1070_key2code[] = {
  58        KEY_0, KEY_1, KEY_2, KEY_3,
  59        KEY_4, KEY_5, KEY_6,
  60};
  61
  62struct qt1070_data {
  63        struct i2c_client *client;
  64        struct input_dev *input;
  65        unsigned int irq;
  66        unsigned short keycodes[ARRAY_SIZE(qt1070_key2code)];
  67        u8 last_keys;
  68};
  69
  70static int qt1070_read(struct i2c_client *client, u8 reg)
  71{
  72        int ret;
  73
  74        ret = i2c_smbus_read_byte_data(client, reg);
  75        if (ret < 0)
  76                dev_err(&client->dev,
  77                        "can not read register, returned %d\n", ret);
  78
  79        return ret;
  80}
  81
  82static int qt1070_write(struct i2c_client *client, u8 reg, u8 data)
  83{
  84        int ret;
  85
  86        ret = i2c_smbus_write_byte_data(client, reg, data);
  87        if (ret < 0)
  88                dev_err(&client->dev,
  89                        "can not write register, returned %d\n", ret);
  90
  91        return ret;
  92}
  93
  94static bool __devinit qt1070_identify(struct i2c_client *client)
  95{
  96        int id, ver;
  97
  98        /* Read Chip ID */
  99        id = qt1070_read(client, CHIP_ID);
 100        if (id != QT1070_CHIP_ID) {
 101                dev_err(&client->dev, "ID %d not supported\n", id);
 102                return false;
 103        }
 104
 105        /* Read firmware version */
 106        ver = qt1070_read(client, FW_VERSION);
 107        if (ver < 0) {
 108                dev_err(&client->dev, "could not read the firmware version\n");
 109                return false;
 110        }
 111
 112        dev_info(&client->dev, "AT42QT1070 firmware version %x\n", ver);
 113
 114        return true;
 115}
 116
 117static irqreturn_t qt1070_interrupt(int irq, void *dev_id)
 118{
 119        struct qt1070_data *data = dev_id;
 120        struct i2c_client *client = data->client;
 121        struct input_dev *input = data->input;
 122        int i;
 123        u8 new_keys, keyval, mask = 0x01;
 124
 125        /* Read the detected status register, thus clearing interrupt */
 126        qt1070_read(client, DET_STATUS);
 127
 128        /* Read which key changed */
 129        new_keys = qt1070_read(client, KEY_STATUS);
 130
 131        for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) {
 132                keyval = new_keys & mask;
 133                if ((data->last_keys & mask) != keyval)
 134                        input_report_key(input, data->keycodes[i], keyval);
 135                mask <<= 1;
 136        }
 137        input_sync(input);
 138
 139        data->last_keys = new_keys;
 140        return IRQ_HANDLED;
 141}
 142
 143static int __devinit qt1070_probe(struct i2c_client *client,
 144                                const struct i2c_device_id *id)
 145{
 146        struct qt1070_data *data;
 147        struct input_dev *input;
 148        int i;
 149        int err;
 150
 151        err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
 152        if (!err) {
 153                dev_err(&client->dev, "%s adapter not supported\n",
 154                        dev_driver_string(&client->adapter->dev));
 155                return -ENODEV;
 156        }
 157
 158        if (!client->irq) {
 159                dev_err(&client->dev, "please assign the irq to this device\n");
 160                return -EINVAL;
 161        }
 162
 163        /* Identify the qt1070 chip */
 164        if (!qt1070_identify(client))
 165                return -ENODEV;
 166
 167        data = kzalloc(sizeof(struct qt1070_data), GFP_KERNEL);
 168        input = input_allocate_device();
 169        if (!data || !input) {
 170                dev_err(&client->dev, "insufficient memory\n");
 171                err = -ENOMEM;
 172                goto err_free_mem;
 173        }
 174
 175        data->client = client;
 176        data->input = input;
 177        data->irq = client->irq;
 178
 179        input->name = "AT42QT1070 QTouch Sensor";
 180        input->dev.parent = &client->dev;
 181        input->id.bustype = BUS_I2C;
 182
 183        /* Add the keycode */
 184        input->keycode = data->keycodes;
 185        input->keycodesize = sizeof(data->keycodes[0]);
 186        input->keycodemax = ARRAY_SIZE(qt1070_key2code);
 187
 188        __set_bit(EV_KEY, input->evbit);
 189
 190        for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) {
 191                data->keycodes[i] = qt1070_key2code[i];
 192                __set_bit(qt1070_key2code[i], input->keybit);
 193        }
 194
 195        /* Calibrate device */
 196        qt1070_write(client, CALIBRATE_CMD, 1);
 197        msleep(QT1070_CAL_TIME);
 198
 199        /* Soft reset */
 200        qt1070_write(client, RESET, 1);
 201        msleep(QT1070_RESET_TIME);
 202
 203        err = request_threaded_irq(client->irq, NULL, qt1070_interrupt,
 204                IRQF_TRIGGER_NONE, client->dev.driver->name, data);
 205        if (err) {
 206                dev_err(&client->dev, "fail to request irq\n");
 207                goto err_free_mem;
 208        }
 209
 210        /* Register the input device */
 211        err = input_register_device(data->input);
 212        if (err) {
 213                dev_err(&client->dev, "Failed to register input device\n");
 214                goto err_free_irq;
 215        }
 216
 217        i2c_set_clientdata(client, data);
 218
 219        /* Read to clear the chang line */
 220        qt1070_read(client, DET_STATUS);
 221
 222        return 0;
 223
 224err_free_irq:
 225        free_irq(client->irq, data);
 226err_free_mem:
 227        input_free_device(input);
 228        kfree(data);
 229        return err;
 230}
 231
 232static int __devexit qt1070_remove(struct i2c_client *client)
 233{
 234        struct qt1070_data *data = i2c_get_clientdata(client);
 235
 236        /* Release IRQ */
 237        free_irq(client->irq, data);
 238
 239        input_unregister_device(data->input);
 240        kfree(data);
 241
 242        return 0;
 243}
 244
 245static const struct i2c_device_id qt1070_id[] = {
 246        { "qt1070", 0 },
 247        { },
 248};
 249MODULE_DEVICE_TABLE(i2c, qt1070_id);
 250
 251static struct i2c_driver qt1070_driver = {
 252        .driver = {
 253                .name   = "qt1070",
 254                .owner  = THIS_MODULE,
 255        },
 256        .id_table       = qt1070_id,
 257        .probe          = qt1070_probe,
 258        .remove         = __devexit_p(qt1070_remove),
 259};
 260
 261module_i2c_driver(qt1070_driver);
 262
 263MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
 264MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor");
 265MODULE_LICENSE("GPL");
 266