]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/input/touchscreen/pixcir_i2c_ts.c
Input: alps - add support for v7 devices
[mirror_ubuntu-bionic-kernel.git] / drivers / input / touchscreen / pixcir_i2c_ts.c
CommitLineData
36a281e2
JB
1/*
2 * Driver for Pixcir I2C touchscreen controllers.
3 *
4 * Copyright (C) 2010-2011 Pixcir, Inc.
5 *
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.
9 *
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.
14 *
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
18 */
19
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>
0dfc8d41 27#include <linux/gpio.h>
36a281e2
JB
28
29struct pixcir_i2c_ts_data {
30 struct i2c_client *client;
31 struct input_dev *input;
32 const struct pixcir_ts_platform_data *chip;
3b36fbb0 33 bool running;
36a281e2
JB
34};
35
36static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
37{
38 struct pixcir_i2c_ts_data *tsdata = data;
39 u8 rdbuf[10], wrbuf[1] = { 0 };
40 u8 touch;
41 int ret;
42
43 ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
44 if (ret != sizeof(wrbuf)) {
45 dev_err(&tsdata->client->dev,
46 "%s: i2c_master_send failed(), ret=%d\n",
47 __func__, ret);
48 return;
49 }
50
51 ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
52 if (ret != sizeof(rdbuf)) {
53 dev_err(&tsdata->client->dev,
54 "%s: i2c_master_recv failed(), ret=%d\n",
55 __func__, ret);
56 return;
57 }
58
59 touch = rdbuf[0];
60 if (touch) {
61 u16 posx1 = (rdbuf[3] << 8) | rdbuf[2];
62 u16 posy1 = (rdbuf[5] << 8) | rdbuf[4];
63 u16 posx2 = (rdbuf[7] << 8) | rdbuf[6];
64 u16 posy2 = (rdbuf[9] << 8) | rdbuf[8];
65
66 input_report_key(tsdata->input, BTN_TOUCH, 1);
67 input_report_abs(tsdata->input, ABS_X, posx1);
68 input_report_abs(tsdata->input, ABS_Y, posy1);
69
70 input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
71 input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
72 input_mt_sync(tsdata->input);
73
74 if (touch == 2) {
75 input_report_abs(tsdata->input,
76 ABS_MT_POSITION_X, posx2);
77 input_report_abs(tsdata->input,
78 ABS_MT_POSITION_Y, posy2);
79 input_mt_sync(tsdata->input);
80 }
81 } else {
82 input_report_key(tsdata->input, BTN_TOUCH, 0);
83 }
84
85 input_sync(tsdata->input);
86}
87
88static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
89{
90 struct pixcir_i2c_ts_data *tsdata = dev_id;
0dfc8d41 91 const struct pixcir_ts_platform_data *pdata = tsdata->chip;
36a281e2 92
3b36fbb0 93 while (tsdata->running) {
36a281e2
JB
94 pixcir_ts_poscheck(tsdata);
95
0dfc8d41 96 if (gpio_get_value(pdata->gpio_attb))
36a281e2
JB
97 break;
98
99 msleep(20);
100 }
101
102 return IRQ_HANDLED;
103}
104
3b36fbb0
RQ
105static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
106 enum pixcir_power_mode mode)
107{
108 struct device *dev = &ts->client->dev;
109 int ret;
110
111 ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE);
112 if (ret < 0) {
113 dev_err(dev, "%s: can't read reg 0x%x : %d\n",
114 __func__, PIXCIR_REG_POWER_MODE, ret);
115 return ret;
116 }
117
118 ret &= ~PIXCIR_POWER_MODE_MASK;
119 ret |= mode;
120
121 /* Always AUTO_IDLE */
122 ret |= PIXCIR_POWER_ALLOW_IDLE;
123
124 ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret);
125 if (ret < 0) {
126 dev_err(dev, "%s: can't write reg 0x%x : %d\n",
127 __func__, PIXCIR_REG_POWER_MODE, ret);
128 return ret;
129 }
130
131 return 0;
132}
133
134/*
135 * Set the interrupt mode for the device i.e. ATTB line behaviour
136 *
137 * @polarity : 1 for active high, 0 for active low.
138 */
139static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
140 enum pixcir_int_mode mode, bool polarity)
141{
142 struct device *dev = &ts->client->dev;
143 int ret;
144
145 ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
146 if (ret < 0) {
147 dev_err(dev, "%s: can't read reg 0x%x : %d\n",
148 __func__, PIXCIR_REG_INT_MODE, ret);
149 return ret;
150 }
151
152 ret &= ~PIXCIR_INT_MODE_MASK;
153 ret |= mode;
154
155 if (polarity)
156 ret |= PIXCIR_INT_POL_HIGH;
157 else
158 ret &= ~PIXCIR_INT_POL_HIGH;
159
160 ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
161 if (ret < 0) {
162 dev_err(dev, "%s: can't write reg 0x%x : %d\n",
163 __func__, PIXCIR_REG_INT_MODE, ret);
164 return ret;
165 }
166
167 return 0;
168}
169
170/*
171 * Enable/disable interrupt generation
172 */
173static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
174{
175 struct device *dev = &ts->client->dev;
176 int ret;
177
178 ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
179 if (ret < 0) {
180 dev_err(dev, "%s: can't read reg 0x%x : %d\n",
181 __func__, PIXCIR_REG_INT_MODE, ret);
182 return ret;
183 }
184
185 if (enable)
186 ret |= PIXCIR_INT_ENABLE;
187 else
188 ret &= ~PIXCIR_INT_ENABLE;
189
190 ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
191 if (ret < 0) {
192 dev_err(dev, "%s: can't write reg 0x%x : %d\n",
193 __func__, PIXCIR_REG_INT_MODE, ret);
194 return ret;
195 }
196
197 return 0;
198}
199
200static int pixcir_start(struct pixcir_i2c_ts_data *ts)
201{
202 struct device *dev = &ts->client->dev;
203 int error;
204
205 /* LEVEL_TOUCH interrupt with active low polarity */
206 error = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0);
207 if (error) {
208 dev_err(dev, "Failed to set interrupt mode: %d\n", error);
209 return error;
210 }
211
212 ts->running = true;
213 mb(); /* Update status before IRQ can fire */
214
215 /* enable interrupt generation */
216 error = pixcir_int_enable(ts, true);
217 if (error) {
218 dev_err(dev, "Failed to enable interrupt generation: %d\n",
219 error);
220 return error;
221 }
222
223 return 0;
224}
225
226static int pixcir_stop(struct pixcir_i2c_ts_data *ts)
227{
228 int error;
229
230 /* Disable interrupt generation */
231 error = pixcir_int_enable(ts, false);
232 if (error) {
233 dev_err(&ts->client->dev,
234 "Failed to disable interrupt generation: %d\n",
235 error);
236 return error;
237 }
238
239 /* Exit ISR if running, no more report parsing */
240 ts->running = false;
241 mb(); /* update status before we synchronize irq */
242
243 /* Wait till running ISR is complete */
244 synchronize_irq(ts->client->irq);
245
246 return 0;
247}
248
249static int pixcir_input_open(struct input_dev *dev)
250{
251 struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
252
253 return pixcir_start(ts);
254}
255
256static void pixcir_input_close(struct input_dev *dev)
257{
258 struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
259
260 pixcir_stop(ts);
261}
262
36a281e2
JB
263#ifdef CONFIG_PM_SLEEP
264static int pixcir_i2c_ts_suspend(struct device *dev)
265{
266 struct i2c_client *client = to_i2c_client(dev);
7cdcb8d1
RQ
267 struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
268 struct input_dev *input = ts->input;
269 int ret = 0;
270
271 mutex_lock(&input->mutex);
272
273 if (device_may_wakeup(&client->dev)) {
274 if (!input->users) {
275 ret = pixcir_start(ts);
276 if (ret) {
277 dev_err(dev, "Failed to start\n");
278 goto unlock;
279 }
280 }
36a281e2 281
36a281e2 282 enable_irq_wake(client->irq);
7cdcb8d1
RQ
283 } else if (input->users) {
284 ret = pixcir_stop(ts);
285 }
36a281e2 286
7cdcb8d1
RQ
287unlock:
288 mutex_unlock(&input->mutex);
289
290 return ret;
36a281e2
JB
291}
292
293static int pixcir_i2c_ts_resume(struct device *dev)
294{
295 struct i2c_client *client = to_i2c_client(dev);
7cdcb8d1
RQ
296 struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
297 struct input_dev *input = ts->input;
298 int ret = 0;
299
300 mutex_lock(&input->mutex);
36a281e2 301
7cdcb8d1 302 if (device_may_wakeup(&client->dev)) {
36a281e2
JB
303 disable_irq_wake(client->irq);
304
7cdcb8d1
RQ
305 if (!input->users) {
306 ret = pixcir_stop(ts);
307 if (ret) {
308 dev_err(dev, "Failed to stop\n");
309 goto unlock;
310 }
311 }
312 } else if (input->users) {
313 ret = pixcir_start(ts);
314 }
315
316unlock:
317 mutex_unlock(&input->mutex);
318
319 return ret;
36a281e2
JB
320}
321#endif
322
323static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
324 pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
325
5298cc4c 326static int pixcir_i2c_ts_probe(struct i2c_client *client,
36a281e2
JB
327 const struct i2c_device_id *id)
328{
c838cb3d
JH
329 const struct pixcir_ts_platform_data *pdata =
330 dev_get_platdata(&client->dev);
e9d4718d 331 struct device *dev = &client->dev;
36a281e2
JB
332 struct pixcir_i2c_ts_data *tsdata;
333 struct input_dev *input;
334 int error;
335
336 if (!pdata) {
337 dev_err(&client->dev, "platform data not defined\n");
338 return -EINVAL;
339 }
340
0dfc8d41
RQ
341 if (!gpio_is_valid(pdata->gpio_attb)) {
342 dev_err(dev, "Invalid gpio_attb in pdata\n");
343 return -EINVAL;
344 }
345
e9d4718d
RQ
346 tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
347 if (!tsdata)
348 return -ENOMEM;
349
350 input = devm_input_allocate_device(dev);
351 if (!input) {
352 dev_err(dev, "Failed to allocate input device\n");
353 return -ENOMEM;
36a281e2
JB
354 }
355
356 tsdata->client = client;
357 tsdata->input = input;
358 tsdata->chip = pdata;
359
360 input->name = client->name;
361 input->id.bustype = BUS_I2C;
3b36fbb0
RQ
362 input->open = pixcir_input_open;
363 input->close = pixcir_input_close;
36a281e2
JB
364 input->dev.parent = &client->dev;
365
366 __set_bit(EV_KEY, input->evbit);
367 __set_bit(EV_ABS, input->evbit);
368 __set_bit(BTN_TOUCH, input->keybit);
369 input_set_abs_params(input, ABS_X, 0, pdata->x_max, 0, 0);
370 input_set_abs_params(input, ABS_Y, 0, pdata->y_max, 0, 0);
371 input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
372 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
373
374 input_set_drvdata(input, tsdata);
375
0dfc8d41
RQ
376 error = devm_gpio_request_one(dev, pdata->gpio_attb,
377 GPIOF_DIR_IN, "pixcir_i2c_attb");
378 if (error) {
379 dev_err(dev, "Failed to request ATTB gpio\n");
380 return error;
381 }
382
e9d4718d
RQ
383 error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
384 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
385 client->name, tsdata);
36a281e2 386 if (error) {
e9d4718d
RQ
387 dev_err(dev, "failed to request irq %d\n", client->irq);
388 return error;
36a281e2
JB
389 }
390
3b36fbb0
RQ
391 /* Always be in IDLE mode to save power, device supports auto wake */
392 error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE);
393 if (error) {
394 dev_err(dev, "Failed to set IDLE mode\n");
395 return error;
396 }
397
398 /* Stop device till opened */
399 error = pixcir_stop(tsdata);
400 if (error)
401 return error;
402
36a281e2
JB
403 error = input_register_device(input);
404 if (error)
e9d4718d 405 return error;
36a281e2 406
7cdcb8d1 407 i2c_set_clientdata(client, tsdata);
36a281e2
JB
408 device_init_wakeup(&client->dev, 1);
409
410 return 0;
36a281e2
JB
411}
412
e2619cf7 413static int pixcir_i2c_ts_remove(struct i2c_client *client)
36a281e2 414{
36a281e2
JB
415 device_init_wakeup(&client->dev, 0);
416
36a281e2
JB
417 return 0;
418}
419
420static const struct i2c_device_id pixcir_i2c_ts_id[] = {
421 { "pixcir_ts", 0 },
422 { }
423};
424MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
425
426static struct i2c_driver pixcir_i2c_ts_driver = {
427 .driver = {
428 .owner = THIS_MODULE,
429 .name = "pixcir_ts",
430 .pm = &pixcir_dev_pm_ops,
431 },
432 .probe = pixcir_i2c_ts_probe,
1cb0aa88 433 .remove = pixcir_i2c_ts_remove,
36a281e2
JB
434 .id_table = pixcir_i2c_ts_id,
435};
436
4a533835 437module_i2c_driver(pixcir_i2c_ts_driver);
36a281e2
JB
438
439MODULE_AUTHOR("Jianchun Bian <jcbian@pixcir.com.cn>, Dequan Meng <dqmeng@pixcir.com.cn>");
440MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver");
441MODULE_LICENSE("GPL");