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