2 * Driver for Pixcir I2C touchscreen controllers.
4 * Copyright (C) 2010-2011 Pixcir, Inc.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/delay.h>
21 #include <linux/module.h>
22 #include <linux/interrupt.h>
23 #include <linux/slab.h>
24 #include <linux/i2c.h>
25 #include <linux/input.h>
26 #include <linux/input/pixcir_ts.h>
28 struct pixcir_i2c_ts_data
{
29 struct i2c_client
*client
;
30 struct input_dev
*input
;
31 const struct pixcir_ts_platform_data
*chip
;
35 static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data
*data
)
37 struct pixcir_i2c_ts_data
*tsdata
= data
;
38 u8 rdbuf
[10], wrbuf
[1] = { 0 };
42 ret
= i2c_master_send(tsdata
->client
, wrbuf
, sizeof(wrbuf
));
43 if (ret
!= sizeof(wrbuf
)) {
44 dev_err(&tsdata
->client
->dev
,
45 "%s: i2c_master_send failed(), ret=%d\n",
50 ret
= i2c_master_recv(tsdata
->client
, rdbuf
, sizeof(rdbuf
));
51 if (ret
!= sizeof(rdbuf
)) {
52 dev_err(&tsdata
->client
->dev
,
53 "%s: i2c_master_recv failed(), ret=%d\n",
60 u16 posx1
= (rdbuf
[3] << 8) | rdbuf
[2];
61 u16 posy1
= (rdbuf
[5] << 8) | rdbuf
[4];
62 u16 posx2
= (rdbuf
[7] << 8) | rdbuf
[6];
63 u16 posy2
= (rdbuf
[9] << 8) | rdbuf
[8];
65 input_report_key(tsdata
->input
, BTN_TOUCH
, 1);
66 input_report_abs(tsdata
->input
, ABS_X
, posx1
);
67 input_report_abs(tsdata
->input
, ABS_Y
, posy1
);
69 input_report_abs(tsdata
->input
, ABS_MT_POSITION_X
, posx1
);
70 input_report_abs(tsdata
->input
, ABS_MT_POSITION_Y
, posy1
);
71 input_mt_sync(tsdata
->input
);
74 input_report_abs(tsdata
->input
,
75 ABS_MT_POSITION_X
, posx2
);
76 input_report_abs(tsdata
->input
,
77 ABS_MT_POSITION_Y
, posy2
);
78 input_mt_sync(tsdata
->input
);
81 input_report_key(tsdata
->input
, BTN_TOUCH
, 0);
84 input_sync(tsdata
->input
);
87 static irqreturn_t
pixcir_ts_isr(int irq
, void *dev_id
)
89 struct pixcir_i2c_ts_data
*tsdata
= dev_id
;
91 while (!tsdata
->exiting
) {
92 pixcir_ts_poscheck(tsdata
);
94 if (tsdata
->chip
->attb_read_val())
103 #ifdef CONFIG_PM_SLEEP
104 static int pixcir_i2c_ts_suspend(struct device
*dev
)
106 struct i2c_client
*client
= to_i2c_client(dev
);
108 if (device_may_wakeup(&client
->dev
))
109 enable_irq_wake(client
->irq
);
114 static int pixcir_i2c_ts_resume(struct device
*dev
)
116 struct i2c_client
*client
= to_i2c_client(dev
);
118 if (device_may_wakeup(&client
->dev
))
119 disable_irq_wake(client
->irq
);
125 static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops
,
126 pixcir_i2c_ts_suspend
, pixcir_i2c_ts_resume
);
128 static int pixcir_i2c_ts_probe(struct i2c_client
*client
,
129 const struct i2c_device_id
*id
)
131 const struct pixcir_ts_platform_data
*pdata
=
132 dev_get_platdata(&client
->dev
);
133 struct pixcir_i2c_ts_data
*tsdata
;
134 struct input_dev
*input
;
138 dev_err(&client
->dev
, "platform data not defined\n");
142 tsdata
= kzalloc(sizeof(*tsdata
), GFP_KERNEL
);
143 input
= input_allocate_device();
144 if (!tsdata
|| !input
) {
145 dev_err(&client
->dev
, "Failed to allocate driver data!\n");
150 tsdata
->client
= client
;
151 tsdata
->input
= input
;
152 tsdata
->chip
= pdata
;
154 input
->name
= client
->name
;
155 input
->id
.bustype
= BUS_I2C
;
156 input
->dev
.parent
= &client
->dev
;
158 __set_bit(EV_KEY
, input
->evbit
);
159 __set_bit(EV_ABS
, input
->evbit
);
160 __set_bit(BTN_TOUCH
, input
->keybit
);
161 input_set_abs_params(input
, ABS_X
, 0, pdata
->x_max
, 0, 0);
162 input_set_abs_params(input
, ABS_Y
, 0, pdata
->y_max
, 0, 0);
163 input_set_abs_params(input
, ABS_MT_POSITION_X
, 0, pdata
->x_max
, 0, 0);
164 input_set_abs_params(input
, ABS_MT_POSITION_Y
, 0, pdata
->y_max
, 0, 0);
166 input_set_drvdata(input
, tsdata
);
168 error
= request_threaded_irq(client
->irq
, NULL
, pixcir_ts_isr
,
169 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
170 client
->name
, tsdata
);
172 dev_err(&client
->dev
, "Unable to request touchscreen IRQ.\n");
176 error
= input_register_device(input
);
180 i2c_set_clientdata(client
, tsdata
);
181 device_init_wakeup(&client
->dev
, 1);
186 free_irq(client
->irq
, tsdata
);
188 input_free_device(input
);
193 static int pixcir_i2c_ts_remove(struct i2c_client
*client
)
195 struct pixcir_i2c_ts_data
*tsdata
= i2c_get_clientdata(client
);
197 device_init_wakeup(&client
->dev
, 0);
199 tsdata
->exiting
= true;
201 free_irq(client
->irq
, tsdata
);
203 input_unregister_device(tsdata
->input
);
209 static const struct i2c_device_id pixcir_i2c_ts_id
[] = {
213 MODULE_DEVICE_TABLE(i2c
, pixcir_i2c_ts_id
);
215 static struct i2c_driver pixcir_i2c_ts_driver
= {
217 .owner
= THIS_MODULE
,
219 .pm
= &pixcir_dev_pm_ops
,
221 .probe
= pixcir_i2c_ts_probe
,
222 .remove
= pixcir_i2c_ts_remove
,
223 .id_table
= pixcir_i2c_ts_id
,
226 module_i2c_driver(pixcir_i2c_ts_driver
);
228 MODULE_AUTHOR("Jianchun Bian <jcbian@pixcir.com.cn>, Dequan Meng <dqmeng@pixcir.com.cn>");
229 MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver");
230 MODULE_LICENSE("GPL");