174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2fde11323SRaphael Derosso Pereira /* 3fde11323SRaphael Derosso Pereira * qt2160.c - Atmel AT42QT2160 Touch Sense Controller 4fde11323SRaphael Derosso Pereira * 5fde11323SRaphael Derosso Pereira * Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com> 6fde11323SRaphael Derosso Pereira */ 7fde11323SRaphael Derosso Pereira 8fde11323SRaphael Derosso Pereira #include <linux/kernel.h> 90e47e3dcSJavier Martin #include <linux/leds.h> 10fde11323SRaphael Derosso Pereira #include <linux/module.h> 11fde11323SRaphael Derosso Pereira #include <linux/slab.h> 12fde11323SRaphael Derosso Pereira #include <linux/jiffies.h> 13fde11323SRaphael Derosso Pereira #include <linux/i2c.h> 14fde11323SRaphael Derosso Pereira #include <linux/irq.h> 15fde11323SRaphael Derosso Pereira #include <linux/interrupt.h> 16fde11323SRaphael Derosso Pereira #include <linux/input.h> 17fde11323SRaphael Derosso Pereira 18fde11323SRaphael Derosso Pereira #define QT2160_VALID_CHIPID 0x11 19fde11323SRaphael Derosso Pereira 20fde11323SRaphael Derosso Pereira #define QT2160_CMD_CHIPID 0 21fde11323SRaphael Derosso Pereira #define QT2160_CMD_CODEVER 1 22fde11323SRaphael Derosso Pereira #define QT2160_CMD_GSTAT 2 23fde11323SRaphael Derosso Pereira #define QT2160_CMD_KEYS3 3 24fde11323SRaphael Derosso Pereira #define QT2160_CMD_KEYS4 4 25fde11323SRaphael Derosso Pereira #define QT2160_CMD_SLIDE 5 26fde11323SRaphael Derosso Pereira #define QT2160_CMD_GPIOS 6 27fde11323SRaphael Derosso Pereira #define QT2160_CMD_SUBVER 7 28fde11323SRaphael Derosso Pereira #define QT2160_CMD_CALIBRATE 10 290e47e3dcSJavier Martin #define QT2160_CMD_DRIVE_X 70 300e47e3dcSJavier Martin #define QT2160_CMD_PWMEN_X 74 310e47e3dcSJavier Martin #define QT2160_CMD_PWM_DUTY 76 320e47e3dcSJavier Martin 330e47e3dcSJavier Martin #define QT2160_NUM_LEDS_X 8 34fde11323SRaphael Derosso Pereira 35f1fbff60SDmitry Torokhov #define QT2160_CYCLE_INTERVAL 2000 /* msec - 2 sec */ 36fde11323SRaphael Derosso Pereira 37fde11323SRaphael Derosso Pereira static unsigned char qt2160_key2code[] = { 38fde11323SRaphael Derosso Pereira KEY_0, KEY_1, KEY_2, KEY_3, 39fde11323SRaphael Derosso Pereira KEY_4, KEY_5, KEY_6, KEY_7, 40fde11323SRaphael Derosso Pereira KEY_8, KEY_9, KEY_A, KEY_B, 41fde11323SRaphael Derosso Pereira KEY_C, KEY_D, KEY_E, KEY_F, 42fde11323SRaphael Derosso Pereira }; 43fde11323SRaphael Derosso Pereira 440e47e3dcSJavier Martin #ifdef CONFIG_LEDS_CLASS 450e47e3dcSJavier Martin struct qt2160_led { 460e47e3dcSJavier Martin struct qt2160_data *qt2160; 470e47e3dcSJavier Martin struct led_classdev cdev; 480e47e3dcSJavier Martin char name[32]; 490e47e3dcSJavier Martin int id; 5083cd2030SDmitry Torokhov enum led_brightness brightness; 510e47e3dcSJavier Martin }; 520e47e3dcSJavier Martin #endif 530e47e3dcSJavier Martin 54fde11323SRaphael Derosso Pereira struct qt2160_data { 55fde11323SRaphael Derosso Pereira struct i2c_client *client; 56fde11323SRaphael Derosso Pereira struct input_dev *input; 57fde11323SRaphael Derosso Pereira unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)]; 58fde11323SRaphael Derosso Pereira u16 key_matrix; 590e47e3dcSJavier Martin #ifdef CONFIG_LEDS_CLASS 600e47e3dcSJavier Martin struct qt2160_led leds[QT2160_NUM_LEDS_X]; 610e47e3dcSJavier Martin #endif 62fde11323SRaphael Derosso Pereira }; 63fde11323SRaphael Derosso Pereira 640e47e3dcSJavier Martin static int qt2160_read(struct i2c_client *client, u8 reg); 650e47e3dcSJavier Martin static int qt2160_write(struct i2c_client *client, u8 reg, u8 data); 660e47e3dcSJavier Martin 670e47e3dcSJavier Martin #ifdef CONFIG_LEDS_CLASS 680e47e3dcSJavier Martin 6983cd2030SDmitry Torokhov static int qt2160_led_set(struct led_classdev *cdev, 7083cd2030SDmitry Torokhov enum led_brightness value) 710e47e3dcSJavier Martin { 7283cd2030SDmitry Torokhov struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev); 730e47e3dcSJavier Martin struct qt2160_data *qt2160 = led->qt2160; 740e47e3dcSJavier Martin struct i2c_client *client = qt2160->client; 750e47e3dcSJavier Martin u32 drive, pwmen; 760e47e3dcSJavier Martin 7783cd2030SDmitry Torokhov if (value != led->brightness) { 780e47e3dcSJavier Martin drive = qt2160_read(client, QT2160_CMD_DRIVE_X); 790e47e3dcSJavier Martin pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X); 800e47e3dcSJavier Martin if (value != LED_OFF) { 8183cd2030SDmitry Torokhov drive |= BIT(led->id); 8283cd2030SDmitry Torokhov pwmen |= BIT(led->id); 830e47e3dcSJavier Martin 840e47e3dcSJavier Martin } else { 8583cd2030SDmitry Torokhov drive &= ~BIT(led->id); 8683cd2030SDmitry Torokhov pwmen &= ~BIT(led->id); 870e47e3dcSJavier Martin } 880e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_DRIVE_X, drive); 890e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen); 900e47e3dcSJavier Martin 910e47e3dcSJavier Martin /* 920e47e3dcSJavier Martin * Changing this register will change the brightness 930e47e3dcSJavier Martin * of every LED in the qt2160. It's a HW limitation. 940e47e3dcSJavier Martin */ 950e47e3dcSJavier Martin if (value != LED_OFF) 960e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_PWM_DUTY, value); 970e47e3dcSJavier Martin 9883cd2030SDmitry Torokhov led->brightness = value; 990e47e3dcSJavier Martin } 1000e47e3dcSJavier Martin 10183cd2030SDmitry Torokhov return 0; 1020e47e3dcSJavier Martin } 1030e47e3dcSJavier Martin 1040e47e3dcSJavier Martin #endif /* CONFIG_LEDS_CLASS */ 1050e47e3dcSJavier Martin 106fde11323SRaphael Derosso Pereira static int qt2160_read_block(struct i2c_client *client, 107fde11323SRaphael Derosso Pereira u8 inireg, u8 *buffer, unsigned int count) 108fde11323SRaphael Derosso Pereira { 109fde11323SRaphael Derosso Pereira int error, idx = 0; 110fde11323SRaphael Derosso Pereira 111fde11323SRaphael Derosso Pereira /* 112fde11323SRaphael Derosso Pereira * Can't use SMBus block data read. Check for I2C functionality to speed 113fde11323SRaphael Derosso Pereira * things up whenever possible. Otherwise we will be forced to read 114fde11323SRaphael Derosso Pereira * sequentially. 115fde11323SRaphael Derosso Pereira */ 116fde11323SRaphael Derosso Pereira if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 117fde11323SRaphael Derosso Pereira 118fde11323SRaphael Derosso Pereira error = i2c_smbus_write_byte(client, inireg + idx); 119fde11323SRaphael Derosso Pereira if (error) { 120fde11323SRaphael Derosso Pereira dev_err(&client->dev, 121fde11323SRaphael Derosso Pereira "couldn't send request. Returned %d\n", error); 122fde11323SRaphael Derosso Pereira return error; 123fde11323SRaphael Derosso Pereira } 124fde11323SRaphael Derosso Pereira 125fde11323SRaphael Derosso Pereira error = i2c_master_recv(client, buffer, count); 126fde11323SRaphael Derosso Pereira if (error != count) { 127fde11323SRaphael Derosso Pereira dev_err(&client->dev, 128fde11323SRaphael Derosso Pereira "couldn't read registers. Returned %d bytes\n", error); 129fde11323SRaphael Derosso Pereira return error; 130fde11323SRaphael Derosso Pereira } 131fde11323SRaphael Derosso Pereira } else { 132fde11323SRaphael Derosso Pereira 133fde11323SRaphael Derosso Pereira while (count--) { 134fde11323SRaphael Derosso Pereira int data; 135fde11323SRaphael Derosso Pereira 136fde11323SRaphael Derosso Pereira error = i2c_smbus_write_byte(client, inireg + idx); 137fde11323SRaphael Derosso Pereira if (error) { 138fde11323SRaphael Derosso Pereira dev_err(&client->dev, 139fde11323SRaphael Derosso Pereira "couldn't send request. Returned %d\n", error); 140fde11323SRaphael Derosso Pereira return error; 141fde11323SRaphael Derosso Pereira } 142fde11323SRaphael Derosso Pereira 143fde11323SRaphael Derosso Pereira data = i2c_smbus_read_byte(client); 144fde11323SRaphael Derosso Pereira if (data < 0) { 145fde11323SRaphael Derosso Pereira dev_err(&client->dev, 146fde11323SRaphael Derosso Pereira "couldn't read register. Returned %d\n", data); 147fde11323SRaphael Derosso Pereira return data; 148fde11323SRaphael Derosso Pereira } 149fde11323SRaphael Derosso Pereira 150fde11323SRaphael Derosso Pereira buffer[idx++] = data; 151fde11323SRaphael Derosso Pereira } 152fde11323SRaphael Derosso Pereira } 153fde11323SRaphael Derosso Pereira 154fde11323SRaphael Derosso Pereira return 0; 155fde11323SRaphael Derosso Pereira } 156fde11323SRaphael Derosso Pereira 157f1fbff60SDmitry Torokhov static void qt2160_get_key_matrix(struct input_dev *input) 158fde11323SRaphael Derosso Pereira { 159f1fbff60SDmitry Torokhov struct qt2160_data *qt2160 = input_get_drvdata(input); 160fde11323SRaphael Derosso Pereira struct i2c_client *client = qt2160->client; 161fde11323SRaphael Derosso Pereira u8 regs[6]; 162fde11323SRaphael Derosso Pereira u16 old_matrix, new_matrix; 163fde11323SRaphael Derosso Pereira int ret, i, mask; 164fde11323SRaphael Derosso Pereira 165fde11323SRaphael Derosso Pereira dev_dbg(&client->dev, "requesting keys...\n"); 166fde11323SRaphael Derosso Pereira 167fde11323SRaphael Derosso Pereira /* 168fde11323SRaphael Derosso Pereira * Read all registers from General Status Register 169fde11323SRaphael Derosso Pereira * to GPIOs register 170fde11323SRaphael Derosso Pereira */ 171fde11323SRaphael Derosso Pereira ret = qt2160_read_block(client, QT2160_CMD_GSTAT, regs, 6); 172fde11323SRaphael Derosso Pereira if (ret) { 173fde11323SRaphael Derosso Pereira dev_err(&client->dev, 174fde11323SRaphael Derosso Pereira "could not perform chip read.\n"); 175f1fbff60SDmitry Torokhov return; 176fde11323SRaphael Derosso Pereira } 177fde11323SRaphael Derosso Pereira 178fde11323SRaphael Derosso Pereira old_matrix = qt2160->key_matrix; 179fde11323SRaphael Derosso Pereira qt2160->key_matrix = new_matrix = (regs[2] << 8) | regs[1]; 180fde11323SRaphael Derosso Pereira 181fde11323SRaphael Derosso Pereira mask = 0x01; 182fde11323SRaphael Derosso Pereira for (i = 0; i < 16; ++i, mask <<= 1) { 183fde11323SRaphael Derosso Pereira int keyval = new_matrix & mask; 184fde11323SRaphael Derosso Pereira 185fde11323SRaphael Derosso Pereira if ((old_matrix & mask) != keyval) { 186fde11323SRaphael Derosso Pereira input_report_key(input, qt2160->keycodes[i], keyval); 187fde11323SRaphael Derosso Pereira dev_dbg(&client->dev, "key %d %s\n", 188fde11323SRaphael Derosso Pereira i, keyval ? "pressed" : "released"); 189fde11323SRaphael Derosso Pereira } 190fde11323SRaphael Derosso Pereira } 191fde11323SRaphael Derosso Pereira 192fde11323SRaphael Derosso Pereira input_sync(input); 193fde11323SRaphael Derosso Pereira } 194fde11323SRaphael Derosso Pereira 195f1fbff60SDmitry Torokhov static irqreturn_t qt2160_irq(int irq, void *data) 196fde11323SRaphael Derosso Pereira { 197f1fbff60SDmitry Torokhov struct input_dev *input = data; 198fde11323SRaphael Derosso Pereira 199f1fbff60SDmitry Torokhov qt2160_get_key_matrix(input); 200fde11323SRaphael Derosso Pereira 201fde11323SRaphael Derosso Pereira return IRQ_HANDLED; 202fde11323SRaphael Derosso Pereira } 203fde11323SRaphael Derosso Pereira 2045298cc4cSBill Pemberton static int qt2160_read(struct i2c_client *client, u8 reg) 205fde11323SRaphael Derosso Pereira { 206fde11323SRaphael Derosso Pereira int ret; 207fde11323SRaphael Derosso Pereira 208fde11323SRaphael Derosso Pereira ret = i2c_smbus_write_byte(client, reg); 209fde11323SRaphael Derosso Pereira if (ret) { 210fde11323SRaphael Derosso Pereira dev_err(&client->dev, 211fde11323SRaphael Derosso Pereira "couldn't send request. Returned %d\n", ret); 212fde11323SRaphael Derosso Pereira return ret; 213fde11323SRaphael Derosso Pereira } 214fde11323SRaphael Derosso Pereira 215fde11323SRaphael Derosso Pereira ret = i2c_smbus_read_byte(client); 216fde11323SRaphael Derosso Pereira if (ret < 0) { 217fde11323SRaphael Derosso Pereira dev_err(&client->dev, 218fde11323SRaphael Derosso Pereira "couldn't read register. Returned %d\n", ret); 219fde11323SRaphael Derosso Pereira return ret; 220fde11323SRaphael Derosso Pereira } 221fde11323SRaphael Derosso Pereira 222fde11323SRaphael Derosso Pereira return ret; 223fde11323SRaphael Derosso Pereira } 224fde11323SRaphael Derosso Pereira 2255298cc4cSBill Pemberton static int qt2160_write(struct i2c_client *client, u8 reg, u8 data) 226fde11323SRaphael Derosso Pereira { 227a6e8c0a2SJavier Martin int ret; 228fde11323SRaphael Derosso Pereira 229a6e8c0a2SJavier Martin ret = i2c_smbus_write_byte_data(client, reg, data); 230a6e8c0a2SJavier Martin if (ret < 0) 231fde11323SRaphael Derosso Pereira dev_err(&client->dev, 232a6e8c0a2SJavier Martin "couldn't write data. Returned %d\n", ret); 233fde11323SRaphael Derosso Pereira 234a6e8c0a2SJavier Martin return ret; 235fde11323SRaphael Derosso Pereira } 236fde11323SRaphael Derosso Pereira 2370e47e3dcSJavier Martin #ifdef CONFIG_LEDS_CLASS 2380e47e3dcSJavier Martin 2390e47e3dcSJavier Martin static int qt2160_register_leds(struct qt2160_data *qt2160) 2400e47e3dcSJavier Martin { 2410e47e3dcSJavier Martin struct i2c_client *client = qt2160->client; 2423e4bb047SYangtao Li int error; 2430e47e3dcSJavier Martin int i; 2440e47e3dcSJavier Martin 2450e47e3dcSJavier Martin for (i = 0; i < QT2160_NUM_LEDS_X; i++) { 2460e47e3dcSJavier Martin struct qt2160_led *led = &qt2160->leds[i]; 2470e47e3dcSJavier Martin 2480e47e3dcSJavier Martin snprintf(led->name, sizeof(led->name), "qt2160:x%d", i); 2490e47e3dcSJavier Martin led->cdev.name = led->name; 25083cd2030SDmitry Torokhov led->cdev.brightness_set_blocking = qt2160_led_set; 2510e47e3dcSJavier Martin led->cdev.brightness = LED_OFF; 2520e47e3dcSJavier Martin led->id = i; 2530e47e3dcSJavier Martin led->qt2160 = qt2160; 2540e47e3dcSJavier Martin 2553e4bb047SYangtao Li error = devm_led_classdev_register(&client->dev, &led->cdev); 2563e4bb047SYangtao Li if (error) 2573e4bb047SYangtao Li return error; 2580e47e3dcSJavier Martin } 2590e47e3dcSJavier Martin 2600e47e3dcSJavier Martin /* Tur off LEDs */ 2610e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_DRIVE_X, 0); 2620e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_PWMEN_X, 0); 2630e47e3dcSJavier Martin qt2160_write(client, QT2160_CMD_PWM_DUTY, 0); 2640e47e3dcSJavier Martin 2650e47e3dcSJavier Martin return 0; 2660e47e3dcSJavier Martin } 2670e47e3dcSJavier Martin 2680e47e3dcSJavier Martin #else 2690e47e3dcSJavier Martin 2700e47e3dcSJavier Martin static inline int qt2160_register_leds(struct qt2160_data *qt2160) 2710e47e3dcSJavier Martin { 2720e47e3dcSJavier Martin return 0; 2730e47e3dcSJavier Martin } 2740e47e3dcSJavier Martin 2750e47e3dcSJavier Martin #endif 276fde11323SRaphael Derosso Pereira 2775298cc4cSBill Pemberton static bool qt2160_identify(struct i2c_client *client) 278fde11323SRaphael Derosso Pereira { 279fde11323SRaphael Derosso Pereira int id, ver, rev; 280fde11323SRaphael Derosso Pereira 281fde11323SRaphael Derosso Pereira /* Read Chid ID to check if chip is valid */ 282fde11323SRaphael Derosso Pereira id = qt2160_read(client, QT2160_CMD_CHIPID); 283fde11323SRaphael Derosso Pereira if (id != QT2160_VALID_CHIPID) { 284fde11323SRaphael Derosso Pereira dev_err(&client->dev, "ID %d not supported\n", id); 285fde11323SRaphael Derosso Pereira return false; 286fde11323SRaphael Derosso Pereira } 287fde11323SRaphael Derosso Pereira 288fde11323SRaphael Derosso Pereira /* Read chip firmware version */ 289fde11323SRaphael Derosso Pereira ver = qt2160_read(client, QT2160_CMD_CODEVER); 290fde11323SRaphael Derosso Pereira if (ver < 0) { 291fde11323SRaphael Derosso Pereira dev_err(&client->dev, "could not get firmware version\n"); 292fde11323SRaphael Derosso Pereira return false; 293fde11323SRaphael Derosso Pereira } 294fde11323SRaphael Derosso Pereira 295fde11323SRaphael Derosso Pereira /* Read chip firmware revision */ 296fde11323SRaphael Derosso Pereira rev = qt2160_read(client, QT2160_CMD_SUBVER); 297fde11323SRaphael Derosso Pereira if (rev < 0) { 298fde11323SRaphael Derosso Pereira dev_err(&client->dev, "could not get firmware revision\n"); 299fde11323SRaphael Derosso Pereira return false; 300fde11323SRaphael Derosso Pereira } 301fde11323SRaphael Derosso Pereira 302fde11323SRaphael Derosso Pereira dev_info(&client->dev, "AT42QT2160 firmware version %d.%d.%d\n", 303fde11323SRaphael Derosso Pereira ver >> 4, ver & 0xf, rev); 304fde11323SRaphael Derosso Pereira 305fde11323SRaphael Derosso Pereira return true; 306fde11323SRaphael Derosso Pereira } 307fde11323SRaphael Derosso Pereira 308b37a4c1bSUwe Kleine-König static int qt2160_probe(struct i2c_client *client) 309fde11323SRaphael Derosso Pereira { 310fde11323SRaphael Derosso Pereira struct qt2160_data *qt2160; 311fde11323SRaphael Derosso Pereira struct input_dev *input; 312fde11323SRaphael Derosso Pereira int i; 313fde11323SRaphael Derosso Pereira int error; 314fde11323SRaphael Derosso Pereira 315f94c3bceSDmitry Torokhov if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { 316fde11323SRaphael Derosso Pereira dev_err(&client->dev, "%s adapter not supported\n", 317fde11323SRaphael Derosso Pereira dev_driver_string(&client->adapter->dev)); 318fde11323SRaphael Derosso Pereira return -ENODEV; 319fde11323SRaphael Derosso Pereira } 320fde11323SRaphael Derosso Pereira 321fde11323SRaphael Derosso Pereira if (!qt2160_identify(client)) 322fde11323SRaphael Derosso Pereira return -ENODEV; 323fde11323SRaphael Derosso Pereira 324fde11323SRaphael Derosso Pereira /* Chip is valid and active. Allocate structure */ 3253e4bb047SYangtao Li qt2160 = devm_kzalloc(&client->dev, sizeof(*qt2160), GFP_KERNEL); 3263e4bb047SYangtao Li if (!qt2160) 3273e4bb047SYangtao Li return -ENOMEM; 3283e4bb047SYangtao Li 3293e4bb047SYangtao Li input = devm_input_allocate_device(&client->dev); 3303e4bb047SYangtao Li if (!input) 3313e4bb047SYangtao Li return -ENOMEM; 332fde11323SRaphael Derosso Pereira 333fde11323SRaphael Derosso Pereira qt2160->client = client; 334fde11323SRaphael Derosso Pereira qt2160->input = input; 335fde11323SRaphael Derosso Pereira 336fde11323SRaphael Derosso Pereira input->name = "AT42QT2160 Touch Sense Keyboard"; 337fde11323SRaphael Derosso Pereira input->id.bustype = BUS_I2C; 338fde11323SRaphael Derosso Pereira 339fde11323SRaphael Derosso Pereira input->keycode = qt2160->keycodes; 340fde11323SRaphael Derosso Pereira input->keycodesize = sizeof(qt2160->keycodes[0]); 341fde11323SRaphael Derosso Pereira input->keycodemax = ARRAY_SIZE(qt2160_key2code); 342fde11323SRaphael Derosso Pereira 343fde11323SRaphael Derosso Pereira __set_bit(EV_KEY, input->evbit); 344fde11323SRaphael Derosso Pereira __clear_bit(EV_REP, input->evbit); 345fde11323SRaphael Derosso Pereira for (i = 0; i < ARRAY_SIZE(qt2160_key2code); i++) { 346fde11323SRaphael Derosso Pereira qt2160->keycodes[i] = qt2160_key2code[i]; 347fde11323SRaphael Derosso Pereira __set_bit(qt2160_key2code[i], input->keybit); 348fde11323SRaphael Derosso Pereira } 349fde11323SRaphael Derosso Pereira __clear_bit(KEY_RESERVED, input->keybit); 350fde11323SRaphael Derosso Pereira 351f1fbff60SDmitry Torokhov input_set_drvdata(input, qt2160); 352f1fbff60SDmitry Torokhov 353fde11323SRaphael Derosso Pereira /* Calibrate device */ 354fde11323SRaphael Derosso Pereira error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1); 355fde11323SRaphael Derosso Pereira if (error) { 356fde11323SRaphael Derosso Pereira dev_err(&client->dev, "failed to calibrate device\n"); 3573e4bb047SYangtao Li return error; 358fde11323SRaphael Derosso Pereira } 359fde11323SRaphael Derosso Pereira 360fde11323SRaphael Derosso Pereira if (client->irq) { 3613e4bb047SYangtao Li error = devm_request_threaded_irq(&client->dev, client->irq, 3623e4bb047SYangtao Li NULL, qt2160_irq, 3633e4bb047SYangtao Li IRQF_ONESHOT, 3643e4bb047SYangtao Li "qt2160", input); 365fde11323SRaphael Derosso Pereira if (error) { 366fde11323SRaphael Derosso Pereira dev_err(&client->dev, 367fde11323SRaphael Derosso Pereira "failed to allocate irq %d\n", client->irq); 3683e4bb047SYangtao Li return error; 369fde11323SRaphael Derosso Pereira } 370f1fbff60SDmitry Torokhov } else { 371f1fbff60SDmitry Torokhov error = input_setup_polling(input, qt2160_get_key_matrix); 372f1fbff60SDmitry Torokhov if (error) { 373f1fbff60SDmitry Torokhov dev_err(&client->dev, "Failed to setup polling\n"); 3743e4bb047SYangtao Li return error; 375f1fbff60SDmitry Torokhov } 376f1fbff60SDmitry Torokhov input_set_poll_interval(input, QT2160_CYCLE_INTERVAL); 377fde11323SRaphael Derosso Pereira } 378fde11323SRaphael Derosso Pereira 3790e47e3dcSJavier Martin error = qt2160_register_leds(qt2160); 3800e47e3dcSJavier Martin if (error) { 3810e47e3dcSJavier Martin dev_err(&client->dev, "Failed to register leds\n"); 3823e4bb047SYangtao Li return error; 3830e47e3dcSJavier Martin } 3840e47e3dcSJavier Martin 385fde11323SRaphael Derosso Pereira error = input_register_device(qt2160->input); 386fde11323SRaphael Derosso Pereira if (error) { 387fde11323SRaphael Derosso Pereira dev_err(&client->dev, 388fde11323SRaphael Derosso Pereira "Failed to register input device\n"); 389fde11323SRaphael Derosso Pereira return error; 390fde11323SRaphael Derosso Pereira } 391fde11323SRaphael Derosso Pereira 3923e4bb047SYangtao Li return 0; 393fde11323SRaphael Derosso Pereira } 394fde11323SRaphael Derosso Pereira 395ce7b39a1SMárton Németh static const struct i2c_device_id qt2160_idtable[] = { 396*5852f2afSUwe Kleine-König { "qt2160" }, 397fde11323SRaphael Derosso Pereira { } 398fde11323SRaphael Derosso Pereira }; 399fde11323SRaphael Derosso Pereira 400fde11323SRaphael Derosso Pereira MODULE_DEVICE_TABLE(i2c, qt2160_idtable); 401fde11323SRaphael Derosso Pereira 402fde11323SRaphael Derosso Pereira static struct i2c_driver qt2160_driver = { 403fde11323SRaphael Derosso Pereira .driver = { 404fde11323SRaphael Derosso Pereira .name = "qt2160", 405fde11323SRaphael Derosso Pereira }, 406fde11323SRaphael Derosso Pereira 407fde11323SRaphael Derosso Pereira .id_table = qt2160_idtable, 408d8bde56dSUwe Kleine-König .probe = qt2160_probe, 409fde11323SRaphael Derosso Pereira }; 410fde11323SRaphael Derosso Pereira 4111b92c1cfSAxel Lin module_i2c_driver(qt2160_driver); 412fde11323SRaphael Derosso Pereira 413fde11323SRaphael Derosso Pereira MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); 414fde11323SRaphael Derosso Pereira MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); 415fde11323SRaphael Derosso Pereira MODULE_LICENSE("GPL"); 416