root/drivers/input/keyboard/qt2160.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qt2160_led_set
  2. qt2160_read_block
  3. qt2160_get_key_matrix
  4. qt2160_irq
  5. qt2160_schedule_read
  6. qt2160_worker
  7. qt2160_read
  8. qt2160_write
  9. qt2160_register_leds
  10. qt2160_unregister_leds
  11. qt2160_register_leds
  12. qt2160_unregister_leds
  13. qt2160_identify
  14. qt2160_probe
  15. qt2160_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  qt2160.c - Atmel AT42QT2160 Touch Sense Controller
   4  *
   5  *  Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com>
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/leds.h>
  10 #include <linux/module.h>
  11 #include <linux/slab.h>
  12 #include <linux/jiffies.h>
  13 #include <linux/i2c.h>
  14 #include <linux/irq.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/input.h>
  17 
  18 #define QT2160_VALID_CHIPID  0x11
  19 
  20 #define QT2160_CMD_CHIPID     0
  21 #define QT2160_CMD_CODEVER    1
  22 #define QT2160_CMD_GSTAT      2
  23 #define QT2160_CMD_KEYS3      3
  24 #define QT2160_CMD_KEYS4      4
  25 #define QT2160_CMD_SLIDE      5
  26 #define QT2160_CMD_GPIOS      6
  27 #define QT2160_CMD_SUBVER     7
  28 #define QT2160_CMD_CALIBRATE  10
  29 #define QT2160_CMD_DRIVE_X    70
  30 #define QT2160_CMD_PWMEN_X    74
  31 #define QT2160_CMD_PWM_DUTY   76
  32 
  33 #define QT2160_NUM_LEDS_X       8
  34 
  35 #define QT2160_CYCLE_INTERVAL   (2*HZ)
  36 
  37 static unsigned char qt2160_key2code[] = {
  38         KEY_0, KEY_1, KEY_2, KEY_3,
  39         KEY_4, KEY_5, KEY_6, KEY_7,
  40         KEY_8, KEY_9, KEY_A, KEY_B,
  41         KEY_C, KEY_D, KEY_E, KEY_F,
  42 };
  43 
  44 #ifdef CONFIG_LEDS_CLASS
  45 struct qt2160_led {
  46         struct qt2160_data *qt2160;
  47         struct led_classdev cdev;
  48         char name[32];
  49         int id;
  50         enum led_brightness brightness;
  51 };
  52 #endif
  53 
  54 struct qt2160_data {
  55         struct i2c_client *client;
  56         struct input_dev *input;
  57         struct delayed_work dwork;
  58         unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)];
  59         u16 key_matrix;
  60 #ifdef CONFIG_LEDS_CLASS
  61         struct qt2160_led leds[QT2160_NUM_LEDS_X];
  62 #endif
  63 };
  64 
  65 static int qt2160_read(struct i2c_client *client, u8 reg);
  66 static int qt2160_write(struct i2c_client *client, u8 reg, u8 data);
  67 
  68 #ifdef CONFIG_LEDS_CLASS
  69 
  70 static int qt2160_led_set(struct led_classdev *cdev,
  71                           enum led_brightness value)
  72 {
  73         struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
  74         struct qt2160_data *qt2160 = led->qt2160;
  75         struct i2c_client *client = qt2160->client;
  76         u32 drive, pwmen;
  77 
  78         if (value != led->brightness) {
  79                 drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
  80                 pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
  81                 if (value != LED_OFF) {
  82                         drive |= BIT(led->id);
  83                         pwmen |= BIT(led->id);
  84 
  85                 } else {
  86                         drive &= ~BIT(led->id);
  87                         pwmen &= ~BIT(led->id);
  88                 }
  89                 qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
  90                 qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
  91 
  92                 /*
  93                  * Changing this register will change the brightness
  94                  * of every LED in the qt2160. It's a HW limitation.
  95                  */
  96                 if (value != LED_OFF)
  97                         qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
  98 
  99                 led->brightness = value;
 100         }
 101 
 102         return 0;
 103 }
 104 
 105 #endif /* CONFIG_LEDS_CLASS */
 106 
 107 static int qt2160_read_block(struct i2c_client *client,
 108                              u8 inireg, u8 *buffer, unsigned int count)
 109 {
 110         int error, idx = 0;
 111 
 112         /*
 113          * Can't use SMBus block data read. Check for I2C functionality to speed
 114          * things up whenever possible. Otherwise we will be forced to read
 115          * sequentially.
 116          */
 117         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))     {
 118 
 119                 error = i2c_smbus_write_byte(client, inireg + idx);
 120                 if (error) {
 121                         dev_err(&client->dev,
 122                                 "couldn't send request. Returned %d\n", error);
 123                         return error;
 124                 }
 125 
 126                 error = i2c_master_recv(client, buffer, count);
 127                 if (error != count) {
 128                         dev_err(&client->dev,
 129                                 "couldn't read registers. Returned %d bytes\n", error);
 130                         return error;
 131                 }
 132         } else {
 133 
 134                 while (count--) {
 135                         int data;
 136 
 137                         error = i2c_smbus_write_byte(client, inireg + idx);
 138                         if (error) {
 139                                 dev_err(&client->dev,
 140                                         "couldn't send request. Returned %d\n", error);
 141                                 return error;
 142                         }
 143 
 144                         data = i2c_smbus_read_byte(client);
 145                         if (data < 0) {
 146                                 dev_err(&client->dev,
 147                                         "couldn't read register. Returned %d\n", data);
 148                                 return data;
 149                         }
 150 
 151                         buffer[idx++] = data;
 152                 }
 153         }
 154 
 155         return 0;
 156 }
 157 
 158 static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
 159 {
 160         struct i2c_client *client = qt2160->client;
 161         struct input_dev *input = qt2160->input;
 162         u8 regs[6];
 163         u16 old_matrix, new_matrix;
 164         int ret, i, mask;
 165 
 166         dev_dbg(&client->dev, "requesting keys...\n");
 167 
 168         /*
 169          * Read all registers from General Status Register
 170          * to GPIOs register
 171          */
 172         ret = qt2160_read_block(client, QT2160_CMD_GSTAT, regs, 6);
 173         if (ret) {
 174                 dev_err(&client->dev,
 175                         "could not perform chip read.\n");
 176                 return ret;
 177         }
 178 
 179         old_matrix = qt2160->key_matrix;
 180         qt2160->key_matrix = new_matrix = (regs[2] << 8) | regs[1];
 181 
 182         mask = 0x01;
 183         for (i = 0; i < 16; ++i, mask <<= 1) {
 184                 int keyval = new_matrix & mask;
 185 
 186                 if ((old_matrix & mask) != keyval) {
 187                         input_report_key(input, qt2160->keycodes[i], keyval);
 188                         dev_dbg(&client->dev, "key %d %s\n",
 189                                 i, keyval ? "pressed" : "released");
 190                 }
 191         }
 192 
 193         input_sync(input);
 194 
 195         return 0;
 196 }
 197 
 198 static irqreturn_t qt2160_irq(int irq, void *_qt2160)
 199 {
 200         struct qt2160_data *qt2160 = _qt2160;
 201 
 202         mod_delayed_work(system_wq, &qt2160->dwork, 0);
 203 
 204         return IRQ_HANDLED;
 205 }
 206 
 207 static void qt2160_schedule_read(struct qt2160_data *qt2160)
 208 {
 209         schedule_delayed_work(&qt2160->dwork, QT2160_CYCLE_INTERVAL);
 210 }
 211 
 212 static void qt2160_worker(struct work_struct *work)
 213 {
 214         struct qt2160_data *qt2160 =
 215                 container_of(work, struct qt2160_data, dwork.work);
 216 
 217         dev_dbg(&qt2160->client->dev, "worker\n");
 218 
 219         qt2160_get_key_matrix(qt2160);
 220 
 221         /* Avoid device lock up by checking every so often */
 222         qt2160_schedule_read(qt2160);
 223 }
 224 
 225 static int qt2160_read(struct i2c_client *client, u8 reg)
 226 {
 227         int ret;
 228 
 229         ret = i2c_smbus_write_byte(client, reg);
 230         if (ret) {
 231                 dev_err(&client->dev,
 232                         "couldn't send request. Returned %d\n", ret);
 233                 return ret;
 234         }
 235 
 236         ret = i2c_smbus_read_byte(client);
 237         if (ret < 0) {
 238                 dev_err(&client->dev,
 239                         "couldn't read register. Returned %d\n", ret);
 240                 return ret;
 241         }
 242 
 243         return ret;
 244 }
 245 
 246 static int qt2160_write(struct i2c_client *client, u8 reg, u8 data)
 247 {
 248         int ret;
 249 
 250         ret = i2c_smbus_write_byte_data(client, reg, data);
 251         if (ret < 0)
 252                 dev_err(&client->dev,
 253                         "couldn't write data. Returned %d\n", ret);
 254 
 255         return ret;
 256 }
 257 
 258 #ifdef CONFIG_LEDS_CLASS
 259 
 260 static int qt2160_register_leds(struct qt2160_data *qt2160)
 261 {
 262         struct i2c_client *client = qt2160->client;
 263         int ret;
 264         int i;
 265 
 266         for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
 267                 struct qt2160_led *led = &qt2160->leds[i];
 268 
 269                 snprintf(led->name, sizeof(led->name), "qt2160:x%d", i);
 270                 led->cdev.name = led->name;
 271                 led->cdev.brightness_set_blocking = qt2160_led_set;
 272                 led->cdev.brightness = LED_OFF;
 273                 led->id = i;
 274                 led->qt2160 = qt2160;
 275 
 276                 ret = led_classdev_register(&client->dev, &led->cdev);
 277                 if (ret < 0)
 278                         return ret;
 279         }
 280 
 281         /* Tur off LEDs */
 282         qt2160_write(client, QT2160_CMD_DRIVE_X, 0);
 283         qt2160_write(client, QT2160_CMD_PWMEN_X, 0);
 284         qt2160_write(client, QT2160_CMD_PWM_DUTY, 0);
 285 
 286         return 0;
 287 }
 288 
 289 static void qt2160_unregister_leds(struct qt2160_data *qt2160)
 290 {
 291         int i;
 292 
 293         for (i = 0; i < QT2160_NUM_LEDS_X; i++)
 294                 led_classdev_unregister(&qt2160->leds[i].cdev);
 295 }
 296 
 297 #else
 298 
 299 static inline int qt2160_register_leds(struct qt2160_data *qt2160)
 300 {
 301         return 0;
 302 }
 303 
 304 static inline void qt2160_unregister_leds(struct qt2160_data *qt2160)
 305 {
 306 }
 307 
 308 #endif
 309 
 310 static bool qt2160_identify(struct i2c_client *client)
 311 {
 312         int id, ver, rev;
 313 
 314         /* Read Chid ID to check if chip is valid */
 315         id = qt2160_read(client, QT2160_CMD_CHIPID);
 316         if (id != QT2160_VALID_CHIPID) {
 317                 dev_err(&client->dev, "ID %d not supported\n", id);
 318                 return false;
 319         }
 320 
 321         /* Read chip firmware version */
 322         ver = qt2160_read(client, QT2160_CMD_CODEVER);
 323         if (ver < 0) {
 324                 dev_err(&client->dev, "could not get firmware version\n");
 325                 return false;
 326         }
 327 
 328         /* Read chip firmware revision */
 329         rev = qt2160_read(client, QT2160_CMD_SUBVER);
 330         if (rev < 0) {
 331                 dev_err(&client->dev, "could not get firmware revision\n");
 332                 return false;
 333         }
 334 
 335         dev_info(&client->dev, "AT42QT2160 firmware version %d.%d.%d\n",
 336                         ver >> 4, ver & 0xf, rev);
 337 
 338         return true;
 339 }
 340 
 341 static int qt2160_probe(struct i2c_client *client,
 342                         const struct i2c_device_id *id)
 343 {
 344         struct qt2160_data *qt2160;
 345         struct input_dev *input;
 346         int i;
 347         int error;
 348 
 349         /* Check functionality */
 350         error = i2c_check_functionality(client->adapter,
 351                         I2C_FUNC_SMBUS_BYTE);
 352         if (!error) {
 353                 dev_err(&client->dev, "%s adapter not supported\n",
 354                                 dev_driver_string(&client->adapter->dev));
 355                 return -ENODEV;
 356         }
 357 
 358         if (!qt2160_identify(client))
 359                 return -ENODEV;
 360 
 361         /* Chip is valid and active. Allocate structure */
 362         qt2160 = kzalloc(sizeof(struct qt2160_data), GFP_KERNEL);
 363         input = input_allocate_device();
 364         if (!qt2160 || !input) {
 365                 dev_err(&client->dev, "insufficient memory\n");
 366                 error = -ENOMEM;
 367                 goto err_free_mem;
 368         }
 369 
 370         qt2160->client = client;
 371         qt2160->input = input;
 372         INIT_DELAYED_WORK(&qt2160->dwork, qt2160_worker);
 373 
 374         input->name = "AT42QT2160 Touch Sense Keyboard";
 375         input->id.bustype = BUS_I2C;
 376 
 377         input->keycode = qt2160->keycodes;
 378         input->keycodesize = sizeof(qt2160->keycodes[0]);
 379         input->keycodemax = ARRAY_SIZE(qt2160_key2code);
 380 
 381         __set_bit(EV_KEY, input->evbit);
 382         __clear_bit(EV_REP, input->evbit);
 383         for (i = 0; i < ARRAY_SIZE(qt2160_key2code); i++) {
 384                 qt2160->keycodes[i] = qt2160_key2code[i];
 385                 __set_bit(qt2160_key2code[i], input->keybit);
 386         }
 387         __clear_bit(KEY_RESERVED, input->keybit);
 388 
 389         /* Calibrate device */
 390         error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1);
 391         if (error) {
 392                 dev_err(&client->dev, "failed to calibrate device\n");
 393                 goto err_free_mem;
 394         }
 395 
 396         if (client->irq) {
 397                 error = request_irq(client->irq, qt2160_irq,
 398                                     IRQF_TRIGGER_FALLING, "qt2160", qt2160);
 399                 if (error) {
 400                         dev_err(&client->dev,
 401                                 "failed to allocate irq %d\n", client->irq);
 402                         goto err_free_mem;
 403                 }
 404         }
 405 
 406         error = qt2160_register_leds(qt2160);
 407         if (error) {
 408                 dev_err(&client->dev, "Failed to register leds\n");
 409                 goto err_free_irq;
 410         }
 411 
 412         error = input_register_device(qt2160->input);
 413         if (error) {
 414                 dev_err(&client->dev,
 415                         "Failed to register input device\n");
 416                 goto err_unregister_leds;
 417         }
 418 
 419         i2c_set_clientdata(client, qt2160);
 420         qt2160_schedule_read(qt2160);
 421 
 422         return 0;
 423 
 424 err_unregister_leds:
 425         qt2160_unregister_leds(qt2160);
 426 err_free_irq:
 427         if (client->irq)
 428                 free_irq(client->irq, qt2160);
 429 err_free_mem:
 430         input_free_device(input);
 431         kfree(qt2160);
 432         return error;
 433 }
 434 
 435 static int qt2160_remove(struct i2c_client *client)
 436 {
 437         struct qt2160_data *qt2160 = i2c_get_clientdata(client);
 438 
 439         qt2160_unregister_leds(qt2160);
 440 
 441         /* Release IRQ so no queue will be scheduled */
 442         if (client->irq)
 443                 free_irq(client->irq, qt2160);
 444 
 445         cancel_delayed_work_sync(&qt2160->dwork);
 446 
 447         input_unregister_device(qt2160->input);
 448         kfree(qt2160);
 449 
 450         return 0;
 451 }
 452 
 453 static const struct i2c_device_id qt2160_idtable[] = {
 454         { "qt2160", 0, },
 455         { }
 456 };
 457 
 458 MODULE_DEVICE_TABLE(i2c, qt2160_idtable);
 459 
 460 static struct i2c_driver qt2160_driver = {
 461         .driver = {
 462                 .name   = "qt2160",
 463         },
 464 
 465         .id_table       = qt2160_idtable,
 466         .probe          = qt2160_probe,
 467         .remove         = qt2160_remove,
 468 };
 469 
 470 module_i2c_driver(qt2160_driver);
 471 
 472 MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>");
 473 MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor");
 474 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */