xref: /openbmc/linux/drivers/input/keyboard/qt2160.c (revision 83cd2030)
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");
497