2 * mcs_touchkey.c - Touchkey driver for MELFAS MCS5000/5080 controller
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: HeungJun Kim <riverful.kim@samsung.com>
6 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/i2c.h>
17 #include <linux/i2c/mcs.h>
18 #include <linux/interrupt.h>
19 #include <linux/input.h>
20 #include <linux/irq.h>
21 #include <linux/slab.h>
22 #include <linux/workqueue.h>
23 #include <linux/delay.h>
24 #include <linux/gpio.h>
25 #include <linux/pm_runtime.h>
27 #include <plat/gpio-cfg.h>
29 /* MCS5000 Touchkey */
30 #define MCS5000_TOUCHKEY_STATUS 0x04
31 #define MCS5000_TOUCHKEY_STATUS_PRESS 7
32 #define MCS5000_TOUCHKEY_FW 0x0a
33 #define MCS5000_TOUCHKEY_BASE_VAL 0x61
35 /* MCS5080 Touchkey */
36 #define MCS5080_TOUCHKEY_STATUS 0x00
37 #define MCS5080_TOUCHKEY_STATUS_PRESS 3
38 #define MCS5080_TOUCHKEY_FW 0x01
39 #define MCS5080_TOUCHKEY_BASE_VAL 0x1
41 #define PRESS_LED_TIME 500
42 #define WAKEUP_LED_TIME 5000
44 enum mcs_touchkey_type {
49 struct mcs_touchkey_chip {
50 unsigned int status_reg;
51 unsigned int pressbit;
52 unsigned int press_invert;
56 struct mcs_touchkey_data {
57 struct i2c_client *client;
58 struct input_dev *input_dev;
59 struct mcs_touchkey_chip chip;
60 struct delayed_work work;
61 void (*poweron)(bool);
62 void (*cfg_pin_fw)(int);
63 unsigned int touchkey_enable;
64 unsigned int key_code;
67 /* The framebuffer notifier block */
68 struct notifier_block fb_notif;
70 unsigned short keycodes[];
73 static void mcs_touchkey_led(struct mcs_touchkey_data *data, int on)
77 if (!data->touchkey_enable)
84 i2c_master_send(data->client, &buf, 1);
87 static void mcs_touchkey_work(struct work_struct *work)
89 struct delayed_work *dw = to_delayed_work(work);
90 struct mcs_touchkey_data *data;
92 data = container_of(dw, struct mcs_touchkey_data, work);
94 mcs_touchkey_led(data, 0);
97 static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
99 struct mcs_touchkey_data *data = dev_id;
100 struct mcs_touchkey_chip *chip = &data->chip;
101 struct i2c_client *client = data->client;
102 struct input_dev *input = data->input_dev;
103 unsigned int key_val;
104 unsigned int pressed;
107 val = i2c_smbus_read_byte_data(client, chip->status_reg);
109 dev_err(&client->dev, "i2c read error [%d]\n", val);
113 pressed = (val & (1 << chip->pressbit)) >> chip->pressbit;
114 if (chip->press_invert)
115 pressed ^= chip->press_invert;
117 /* key_val is 0 when released, so we should use key_val of press. */
119 key_val = val & (0xff >> (8 - chip->pressbit));
122 key_val -= chip->baseval;
123 data->key_code = data->keycodes[key_val];
124 data->key_val = key_val;
127 input_event(input, EV_MSC, MSC_SCAN, data->key_val);
128 input_report_key(input, data->key_code, pressed);
132 cancel_work_sync(&data->work.work);
133 mcs_touchkey_led(data, 1);
135 if (!delayed_work_pending(&data->work))
136 schedule_delayed_work(&data->work,
137 msecs_to_jiffies(PRESS_LED_TIME));
140 dev_dbg(&client->dev, "key %d %d %s\n", data->key_val, data->key_code,
141 pressed ? "pressed" : "released");
146 static u8 mcs_i2c_read(struct i2c_client *client, u8 cmd, u8 *rval, int size)
148 struct i2c_msg msg[2];
151 msg[0].addr = client->addr;
152 msg[0].flags = client->flags | I2C_M_RD;
154 msg[0].buf = (char *)rval;
158 ret = i2c_transfer(client->adapter, msg, wret);
160 dev_err(&client->dev, "failed i2c transfer ret %d, "
161 "cmd %02x, rval %02x\n", ret, cmd, *rval);
165 static int mcs_fw_update(struct mcs_touchkey_data *data, const char *fn)
167 struct i2c_client *client = data->client;
170 dev_info(&client->dev, "[TK] firmware file : %s\n", fn);
172 /* set mode FW download */
173 disable_irq(client->irq);
175 ret = mcsdl_download_binary_data();
177 dev_info(&client->dev, "[TK] failed to update.\n");
179 dev_info(&client->dev, "[TK] succeeded to update.\n");
182 /* set mode touchkey mode */
183 enable_irq(client->irq);
192 static ssize_t mcs_firmware_store(struct device *dev,
193 struct device_attribute *attr, const char *buf, size_t count)
195 struct mcs_touchkey_data *data = dev_get_drvdata(dev);
196 struct i2c_client *client = data->client;
201 sscanf(buf, "%d", &type);
204 dev_info(&client->dev, "[TK] firmware update\n");
206 /* set mode FW download */
207 disable_irq(client->irq);
209 ret = mcsdl_download_binary_data();
211 dev_info(&client->dev, "[TK] failed to update.\n");
213 dev_info(&client->dev, "[TK] succeeded to update.\n");
216 /* set mode touchkey mode */
217 enable_irq(client->irq);
223 } else if (type == 2) {
224 ret = mcs_fw_update(data, "MTH-KESSLER-R01_V82.bin");
226 dev_info(&client->dev, "[TK] failed to update.\n");
228 dev_info(&client->dev, "[TK] succeeded to update.\n");
231 dev_info(&client->dev, "[TK] wrong command\n");
237 static ssize_t mcs_firmware_show(struct device *dev,
238 struct device_attribute *attr, char *buf)
240 struct mcs_touchkey_data *data = dev_get_drvdata(dev);
241 struct i2c_client *client = data->client;
245 err = mcs_i2c_read(client, MCS5080_TOUCHKEY_STATUS, buffer, 3);
247 dev_err(&client->dev, "%s: error\n", __func__);
249 dev_info(&client->dev, "[TK] firmware version = 0x%x, "
250 "Module version = 0x%x\n",
251 buffer[1], buffer[2]);
255 static DEVICE_ATTR(fw_update, 0664, mcs_firmware_show, mcs_firmware_store);
257 static struct attribute *mcs_attrs[] = {
258 &dev_attr_fw_update.attr,
262 static const struct attribute_group mcs_attr_group = {
266 static void mcs_touchkey_enable(struct mcs_touchkey_data *data)
268 struct i2c_client *client = data->client;
270 if (data->touchkey_enable == 1)
273 /* Enable the device first */
277 /* Enable irq again */
278 enable_irq(client->irq);
280 if (!delayed_work_pending(&data->work))
281 schedule_delayed_work(&data->work,
282 msecs_to_jiffies(WAKEUP_LED_TIME));
284 /* Set touchkey state as enable */
285 data->touchkey_enable = 1;
288 static void mcs_touchkey_disable(struct mcs_touchkey_data *data)
290 struct i2c_client *client = data->client;
292 if (data->touchkey_enable == 0)
296 mcs_touchkey_led(data, 0);
298 /* Disable the work */
299 disable_irq(client->irq);
300 cancel_delayed_work_sync(&data->work);
302 /* Finally turn off the power */
306 /* Set touchkey state as disable */
307 data->touchkey_enable = 0;
310 static int mcs_touchkey_fb_notifier_callback(struct notifier_block *self,
311 unsigned long event, void *fb_evdata)
313 struct mcs_touchkey_data *data;
314 struct fb_event *evdata = fb_evdata;
317 /* If we aren't interested in this event, skip it immediately ... */
318 if (event != FB_EVENT_BLANK)
321 data = container_of(self, struct mcs_touchkey_data, fb_notif);
322 blank = *(int *)evdata->data;
326 mcs_touchkey_enable(data);
329 mcs_touchkey_disable(data);
338 static int __devinit mcs_touchkey_probe(struct i2c_client *client,
339 const struct i2c_device_id *id)
341 const struct mcs_platform_data *pdata;
342 struct mcs_touchkey_data *data;
343 struct input_dev *input_dev;
344 struct device *dev = &client->dev;
353 pdata = client->dev.platform_data;
355 dev_err(&client->dev, "no platform data defined\n");
359 data = kzalloc(sizeof(struct mcs_touchkey_data) +
360 sizeof(data->keycodes[0]) * (pdata->key_maxval + 1),
362 input_dev = input_allocate_device();
363 if (!data || !input_dev) {
364 dev_err(dev, "Failed to allocate memory\n");
369 data->client = client;
370 data->input_dev = input_dev;
372 data->poweron = pdata->poweron;
373 data->cfg_pin_fw = pdata->cfg_pin_fw;
378 if (id->driver_data == MCS5000_TOUCHKEY) {
379 data->chip.status_reg = MCS5000_TOUCHKEY_STATUS;
380 data->chip.pressbit = MCS5000_TOUCHKEY_STATUS_PRESS;
381 data->chip.baseval = MCS5000_TOUCHKEY_BASE_VAL;
382 fw_reg = MCS5000_TOUCHKEY_FW;
384 data->chip.status_reg = MCS5080_TOUCHKEY_STATUS;
385 data->chip.pressbit = MCS5080_TOUCHKEY_STATUS_PRESS;
386 data->chip.press_invert = 1;
387 data->chip.baseval = MCS5080_TOUCHKEY_BASE_VAL;
388 fw_reg = MCS5080_TOUCHKEY_FW;
391 fw_ver = i2c_smbus_read_byte_data(client, fw_reg);
394 dev_err(dev, "i2c read error[%d]\n", error);
397 dev_info(dev, "Firmware version: %d\n", fw_ver);
399 input_dev->name = "MELFAS MCS Touchkey";
400 input_dev->id.bustype = BUS_I2C;
401 input_dev->dev.parent = &client->dev;
402 input_dev->evbit[0] = BIT_MASK(EV_KEY);
403 if (!pdata->no_autorepeat)
404 input_dev->evbit[0] |= BIT_MASK(EV_REP);
405 input_dev->keycode = data->keycodes;
406 input_dev->keycodesize = sizeof(data->keycodes[0]);
407 input_dev->keycodemax = pdata->key_maxval + 1;
409 for (i = 0; i < pdata->keymap_size; i++) {
410 unsigned int val = MCS_KEY_VAL(pdata->keymap[i]);
411 unsigned int code = MCS_KEY_CODE(pdata->keymap[i]);
413 data->keycodes[val] = code;
414 __set_bit(code, input_dev->keybit);
417 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
418 input_set_drvdata(input_dev, data);
420 INIT_DELAYED_WORK(&data->work, mcs_touchkey_work);
422 error = input_register_device(input_dev);
426 i2c_set_clientdata(client, data);
428 error = sysfs_create_group(&client->dev.kobj, &mcs_attr_group);
430 dev_err(dev, "[TK] make sysfs_create_group error\n");
432 /* After all, set the firmware setting */
433 error = mcsdl_set_i2c_client(client);
436 if (id->driver_data != MCS5080_TOUCHKEY)
439 error = mcs_i2c_read(client, MCS5080_TOUCHKEY_STATUS, buffer, 3);
441 dev_err(dev, "%s: error\n", __func__);
444 dev_info(dev, "[TK] FW ver = 0x%x, " "MD(Module) ver = 0x%x\n",
445 buffer[1], buffer[2]);
447 error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt,
448 IRQF_TRIGGER_FALLING, client->dev.driver->name, data);
450 dev_err(dev, "Failed to register interrupt\n");
454 data->touchkey_enable = 1;
455 mcs_touchkey_disable(data);
456 /* To turn off touchkey when LCD turns off */
457 data->fb_notif.notifier_call = mcs_touchkey_fb_notifier_callback;
458 fb_register_client(&data->fb_notif);
460 /* TODO: Touchkey power change from GPIO to PMIC */
462 if ((buffer[2] != pdata->md_ver) || ((buffer[2] == pdata->md_ver) &&
463 (buffer[1] < pdata->fw_ver))) {
464 dev_info(dev, "[TK] FW auto update!\n");
465 dev_info(dev, "[TK] MTH-KESSLER-R%x_V%x.bin ->"
466 "MTH-KESSLER-R%x_V%x.bin\n",
467 buffer[2], buffer[1], pdata->md_ver, pdata->fw_ver);
468 error = mcs_fw_update(data, "MTH-KESSLER-R01_V02.bin");
470 dev_info(dev, "[TK] failed to FW update.\n");
472 dev_info(dev, "[TK] succeeded to FW update.\n");
476 /* enable runtime pm */
477 pm_runtime_set_active(dev);
482 free_irq(client->irq, data);
484 input_free_device(input_dev);
489 static int __devexit mcs_touchkey_remove(struct i2c_client *client)
491 struct mcs_touchkey_data *data = i2c_get_clientdata(client);
493 free_irq(client->irq, data);
494 input_unregister_device(data->input_dev);
500 static void mcs_touchkey_shutdown(struct i2c_client *client)
502 struct mcs_touchkey_data *data = i2c_get_clientdata(client);
508 static const struct i2c_device_id mcs_touchkey_id[] = {
509 { "mcs5000_touchkey", MCS5000_TOUCHKEY },
510 { "mcs5080_touchkey", MCS5080_TOUCHKEY },
513 MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id);
515 static struct i2c_driver mcs_touchkey_driver = {
517 .name = "mcs_touchkey",
518 .owner = THIS_MODULE,
520 .probe = mcs_touchkey_probe,
521 .remove = __devexit_p(mcs_touchkey_remove),
522 .shutdown = mcs_touchkey_shutdown,
523 .id_table = mcs_touchkey_id,
526 static int __init mcs_touchkey_init(void)
528 return i2c_add_driver(&mcs_touchkey_driver);
531 static void __exit mcs_touchkey_exit(void)
533 i2c_del_driver(&mcs_touchkey_driver);
536 module_init(mcs_touchkey_init);
537 module_exit(mcs_touchkey_exit);
539 /* Module information */
540 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
541 MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
542 MODULE_DESCRIPTION("Touchkey driver for MELFAS MCS5000/5080 controller");
543 MODULE_LICENSE("GPL");