2 * drivers/input/touchscreen/panjit_i2c.c
4 * Touchscreen class input driver for Panjit touch panel using I2C bus
6 * Copyright (c) 2010, NVIDIA Corporation.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <linux/module.h>
24 #include <linux/device.h>
25 #include <linux/input.h>
26 #include <linux/delay.h>
27 #include <linux/earlysuspend.h>
28 #include <linux/i2c.h>
29 #include <linux/i2c/panjit_ts.h>
30 #include <linux/interrupt.h>
31 #include <linux/gpio.h>
32 #include <linux/slab.h>
35 #define CSR_SCAN_EN (1 << 3)
36 #define CSR_SLEEP_EN (1 << 7)
40 #define DRIVER_NAME "panjit_touch"
42 #ifdef CONFIG_HAS_EARLYSUSPEND
43 static void pj_early_suspend(struct early_suspend *h);
44 static void pj_late_resume(struct early_suspend *h);
48 struct input_dev *input_dev;
49 struct i2c_client *client;
51 struct early_suspend early_suspend;
62 unsigned char buff[sizeof(struct pj_data)];
65 static void pj_reset(struct pj_data *touch)
67 if (touch->gpio_reset < 0)
70 gpio_set_value(touch->gpio_reset, 1);
72 gpio_set_value(touch->gpio_reset, 0);
76 static irqreturn_t pj_irq(int irq, void *dev_id)
78 struct pj_data *touch = dev_id;
79 struct i2c_client *client = touch->client;
83 ret = i2c_smbus_read_i2c_block_data(client, X1_H,
84 sizeof(event.buff), event.buff);
85 if (WARN_ON(ret < 0)) {
86 dev_err(&client->dev, "error %d reading event data\n", ret);
89 ret = i2c_smbus_write_byte_data(client, C_FLAG, 0);
90 if (WARN_ON(ret < 0)) {
91 dev_err(&client->dev, "error %d clearing interrupt\n", ret);
95 input_report_key(touch->input_dev, BTN_TOUCH,
96 (event.data.fingers == 1 || event.data.fingers == 2));
97 input_report_key(touch->input_dev, BTN_2, (event.data.fingers == 2));
99 if (!event.data.fingers || (event.data.fingers > 2))
102 for (i = 0; i < event.data.fingers; i++) {
103 input_report_abs(touch->input_dev, ABS_MT_POSITION_X,
104 __be16_to_cpu(event.data.coord[i][0]));
105 input_report_abs(touch->input_dev, ABS_MT_POSITION_Y,
106 __be16_to_cpu(event.data.coord[i][1]));
107 input_report_abs(touch->input_dev, ABS_MT_TRACKING_ID, i + 1);
108 input_mt_sync(touch->input_dev);
112 input_sync(touch->input_dev);
116 static int pj_probe(struct i2c_client *client,
117 const struct i2c_device_id *id)
119 struct panjit_i2c_ts_platform_data *pdata = client->dev.platform_data;
120 struct pj_data *touch = NULL;
121 struct input_dev *input_dev = NULL;
124 touch = kzalloc(sizeof(struct pj_data), GFP_KERNEL);
126 dev_err(&client->dev, "%s: no memory\n", __func__);
130 touch->gpio_reset = -EINVAL;
133 ret = gpio_request(pdata->gpio_reset, "panjit_reset");
135 ret = gpio_direction_output(pdata->gpio_reset, 1);
137 gpio_free(pdata->gpio_reset);
141 touch->gpio_reset = pdata->gpio_reset;
143 dev_warn(&client->dev, "unable to configure GPIO\n");
146 input_dev = input_allocate_device();
148 dev_err(&client->dev, "%s: no memory\n", __func__);
153 touch->client = client;
154 i2c_set_clientdata(client, touch);
158 /* clear interrupt */
159 ret = i2c_smbus_write_byte_data(touch->client, C_FLAG, 0);
161 dev_err(&client->dev, "%s: clear interrupt failed\n",
163 goto fail_i2c_or_register;
166 /* enable scanning */
167 ret = i2c_smbus_write_byte_data(touch->client, CSR, CSR_SCAN_EN);
169 dev_err(&client->dev, "%s: enable interrupt failed\n",
171 goto fail_i2c_or_register;
174 touch->input_dev = input_dev;
175 touch->input_dev->name = DRIVER_NAME;
177 set_bit(EV_SYN, touch->input_dev->evbit);
178 set_bit(EV_KEY, touch->input_dev->evbit);
179 set_bit(EV_ABS, touch->input_dev->evbit);
180 set_bit(BTN_TOUCH, touch->input_dev->keybit);
181 set_bit(BTN_2, touch->input_dev->keybit);
183 /* expose multi-touch capabilities */
184 set_bit(ABS_MT_POSITION_X, touch->input_dev->keybit);
185 set_bit(ABS_MT_POSITION_Y, touch->input_dev->keybit);
186 set_bit(ABS_X, touch->input_dev->keybit);
187 set_bit(ABS_Y, touch->input_dev->keybit);
189 /* all coordinates are reported in 0..4095 */
190 input_set_abs_params(touch->input_dev, ABS_X, 0, 4095, 0, 0);
191 input_set_abs_params(touch->input_dev, ABS_Y, 0, 4095, 0, 0);
192 input_set_abs_params(touch->input_dev, ABS_HAT0X, 0, 4095, 0, 0);
193 input_set_abs_params(touch->input_dev, ABS_HAT0Y, 0, 4095, 0, 0);
194 input_set_abs_params(touch->input_dev, ABS_HAT1X, 0, 4095, 0, 0);
195 input_set_abs_params(touch->input_dev, ABS_HAT1Y, 0, 4095, 0, 0);
197 input_set_abs_params(touch->input_dev, ABS_MT_POSITION_X, 0, 4095, 0, 0);
198 input_set_abs_params(touch->input_dev, ABS_MT_POSITION_Y, 0, 4095, 0, 0);
199 input_set_abs_params(touch->input_dev, ABS_MT_TRACKING_ID, 0, 2, 1, 0);
201 ret = input_register_device(touch->input_dev);
203 dev_err(&client->dev, "%s: input_register_device failed\n",
205 goto fail_i2c_or_register;
209 ret = request_threaded_irq(touch->client->irq, NULL, pj_irq,
210 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
213 dev_err(&client->dev, "%s: request_irq(%d) failed\n",
214 __func__, touch->client->irq);
218 #ifdef CONFIG_HAS_EARLYSUSPEND
219 touch->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
220 touch->early_suspend.suspend = pj_early_suspend;
221 touch->early_suspend.resume = pj_late_resume;
222 register_early_suspend(&touch->early_suspend);
224 dev_info(&client->dev, "%s: initialized\n", __func__);
228 input_unregister_device(touch->input_dev);
230 fail_i2c_or_register:
231 if (touch->gpio_reset >= 0)
232 gpio_free(touch->gpio_reset);
234 input_free_device(input_dev);
239 static int pj_suspend(struct i2c_client *client, pm_message_t state)
241 struct pj_data *touch = i2c_get_clientdata(client);
247 disable_irq(client->irq);
249 /* disable scanning and enable deep sleep */
250 ret = i2c_smbus_write_byte_data(client, CSR, CSR_SLEEP_EN);
252 dev_err(&client->dev, "%s: sleep enable fail\n", __func__);
259 static int pj_resume(struct i2c_client *client)
261 struct pj_data *touch = i2c_get_clientdata(client);
269 /* enable scanning and disable deep sleep */
270 ret = i2c_smbus_write_byte_data(client, C_FLAG, 0);
272 ret = i2c_smbus_write_byte_data(client, CSR, CSR_SCAN_EN);
274 dev_err(&client->dev, "%s: scan enable fail\n", __func__);
278 enable_irq(client->irq);
283 #ifdef CONFIG_HAS_EARLYSUSPEND
284 static void pj_early_suspend(struct early_suspend *es)
286 struct pj_data *touch;
287 touch = container_of(es, struct pj_data, early_suspend);
289 if (pj_suspend(touch->client, PMSG_SUSPEND) != 0)
290 dev_err(&touch->client->dev, "%s: failed\n", __func__);
293 static void pj_late_resume(struct early_suspend *es)
295 struct pj_data *touch;
296 touch = container_of(es, struct pj_data, early_suspend);
298 if (pj_resume(touch->client) != 0)
299 dev_err(&touch->client->dev, "%s: failed\n", __func__);
303 static int pj_remove(struct i2c_client *client)
305 struct pj_data *touch = i2c_get_clientdata(client);
310 #ifdef CONFIG_HAS_EARLYSUSPEND
311 unregister_early_suspend(&touch->early_suspend);
313 free_irq(touch->client->irq, touch);
314 if (touch->gpio_reset >= 0)
315 gpio_free(touch->gpio_reset);
316 input_unregister_device(touch->input_dev);
317 input_free_device(touch->input_dev);
322 static const struct i2c_device_id panjit_ts_id[] = {
327 static struct i2c_driver panjit_driver = {
330 #ifndef CONFIG_HAS_EARLYSUSPEND
331 .suspend = pj_suspend,
334 .id_table = panjit_ts_id,
340 static int __devinit panjit_init(void)
344 e = i2c_add_driver(&panjit_driver);
346 pr_err("%s: failed to register with I2C bus with "
347 "error: 0x%x\n", __func__, e);
352 static void __exit panjit_exit(void)
354 i2c_del_driver(&panjit_driver);
357 module_init(panjit_init);
358 module_exit(panjit_exit);
360 MODULE_LICENSE("GPL");
361 MODULE_DESCRIPTION("Panjit I2C touch driver");