blob: 8dbac64e7a95a9d126ea05f193be51608b246362 [file] [log] [blame]
Mohan Pallakaa2595072012-01-12 22:23:15 +05301/*
2 *
3 * FocalTech ft5x06 TouchScreen driver.
4 *
5 * Copyright (c) 2010 Focal tech Ltd.
Mohan Pallaka3a138202013-05-09 16:30:00 +05306 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Mohan Pallakaa2595072012-01-12 22:23:15 +05307 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/i2c.h>
20#include <linux/input.h>
Mohan Pallaka959a69a2013-06-14 17:12:24 +053021#include <linux/input/mt.h>
Mohan Pallakaa2595072012-01-12 22:23:15 +053022#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/delay.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/gpio.h>
Mohan Pallaka3a138202013-05-09 16:30:00 +053028#include <linux/of_gpio.h>
Mohan Pallakaa2595072012-01-12 22:23:15 +053029#include <linux/regulator/consumer.h>
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053030#include <linux/firmware.h>
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +053031#include <linux/debugfs.h>
Mohan Pallakaa2595072012-01-12 22:23:15 +053032#include <linux/input/ft5x06_ts.h>
33
Mohan Pallakaa5d601b2013-05-10 15:34:44 +053034#if defined(CONFIG_FB)
35#include <linux/notifier.h>
36#include <linux/fb.h>
37
38#elif defined(CONFIG_HAS_EARLYSUSPEND)
Mohan Pallakaa2595072012-01-12 22:23:15 +053039#include <linux/earlysuspend.h>
40/* Early-suspend level */
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053041#define FT_SUSPEND_LEVEL 1
Mohan Pallakaa2595072012-01-12 22:23:15 +053042#endif
43
44#define CFG_MAX_TOUCH_POINTS 5
45
46#define FT_STARTUP_DLY 150
47#define FT_RESET_DLY 20
48
49#define FT_PRESS 0x7F
50#define FT_MAX_ID 0x0F
51#define FT_TOUCH_STEP 6
52#define FT_TOUCH_X_H_POS 3
53#define FT_TOUCH_X_L_POS 4
54#define FT_TOUCH_Y_H_POS 5
55#define FT_TOUCH_Y_L_POS 6
56#define FT_TOUCH_EVENT_POS 3
57#define FT_TOUCH_ID_POS 5
58
59#define POINT_READ_BUF (3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS)
60
61/*register address*/
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053062#define FT_REG_DEV_MODE 0x00
63#define FT_DEV_MODE_REG_CAL 0x02
64#define FT_REG_ID 0xA3
65#define FT_REG_PMODE 0xA5
66#define FT_REG_FW_VER 0xA6
67#define FT_REG_POINT_RATE 0x88
68#define FT_REG_THGROUP 0x80
69#define FT_REG_ECC 0xCC
70#define FT_REG_RESET_FW 0x07
Mohan Pallakaa2595072012-01-12 22:23:15 +053071
72/* power register bits*/
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053073#define FT_PMODE_ACTIVE 0x00
74#define FT_PMODE_MONITOR 0x01
75#define FT_PMODE_STANDBY 0x02
76#define FT_PMODE_HIBERNATE 0x03
77#define FT_FACTORYMODE_VALUE 0x40
78#define FT_WORKMODE_VALUE 0x00
79#define FT_RST_CMD_REG 0xFC
80#define FT_READ_ID_REG 0x90
81#define FT_ERASE_APP_REG 0x61
82#define FT_ERASE_PANEL_REG 0x63
83#define FT_FW_START_REG 0xBF
Mohan Pallakaa2595072012-01-12 22:23:15 +053084
Mohan Pallakaa2595072012-01-12 22:23:15 +053085
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053086#define FT_VTG_MIN_UV 2600000
87#define FT_VTG_MAX_UV 3300000
88#define FT_I2C_VTG_MIN_UV 1800000
89#define FT_I2C_VTG_MAX_UV 1800000
90
91#define FT_COORDS_ARR_SIZE 4
Mohan Pallaka3a138202013-05-09 16:30:00 +053092#define MAX_BUTTONS 4
93
Mohan Pallaka6d2ab952013-06-04 17:36:20 +053094#define FT_8BIT_SHIFT 8
95#define FT_4BIT_SHIFT 4
96#define FT_FW_NAME_MAX_LEN 50
97
98#define FT5316_ID 0x0A
99#define FT5306I_ID 0x55
100
101#define FT_UPGRADE_AA 0xAA
102#define FT_UPGRADE_55 0x55
103
104/*upgrade config of FT5606*/
105#define FT5606_UPGRADE_AA_DELAY 50
106#define FT5606_UPGRADE_55_DELAY 10
107#define FT5606_UPGRADE_ID_1 0x79
108#define FT5606_UPGRADE_ID_2 0x06
109#define FT5606_UPGRADE_READID_DELAY 100
110#define FT5606_UPGRADE_EARSE_DELAY 2000
111
112/*upgrade config of FT5316*/
113#define FT5316_UPGRADE_AA_DELAY 50
114#define FT5316_UPGRADE_55_DELAY 30
115#define FT5316_UPGRADE_ID_1 0x79
116#define FT5316_UPGRADE_ID_2 0x07
117#define FT5316_UPGRADE_READID_DELAY 1
118#define FT5316_UPGRADE_EARSE_DELAY 1500
119
120/*upgrade config of FT5x06(x=2,3,4)*/
121#define FT5X06_UPGRADE_AA_DELAY 50
122#define FT5X06_UPGRADE_55_DELAY 30
123#define FT5X06_UPGRADE_ID_1 0x79
124#define FT5X06_UPGRADE_ID_2 0x03
125#define FT5X06_UPGRADE_READID_DELAY 1
126#define FT5X06_UPGRADE_EARSE_DELAY 2000
127
128/*upgrade config of FT6208*/
129#define FT6208_UPGRADE_AA_DELAY 60
130#define FT6208_UPGRADE_55_DELAY 10
131#define FT6208_UPGRADE_ID_1 0x79
132#define FT6208_UPGRADE_ID_2 0x05
133#define FT6208_UPGRADE_READID_DELAY 10
134#define FT6208_UPGRADE_EARSE_DELAY 2000
135
136#define FT_UPGRADE_INFO(x, y) do { \
137 x->delay_55 = y##_UPGRADE_55_DELAY; \
138 x->delay_aa = y##_UPGRADE_AA_DELAY; \
139 x->upgrade_id_1 = y##_UPGRADE_ID_1; \
140 x->upgrade_id_2 = y##_UPGRADE_ID_2; \
141 x->delay_readid = y##_UPGRADE_READID_DELAY; \
142 x->delay_earse_flash = y##_UPGRADE_EARSE_DELAY; \
143 } while (0)
144
145#define FT_FW_MIN_SIZE 8
146#define FT_FW_MAX_SIZE 32768
147#define FT_FW_FILE_VER(x) ((x)->data[(x)->size - 2])
148#define FT_FW_CHECK(x) \
149 (((x)->data[(x)->size - 8] ^ (x)->data[(x)->size - 6]) == 0xFF \
150 && (((x)->data[(x)->size - 7] ^ (x)->data[(x)->size - 5]) == 0xFF \
151 && (((x)->data[(x)->size - 3] ^ (x)->data[(x)->size - 4]) == 0xFF)))
152
153#define FT_MAX_TRIES 5
154#define FT_RETRY_DLY 20
155
156#define FT_MAX_WR_BUF 10
157#define FT_MAX_RD_BUF 2
158#define FT_FW_PKT_LEN 128
159#define FT_FW_PKT_META_LEN 6
160#define FT_FW_PKT_DLY_MS 20
161#define FT_FW_LAST_PKT 0x6ffa
162#define FT_EARSE_DLY_MS 100
163
164#define FT_UPGRADE_LOOP 3
165#define FT_CAL_START 0x04
166#define FT_CAL_FIN 0x00
167#define FT_CAL_STORE 0x05
168#define FT_CAL_RETRY 100
169#define FT_REG_CAL 0x00
170#define FT_CAL_MASK 0x70
171
Mohan Pallaka768d5e32013-06-14 17:50:10 +0530172#define FT_INFO_MAX_LEN 200
173
174#define FT_STORE_TS_INFO(buf, id, fw_ver) \
175 snprintf(buf, FT_INFO_MAX_LEN, \
176 "controller\t= focaltech\n" \
177 "model\t\t= 0x%x\n" \
178 "fw_ver\t\t= 0x%x\n", id, fw_ver)
179
180#define FT_DEBUG_DIR_NAME "ts_debug"
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530181
Mohan Pallakaa2595072012-01-12 22:23:15 +0530182struct ts_event {
183 u16 x[CFG_MAX_TOUCH_POINTS]; /*x coordinate */
184 u16 y[CFG_MAX_TOUCH_POINTS]; /*y coordinate */
185 /* touch event: 0 -- down; 1-- contact; 2 -- contact */
186 u8 touch_event[CFG_MAX_TOUCH_POINTS];
187 u8 finger_id[CFG_MAX_TOUCH_POINTS]; /*touch ID */
188 u16 pressure;
189 u8 touch_point;
190};
191
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530192struct upgrade_info {
193 u16 delay_aa; /*delay of write FT_UPGRADE_AA */
194 u16 delay_55; /*delay of write FT_UPGRADE_55 */
195 u8 upgrade_id_1; /*upgrade id 1 */
196 u8 upgrade_id_2; /*upgrade id 2 */
197 u16 delay_readid; /*delay of read id */
198 u16 delay_earse_flash; /*delay of earse flash*/
199};
200
Mohan Pallakaa2595072012-01-12 22:23:15 +0530201struct ft5x06_ts_data {
202 struct i2c_client *client;
203 struct input_dev *input_dev;
204 struct ts_event event;
205 const struct ft5x06_ts_platform_data *pdata;
206 struct regulator *vdd;
207 struct regulator *vcc_i2c;
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530208 char fw_name[FT_FW_NAME_MAX_LEN];
209 bool loading_fw;
210 u8 family_id;
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530211 struct dentry *dir;
212 u16 addr;
213 bool suspended;
Mohan Pallaka768d5e32013-06-14 17:50:10 +0530214 char *ts_info;
Mohan Pallakaa5d601b2013-05-10 15:34:44 +0530215#if defined(CONFIG_FB)
216 struct notifier_block fb_notif;
217#elif defined(CONFIG_HAS_EARLYSUSPEND)
Mohan Pallakaa2595072012-01-12 22:23:15 +0530218 struct early_suspend early_suspend;
219#endif
220};
221
222static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf,
223 int writelen, char *readbuf, int readlen)
224{
225 int ret;
226
227 if (writelen > 0) {
228 struct i2c_msg msgs[] = {
229 {
230 .addr = client->addr,
231 .flags = 0,
232 .len = writelen,
233 .buf = writebuf,
234 },
235 {
236 .addr = client->addr,
237 .flags = I2C_M_RD,
238 .len = readlen,
239 .buf = readbuf,
240 },
241 };
242 ret = i2c_transfer(client->adapter, msgs, 2);
243 if (ret < 0)
244 dev_err(&client->dev, "%s: i2c read error.\n",
245 __func__);
246 } else {
247 struct i2c_msg msgs[] = {
248 {
249 .addr = client->addr,
250 .flags = I2C_M_RD,
251 .len = readlen,
252 .buf = readbuf,
253 },
254 };
255 ret = i2c_transfer(client->adapter, msgs, 1);
256 if (ret < 0)
257 dev_err(&client->dev, "%s:i2c read error.\n", __func__);
258 }
259 return ret;
260}
261
262static int ft5x06_i2c_write(struct i2c_client *client, char *writebuf,
263 int writelen)
264{
265 int ret;
266
267 struct i2c_msg msgs[] = {
268 {
269 .addr = client->addr,
270 .flags = 0,
271 .len = writelen,
272 .buf = writebuf,
273 },
274 };
275 ret = i2c_transfer(client->adapter, msgs, 1);
276 if (ret < 0)
277 dev_err(&client->dev, "%s: i2c write error.\n", __func__);
278
279 return ret;
280}
281
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530282static int ft5x0x_write_reg(struct i2c_client *client, u8 addr, const u8 val)
283{
284 u8 buf[2] = {0};
285
286 buf[0] = addr;
287 buf[1] = val;
288
289 return ft5x06_i2c_write(client, buf, sizeof(buf));
290}
291
292static int ft5x0x_read_reg(struct i2c_client *client, u8 addr, u8 *val)
293{
294 return ft5x06_i2c_read(client, &addr, 1, val, 1);
295}
296
Mohan Pallakaa2595072012-01-12 22:23:15 +0530297static void ft5x06_report_value(struct ft5x06_ts_data *data)
298{
299 struct ts_event *event = &data->event;
300 int i;
301 int fingerdown = 0;
302
303 for (i = 0; i < event->touch_point; i++) {
304 if (event->touch_event[i] == 0 || event->touch_event[i] == 2) {
305 event->pressure = FT_PRESS;
306 fingerdown++;
307 } else {
308 event->pressure = 0;
309 }
310
Mohan Pallaka959a69a2013-06-14 17:12:24 +0530311 input_mt_slot(data->input_dev, i);
312 input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER,
313 !!event->pressure);
314
315 if (event->pressure == FT_PRESS) {
316 input_report_abs(data->input_dev, ABS_MT_POSITION_X,
317 event->x[i]);
318 input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
319 event->y[i]);
320 input_report_abs(data->input_dev, ABS_MT_PRESSURE,
321 event->pressure);
322 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
323 event->finger_id[i]);
324 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
325 event->pressure);
326 }
Mohan Pallakaa2595072012-01-12 22:23:15 +0530327 }
328
329 input_report_key(data->input_dev, BTN_TOUCH, !!fingerdown);
330 input_sync(data->input_dev);
331}
332
333static int ft5x06_handle_touchdata(struct ft5x06_ts_data *data)
334{
335 struct ts_event *event = &data->event;
336 int ret, i;
337 u8 buf[POINT_READ_BUF] = { 0 };
338 u8 pointid = FT_MAX_ID;
339
340 ret = ft5x06_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
341 if (ret < 0) {
342 dev_err(&data->client->dev, "%s read touchdata failed.\n",
343 __func__);
344 return ret;
345 }
346 memset(event, 0, sizeof(struct ts_event));
347
348 event->touch_point = 0;
349 for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
350 pointid = (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
351 if (pointid >= FT_MAX_ID)
352 break;
353 else
354 event->touch_point++;
355 event->x[i] =
356 (s16) (buf[FT_TOUCH_X_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
357 8 | (s16) buf[FT_TOUCH_X_L_POS + FT_TOUCH_STEP * i];
358 event->y[i] =
359 (s16) (buf[FT_TOUCH_Y_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
360 8 | (s16) buf[FT_TOUCH_Y_L_POS + FT_TOUCH_STEP * i];
361 event->touch_event[i] =
362 buf[FT_TOUCH_EVENT_POS + FT_TOUCH_STEP * i] >> 6;
363 event->finger_id[i] =
364 (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
365 }
366
367 ft5x06_report_value(data);
368
369 return 0;
370}
371
372static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
373{
374 struct ft5x06_ts_data *data = dev_id;
375 int rc;
376
377 rc = ft5x06_handle_touchdata(data);
378 if (rc)
379 pr_err("%s: handling touchdata failed\n", __func__);
380
381 return IRQ_HANDLED;
382}
383
384static int ft5x06_power_on(struct ft5x06_ts_data *data, bool on)
385{
386 int rc;
387
388 if (!on)
389 goto power_off;
390
391 rc = regulator_enable(data->vdd);
392 if (rc) {
393 dev_err(&data->client->dev,
394 "Regulator vdd enable failed rc=%d\n", rc);
395 return rc;
396 }
397
398 rc = regulator_enable(data->vcc_i2c);
399 if (rc) {
400 dev_err(&data->client->dev,
401 "Regulator vcc_i2c enable failed rc=%d\n", rc);
402 regulator_disable(data->vdd);
403 }
404
405 return rc;
406
407power_off:
408 rc = regulator_disable(data->vdd);
409 if (rc) {
410 dev_err(&data->client->dev,
411 "Regulator vdd disable failed rc=%d\n", rc);
412 return rc;
413 }
414
415 rc = regulator_disable(data->vcc_i2c);
416 if (rc) {
417 dev_err(&data->client->dev,
418 "Regulator vcc_i2c disable failed rc=%d\n", rc);
419 regulator_enable(data->vdd);
420 }
421
422 return rc;
423}
424
425static int ft5x06_power_init(struct ft5x06_ts_data *data, bool on)
426{
427 int rc;
428
429 if (!on)
430 goto pwr_deinit;
431
432 data->vdd = regulator_get(&data->client->dev, "vdd");
433 if (IS_ERR(data->vdd)) {
434 rc = PTR_ERR(data->vdd);
435 dev_err(&data->client->dev,
436 "Regulator get failed vdd rc=%d\n", rc);
437 return rc;
438 }
439
440 if (regulator_count_voltages(data->vdd) > 0) {
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530441 rc = regulator_set_voltage(data->vdd, FT_VTG_MIN_UV,
442 FT_VTG_MAX_UV);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530443 if (rc) {
444 dev_err(&data->client->dev,
445 "Regulator set_vtg failed vdd rc=%d\n", rc);
446 goto reg_vdd_put;
447 }
448 }
449
450 data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c");
451 if (IS_ERR(data->vcc_i2c)) {
452 rc = PTR_ERR(data->vcc_i2c);
453 dev_err(&data->client->dev,
454 "Regulator get failed vcc_i2c rc=%d\n", rc);
455 goto reg_vdd_set_vtg;
456 }
457
458 if (regulator_count_voltages(data->vcc_i2c) > 0) {
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530459 rc = regulator_set_voltage(data->vcc_i2c, FT_I2C_VTG_MIN_UV,
460 FT_I2C_VTG_MAX_UV);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530461 if (rc) {
462 dev_err(&data->client->dev,
463 "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
464 goto reg_vcc_i2c_put;
465 }
466 }
467
468 return 0;
469
470reg_vcc_i2c_put:
471 regulator_put(data->vcc_i2c);
472reg_vdd_set_vtg:
473 if (regulator_count_voltages(data->vdd) > 0)
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530474 regulator_set_voltage(data->vdd, 0, FT_VTG_MAX_UV);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530475reg_vdd_put:
476 regulator_put(data->vdd);
477 return rc;
478
479pwr_deinit:
480 if (regulator_count_voltages(data->vdd) > 0)
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530481 regulator_set_voltage(data->vdd, 0, FT_VTG_MAX_UV);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530482
483 regulator_put(data->vdd);
484
485 if (regulator_count_voltages(data->vcc_i2c) > 0)
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530486 regulator_set_voltage(data->vcc_i2c, 0, FT_I2C_VTG_MAX_UV);
Mohan Pallakaa2595072012-01-12 22:23:15 +0530487
488 regulator_put(data->vcc_i2c);
489 return 0;
490}
491
492#ifdef CONFIG_PM
493static int ft5x06_ts_suspend(struct device *dev)
494{
495 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
496 char txbuf[2];
497
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530498 if (data->loading_fw) {
499 dev_info(dev, "Firmware loading in process...\n");
500 return 0;
501 }
502
503 if (data->suspended) {
504 dev_info(dev, "Already in suspend state\n");
505 return 0;
506 }
507
Mohan Pallakaa2595072012-01-12 22:23:15 +0530508 disable_irq(data->client->irq);
509
510 if (gpio_is_valid(data->pdata->reset_gpio)) {
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530511 txbuf[0] = FT_REG_PMODE;
512 txbuf[1] = FT_PMODE_HIBERNATE;
Mohan Pallakaa2595072012-01-12 22:23:15 +0530513 ft5x06_i2c_write(data->client, txbuf, sizeof(txbuf));
514 }
515
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530516 data->suspended = true;
517
Mohan Pallakaa2595072012-01-12 22:23:15 +0530518 return 0;
519}
520
521static int ft5x06_ts_resume(struct device *dev)
522{
523 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
524
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530525 if (!data->suspended) {
526 dev_info(dev, "Already in awake state\n");
527 return 0;
528 }
529
Mohan Pallakaa2595072012-01-12 22:23:15 +0530530 if (gpio_is_valid(data->pdata->reset_gpio)) {
531 gpio_set_value_cansleep(data->pdata->reset_gpio, 0);
532 msleep(FT_RESET_DLY);
533 gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
534 }
535 enable_irq(data->client->irq);
536
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530537 data->suspended = false;
538
Mohan Pallakaa2595072012-01-12 22:23:15 +0530539 return 0;
540}
541
Mohan Pallakaa5d601b2013-05-10 15:34:44 +0530542#if defined(CONFIG_FB)
543static int fb_notifier_callback(struct notifier_block *self,
544 unsigned long event, void *data)
545{
546 struct fb_event *evdata = data;
547 int *blank;
548 struct ft5x06_ts_data *ft5x06_data =
549 container_of(self, struct ft5x06_ts_data, fb_notif);
550
551 if (evdata && evdata->data && event == FB_EVENT_BLANK &&
552 ft5x06_data && ft5x06_data->client) {
553 blank = evdata->data;
554 if (*blank == FB_BLANK_UNBLANK)
555 ft5x06_ts_resume(&ft5x06_data->client->dev);
556 else if (*blank == FB_BLANK_POWERDOWN)
557 ft5x06_ts_suspend(&ft5x06_data->client->dev);
558 }
559
560 return 0;
561}
562#elif defined(CONFIG_HAS_EARLYSUSPEND)
Mohan Pallakaa2595072012-01-12 22:23:15 +0530563static void ft5x06_ts_early_suspend(struct early_suspend *handler)
564{
565 struct ft5x06_ts_data *data = container_of(handler,
566 struct ft5x06_ts_data,
567 early_suspend);
568
569 ft5x06_ts_suspend(&data->client->dev);
570}
571
572static void ft5x06_ts_late_resume(struct early_suspend *handler)
573{
574 struct ft5x06_ts_data *data = container_of(handler,
575 struct ft5x06_ts_data,
576 early_suspend);
577
578 ft5x06_ts_resume(&data->client->dev);
579}
580#endif
581
582static const struct dev_pm_ops ft5x06_ts_pm_ops = {
Mohan Pallakaa5d601b2013-05-10 15:34:44 +0530583#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
Mohan Pallakaa2595072012-01-12 22:23:15 +0530584 .suspend = ft5x06_ts_suspend,
585 .resume = ft5x06_ts_resume,
586#endif
587};
588#endif
589
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530590static int ft5x06_auto_cal(struct i2c_client *client)
591{
592 u8 temp = 0, i;
593
594 /* set to factory mode */
595 msleep(2 * FT_STARTUP_DLY);
596 ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_FACTORYMODE_VALUE);
597 msleep(FT_STARTUP_DLY);
598
599 /* start calibration */
600 ft5x0x_write_reg(client, FT_DEV_MODE_REG_CAL, FT_CAL_START);
601 msleep(2 * FT_STARTUP_DLY);
602 for (i = 0; i < FT_CAL_RETRY; i++) {
603 ft5x0x_read_reg(client, FT_REG_CAL, &temp);
604 /*return to normal mode, calibration finish */
605 if (((temp & FT_CAL_MASK) >> FT_4BIT_SHIFT) == FT_CAL_FIN)
606 break;
607 }
608
609 /*calibration OK */
610 msleep(2 * FT_STARTUP_DLY);
611 ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_FACTORYMODE_VALUE);
612 msleep(FT_STARTUP_DLY);
613
614 /* store calibration data */
615 ft5x0x_write_reg(client, FT_DEV_MODE_REG_CAL, FT_CAL_STORE);
616 msleep(2 * FT_STARTUP_DLY);
617
618 /* set to normal mode */
619 ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_WORKMODE_VALUE);
620 msleep(2 * FT_STARTUP_DLY);
621
622 return 0;
623}
624
625static int ft5x06_get_upgrade_info(u8 family_id, struct upgrade_info *info)
626{
627 switch (family_id) {
628 case FT5306I_ID:
629 FT_UPGRADE_INFO(info, FT5X06);
630 break;
631 case FT5316_ID:
632 FT_UPGRADE_INFO(info, FT5316);
633 break;
634 default:
635 return -EINVAL;
636 }
637
638 return 0;
639}
640
641static int ft5x06_fw_upgrade_start(struct i2c_client *client,
642 const u8 *data, u32 data_len)
643{
644 struct ft5x06_ts_data *ts_data = i2c_get_clientdata(client);
645 struct upgrade_info info;
646 u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[FT_MAX_RD_BUF] = {0};
647 u8 pkt_buf[FT_FW_PKT_LEN + FT_FW_PKT_META_LEN];
648 int rc, i, j, temp;
649 u32 pkt_num, pkt_len;
650 u8 fw_ecc;
651
652 rc = ft5x06_get_upgrade_info(ts_data->family_id, &info);
653 if (rc < 0) {
654 dev_err(&client->dev, "Cannot get upgrade information!\n");
655 return -EINVAL;
656 }
657
658 for (i = 0; i < FT_UPGRADE_LOOP; i++) {
659 /* reset - write 0xaa and 0x55 to register 0xfc */
660 ft5x0x_write_reg(client, FT_RST_CMD_REG, FT_UPGRADE_AA);
661 msleep(info.delay_aa);
662
663 ft5x0x_write_reg(client, FT_RST_CMD_REG, FT_UPGRADE_55);
664 msleep(info.delay_55);
665
666 /* Enter upgrade mode */
667 w_buf[0] = FT_UPGRADE_55;
668 w_buf[1] = FT_UPGRADE_AA;
669 do {
670 i++;
671 rc = ft5x06_i2c_write(client, w_buf, 2);
672 msleep(FT_RETRY_DLY);
673 } while (rc <= 0 && i < FT_MAX_TRIES);
674
675 /* check READ_ID */
676 msleep(info.delay_readid);
677 w_buf[0] = FT_READ_ID_REG;
678 w_buf[1] = 0x00;
679 w_buf[2] = 0x00;
680 w_buf[3] = 0x00;
681
682 ft5x06_i2c_read(client, w_buf, 4, r_buf, 2);
683
684 if (r_buf[0] != info.upgrade_id_1
685 || r_buf[1] != info.upgrade_id_2) {
686 dev_err(&client->dev, "Upgrade ID mismatch(%d)\n", i);
687 } else
688 break;
689 }
690
691 if (i >= FT_UPGRADE_LOOP) {
692 dev_err(&client->dev, "Abort upgrade\n");
693 return -EIO;
694 }
695
696 /* erase app and panel paramenter area */
697 w_buf[0] = FT_ERASE_APP_REG;
698 ft5x06_i2c_write(client, w_buf, 1);
699 msleep(info.delay_earse_flash);
700
701 w_buf[0] = FT_ERASE_PANEL_REG;
702 ft5x06_i2c_write(client, w_buf, 1);
703 msleep(FT_EARSE_DLY_MS);
704
705 /* program firmware */
706 data_len = data_len - 8;
707 pkt_num = (data_len) / FT_FW_PKT_LEN;
708 pkt_len = FT_FW_PKT_LEN;
709 pkt_buf[0] = FT_FW_START_REG;
710 pkt_buf[1] = 0x00;
711 fw_ecc = 0;
712
713 for (i = 0; i < pkt_num; i++) {
714 temp = i * FT_FW_PKT_LEN;
715 pkt_buf[2] = (u8) (temp >> FT_8BIT_SHIFT);
716 pkt_buf[3] = (u8) temp;
717 pkt_buf[4] = (u8) (pkt_len >> FT_8BIT_SHIFT);
718 pkt_buf[5] = (u8) pkt_len;
719
720 for (j = 0; j < FT_FW_PKT_LEN; j++) {
721 pkt_buf[6 + j] = data[i * FT_FW_PKT_LEN + j];
722 fw_ecc ^= pkt_buf[6 + j];
723 }
724
725 ft5x06_i2c_write(client, pkt_buf,
726 FT_FW_PKT_LEN + FT_FW_PKT_META_LEN);
727 msleep(FT_FW_PKT_DLY_MS);
728 }
729
730 /* send remaining bytes */
731 if ((data_len) % FT_FW_PKT_LEN > 0) {
732 temp = pkt_num * FT_FW_PKT_LEN;
733 pkt_buf[2] = (u8) (temp >> FT_8BIT_SHIFT);
734 pkt_buf[3] = (u8) temp;
735 temp = (data_len) % FT_FW_PKT_LEN;
736 pkt_buf[4] = (u8) (temp >> FT_8BIT_SHIFT);
737 pkt_buf[5] = (u8) temp;
738
739 for (i = 0; i < temp; i++) {
740 pkt_buf[6 + i] = data[pkt_num * FT_FW_PKT_LEN + i];
741 fw_ecc ^= pkt_buf[6 + i];
742 }
743
744 ft5x06_i2c_write(client, pkt_buf, temp + FT_FW_PKT_META_LEN);
745 msleep(FT_FW_PKT_DLY_MS);
746 }
747
748 /* send the finishing packet */
749 for (i = 0; i < 6; i++) {
750 temp = FT_FW_LAST_PKT + i;
751 pkt_buf[2] = (u8) (temp >> 8);
752 pkt_buf[3] = (u8) temp;
753 temp = 1;
754 pkt_buf[4] = (u8) (temp >> 8);
755 pkt_buf[5] = (u8) temp;
756 pkt_buf[6] = data[data_len + i];
757 fw_ecc ^= pkt_buf[6];
758 ft5x06_i2c_write(client, pkt_buf, temp + FT_FW_PKT_META_LEN);
759 msleep(FT_FW_PKT_DLY_MS);
760 }
761
762 /* verify checksum */
763 w_buf[0] = FT_REG_ECC;
764 ft5x06_i2c_read(client, w_buf, 1, r_buf, 1);
765 if (r_buf[0] != fw_ecc) {
766 dev_err(&client->dev, "ECC error! dev_ecc=%02x fw_ecc=%02x\n",
767 r_buf[0], fw_ecc);
768 return -EIO;
769 }
770
771 /* reset */
772 w_buf[0] = FT_REG_RESET_FW;
773 ft5x06_i2c_write(client, w_buf, 1);
774 msleep(FT_STARTUP_DLY);
775
776 return 0;
777}
778
779static int ft5x06_fw_upgrade(struct device *dev, bool force)
780{
781 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
782 const struct firmware *fw = NULL;
783 int rc;
784 u8 val = 0;
785
786 rc = request_firmware(&fw, data->fw_name, dev);
787 if (rc < 0) {
788 dev_err(dev, "Request firmware failed - %s (%d)\n",
789 data->fw_name, rc);
790 return rc;
791 }
792
793 if (fw->size < FT_FW_MIN_SIZE || fw->size > FT_FW_MAX_SIZE) {
794 dev_err(dev, "Invalid firmware size (%d)\n", fw->size);
795 rc = -EIO;
796 goto rel_fw;
797 }
798
799 /* check firmware version */
800 rc = ft5x0x_read_reg(data->client, FT_REG_FW_VER, &val);
801 if (rc < 0) {
802 dev_err(dev, "Get firmware version failed\n");
803 goto rel_fw;
804 }
805
806 if (val == FT_FW_FILE_VER(fw) && !force) {
807 dev_err(dev, "No need to update (0x%x)\n", val);
808 rc = -EFAULT;
809 goto rel_fw;
810 }
811
812 dev_info(dev, "upgrade to fw ver 0x%x from 0x%x\n",
813 FT_FW_FILE_VER(fw), val);
814
815 /* start firmware upgrade */
816 if (FT_FW_CHECK(fw)) {
817 rc = ft5x06_fw_upgrade_start(data->client, fw->data, fw->size);
818 if (rc < 0)
819 dev_err(dev, "update failed (%d)\n", rc);
820 else
821 ft5x06_auto_cal(data->client);
822 } else {
823 dev_err(dev, "FW format error\n");
824 rc = -EIO;
825 }
826
Mohan Pallaka768d5e32013-06-14 17:50:10 +0530827 FT_STORE_TS_INFO(data->ts_info, data->family_id, FT_FW_FILE_VER(fw));
Mohan Pallaka6d2ab952013-06-04 17:36:20 +0530828rel_fw:
829 release_firmware(fw);
830 return rc;
831}
832
833static ssize_t ft5x06_update_fw_show(struct device *dev,
834 struct device_attribute *attr, char *buf)
835{
836 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
837 return snprintf(buf, 2, "%d\n", data->loading_fw);
838}
839
840static ssize_t ft5x06_update_fw_store(struct device *dev,
841 struct device_attribute *attr,
842 const char *buf, size_t size)
843{
844 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
845 unsigned long val;
846 int rc;
847
848 if (size > 2)
849 return -EINVAL;
850
851 rc = kstrtoul(buf, 10, &val);
852 if (rc != 0)
853 return rc;
854
855 mutex_lock(&data->input_dev->mutex);
856 if (!data->loading_fw && val) {
857 data->loading_fw = true;
858 ft5x06_fw_upgrade(dev, false);
859 data->loading_fw = false;
860 }
861 mutex_unlock(&data->input_dev->mutex);
862
863 return size;
864}
865
866static DEVICE_ATTR(update_fw, 0664, ft5x06_update_fw_show,
867 ft5x06_update_fw_store);
868
869static ssize_t ft5x06_force_update_fw_store(struct device *dev,
870 struct device_attribute *attr,
871 const char *buf, size_t size)
872{
873 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
874 unsigned long val;
875 int rc;
876
877 if (size > 2)
878 return -EINVAL;
879
880 rc = kstrtoul(buf, 10, &val);
881 if (rc != 0)
882 return rc;
883
884 mutex_lock(&data->input_dev->mutex);
885 if (!data->loading_fw && val) {
886 data->loading_fw = true;
887 ft5x06_fw_upgrade(dev, true);
888 data->loading_fw = false;
889 }
890 mutex_unlock(&data->input_dev->mutex);
891
892 return size;
893}
894
895static DEVICE_ATTR(force_update_fw, 0664, ft5x06_update_fw_show,
896 ft5x06_force_update_fw_store);
897
898static ssize_t ft5x06_fw_name_show(struct device *dev,
899 struct device_attribute *attr, char *buf)
900{
901 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
902 return snprintf(buf, FT_FW_NAME_MAX_LEN - 1, "%s\n", data->fw_name);
903}
904
905static ssize_t ft5x06_fw_name_store(struct device *dev,
906 struct device_attribute *attr,
907 const char *buf, size_t size)
908{
909 struct ft5x06_ts_data *data = dev_get_drvdata(dev);
910
911 if (size > FT_FW_NAME_MAX_LEN - 1)
912 return -EINVAL;
913
914 strlcpy(data->fw_name, buf, size);
915 if (data->fw_name[size-1] == '\n')
916 data->fw_name[size-1] = 0;
917
918 return size;
919}
920
921static DEVICE_ATTR(fw_name, 0664, ft5x06_fw_name_show, ft5x06_fw_name_store);
922
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +0530923static bool ft5x06_debug_addr_is_valid(int addr)
924{
925 if (addr < 0 || addr > 0xFF) {
926 pr_err("FT reg address is invalid: 0x%x\n", addr);
927 return false;
928 }
929
930 return true;
931}
932
933static int ft5x06_debug_data_set(void *_data, u64 val)
934{
935 struct ft5x06_ts_data *data = _data;
936
937 mutex_lock(&data->input_dev->mutex);
938
939 if (ft5x06_debug_addr_is_valid(data->addr))
940 dev_info(&data->client->dev,
941 "Writing into FT registers not supported\n");
942
943 mutex_unlock(&data->input_dev->mutex);
944
945 return 0;
946}
947
948static int ft5x06_debug_data_get(void *_data, u64 *val)
949{
950 struct ft5x06_ts_data *data = _data;
951 int rc;
952 u8 reg;
953
954 mutex_lock(&data->input_dev->mutex);
955
956 if (ft5x06_debug_addr_is_valid(data->addr)) {
957 rc = ft5x0x_read_reg(data->client, data->addr, &reg);
958 if (rc < 0)
959 dev_err(&data->client->dev,
960 "FT read register 0x%x failed (%d)\n",
961 data->addr, rc);
962 else
963 *val = reg;
964 }
965
966 mutex_unlock(&data->input_dev->mutex);
967
968 return 0;
969}
970
971DEFINE_SIMPLE_ATTRIBUTE(debug_data_fops, ft5x06_debug_data_get,
972 ft5x06_debug_data_set, "0x%02llX\n");
973
974static int ft5x06_debug_addr_set(void *_data, u64 val)
975{
976 struct ft5x06_ts_data *data = _data;
977
978 if (ft5x06_debug_addr_is_valid(val)) {
979 mutex_lock(&data->input_dev->mutex);
980 data->addr = val;
981 mutex_unlock(&data->input_dev->mutex);
982 }
983
984 return 0;
985}
986
987static int ft5x06_debug_addr_get(void *_data, u64 *val)
988{
989 struct ft5x06_ts_data *data = _data;
990
991 mutex_lock(&data->input_dev->mutex);
992
993 if (ft5x06_debug_addr_is_valid(data->addr))
994 *val = data->addr;
995
996 mutex_unlock(&data->input_dev->mutex);
997
998 return 0;
999}
1000
1001DEFINE_SIMPLE_ATTRIBUTE(debug_addr_fops, ft5x06_debug_addr_get,
1002 ft5x06_debug_addr_set, "0x%02llX\n");
1003
1004static int ft5x06_debug_suspend_set(void *_data, u64 val)
1005{
1006 struct ft5x06_ts_data *data = _data;
1007
1008 mutex_lock(&data->input_dev->mutex);
1009
1010 if (val)
1011 ft5x06_ts_suspend(&data->client->dev);
1012 else
1013 ft5x06_ts_resume(&data->client->dev);
1014
1015 mutex_unlock(&data->input_dev->mutex);
1016
1017 return 0;
1018}
1019
1020static int ft5x06_debug_suspend_get(void *_data, u64 *val)
1021{
1022 struct ft5x06_ts_data *data = _data;
1023
1024 mutex_lock(&data->input_dev->mutex);
1025 *val = data->suspended;
1026 mutex_unlock(&data->input_dev->mutex);
1027
1028 return 0;
1029}
1030
1031DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, ft5x06_debug_suspend_get,
1032 ft5x06_debug_suspend_set, "%lld\n");
1033
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301034static int ft5x06_debug_dump_info(struct seq_file *m, void *v)
1035{
1036 struct ft5x06_ts_data *data = m->private;
1037
1038 seq_printf(m, "%s\n", data->ts_info);
1039
1040 return 0;
1041}
1042
1043static int debugfs_dump_info_open(struct inode *inode, struct file *file)
1044{
1045 return single_open(file, ft5x06_debug_dump_info, inode->i_private);
1046}
1047
1048static const struct file_operations debug_dump_info_fops = {
1049 .owner = THIS_MODULE,
1050 .open = debugfs_dump_info_open,
1051 .read = seq_read,
1052 .release = single_release,
1053};
1054
Mohan Pallaka3a138202013-05-09 16:30:00 +05301055#ifdef CONFIG_OF
1056static int ft5x06_get_dt_coords(struct device *dev, char *name,
1057 struct ft5x06_ts_platform_data *pdata)
1058{
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301059 u32 coords[FT_COORDS_ARR_SIZE];
Mohan Pallaka3a138202013-05-09 16:30:00 +05301060 struct property *prop;
1061 struct device_node *np = dev->of_node;
1062 int coords_size, rc;
1063
1064 prop = of_find_property(np, name, NULL);
1065 if (!prop)
1066 return -EINVAL;
1067 if (!prop->value)
1068 return -ENODATA;
1069
1070 coords_size = prop->length / sizeof(u32);
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301071 if (coords_size != FT_COORDS_ARR_SIZE) {
Mohan Pallaka3a138202013-05-09 16:30:00 +05301072 dev_err(dev, "invalid %s\n", name);
1073 return -EINVAL;
1074 }
1075
1076 rc = of_property_read_u32_array(np, name, coords, coords_size);
1077 if (rc && (rc != -EINVAL)) {
1078 dev_err(dev, "Unable to read %s\n", name);
1079 return rc;
1080 }
1081
1082 if (!strcmp(name, "focaltech,panel-coords")) {
1083 pdata->panel_minx = coords[0];
1084 pdata->panel_miny = coords[1];
1085 pdata->panel_maxx = coords[2];
1086 pdata->panel_maxy = coords[3];
1087 } else if (!strcmp(name, "focaltech,display-coords")) {
1088 pdata->x_min = coords[0];
1089 pdata->y_min = coords[1];
1090 pdata->x_max = coords[2];
1091 pdata->y_max = coords[3];
1092 } else {
1093 dev_err(dev, "unsupported property %s\n", name);
1094 return -EINVAL;
1095 }
1096
1097 return 0;
1098}
1099
1100static int ft5x06_parse_dt(struct device *dev,
1101 struct ft5x06_ts_platform_data *pdata)
1102{
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301103 int rc;
Mohan Pallaka3a138202013-05-09 16:30:00 +05301104 struct device_node *np = dev->of_node;
1105 struct property *prop;
1106 u32 temp_val, num_buttons;
1107 u32 button_map[MAX_BUTTONS];
1108
1109 rc = ft5x06_get_dt_coords(dev, "focaltech,panel-coords", pdata);
1110 if (rc && (rc != -EINVAL))
1111 return rc;
1112
1113 rc = ft5x06_get_dt_coords(dev, "focaltech,display-coords", pdata);
1114 if (rc)
1115 return rc;
1116
1117 pdata->i2c_pull_up = of_property_read_bool(np,
1118 "focaltech,i2c-pull-up");
1119
1120 pdata->no_force_update = of_property_read_bool(np,
1121 "focaltech,no-force-update");
1122 /* reset, irq gpio info */
1123 pdata->reset_gpio = of_get_named_gpio_flags(np, "focaltech,reset-gpio",
1124 0, &pdata->reset_gpio_flags);
1125 if (pdata->reset_gpio < 0)
1126 return pdata->reset_gpio;
1127
1128 pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio",
1129 0, &pdata->irq_gpio_flags);
1130 if (pdata->irq_gpio < 0)
1131 return pdata->irq_gpio;
1132
1133 rc = of_property_read_u32(np, "focaltech,family-id", &temp_val);
1134 if (!rc)
1135 pdata->family_id = temp_val;
1136 else
1137 return rc;
1138
1139 prop = of_find_property(np, "focaltech,button-map", NULL);
1140 if (prop) {
1141 num_buttons = prop->length / sizeof(temp_val);
1142 if (num_buttons > MAX_BUTTONS)
1143 return -EINVAL;
1144
1145 rc = of_property_read_u32_array(np,
1146 "focaltech,button-map", button_map,
1147 num_buttons);
1148 if (rc) {
1149 dev_err(dev, "Unable to read key codes\n");
1150 return rc;
1151 }
1152 }
1153
1154 return 0;
1155}
1156#else
1157static int ft5x06_parse_dt(struct device *dev,
1158 struct ft5x06_ts_platform_data *pdata)
1159{
1160 return -ENODEV;
1161}
1162#endif
1163
Mohan Pallakaa2595072012-01-12 22:23:15 +05301164static int ft5x06_ts_probe(struct i2c_client *client,
1165 const struct i2c_device_id *id)
1166{
Mohan Pallaka3a138202013-05-09 16:30:00 +05301167 struct ft5x06_ts_platform_data *pdata;
Mohan Pallakaa2595072012-01-12 22:23:15 +05301168 struct ft5x06_ts_data *data;
1169 struct input_dev *input_dev;
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301170 struct dentry *temp;
Mohan Pallakaa2595072012-01-12 22:23:15 +05301171 u8 reg_value;
1172 u8 reg_addr;
1173 int err;
1174
Mohan Pallaka3a138202013-05-09 16:30:00 +05301175 if (client->dev.of_node) {
1176 pdata = devm_kzalloc(&client->dev,
1177 sizeof(struct ft5x06_ts_platform_data), GFP_KERNEL);
1178 if (!pdata) {
1179 dev_err(&client->dev, "Failed to allocate memory\n");
1180 return -ENOMEM;
1181 }
1182
1183 err = ft5x06_parse_dt(&client->dev, pdata);
1184 if (err)
1185 return err;
1186 } else
1187 pdata = client->dev.platform_data;
1188
Mohan Pallakaa2595072012-01-12 22:23:15 +05301189 if (!pdata) {
1190 dev_err(&client->dev, "Invalid pdata\n");
1191 return -EINVAL;
1192 }
1193
1194 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1195 dev_err(&client->dev, "I2C not supported\n");
1196 return -ENODEV;
1197 }
1198
1199 data = kzalloc(sizeof(struct ft5x06_ts_data), GFP_KERNEL);
1200 if (!data) {
1201 dev_err(&client->dev, "Not enough memory\n");
1202 return -ENOMEM;
1203 }
1204
1205 input_dev = input_allocate_device();
1206 if (!input_dev) {
1207 err = -ENOMEM;
1208 dev_err(&client->dev, "failed to allocate input device\n");
1209 goto free_mem;
1210 }
1211
1212 data->input_dev = input_dev;
1213 data->client = client;
1214 data->pdata = pdata;
1215
1216 input_dev->name = "ft5x06_ts";
1217 input_dev->id.bustype = BUS_I2C;
1218 input_dev->dev.parent = &client->dev;
1219
1220 input_set_drvdata(input_dev, data);
1221 i2c_set_clientdata(client, data);
1222
1223 __set_bit(EV_KEY, input_dev->evbit);
1224 __set_bit(EV_ABS, input_dev->evbit);
1225 __set_bit(BTN_TOUCH, input_dev->keybit);
Amy Malochedd2703d2012-06-20 11:03:56 -07001226 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301227
Mohan Pallaka959a69a2013-06-14 17:12:24 +05301228 input_mt_init_slots(input_dev, CFG_MAX_TOUCH_POINTS);
Mohan Pallaka3a138202013-05-09 16:30:00 +05301229 input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min,
Mohan Pallakaa2595072012-01-12 22:23:15 +05301230 pdata->x_max, 0, 0);
Mohan Pallaka3a138202013-05-09 16:30:00 +05301231 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min,
Mohan Pallakaa2595072012-01-12 22:23:15 +05301232 pdata->y_max, 0, 0);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301233 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, FT_PRESS, 0, 0);
1234 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, FT_PRESS, 0, 0);
1235
1236 err = input_register_device(input_dev);
1237 if (err) {
1238 dev_err(&client->dev, "Input device registration failed\n");
1239 goto free_inputdev;
1240 }
1241
1242 if (pdata->power_init) {
1243 err = pdata->power_init(true);
1244 if (err) {
1245 dev_err(&client->dev, "power init failed");
1246 goto unreg_inputdev;
1247 }
1248 } else {
1249 err = ft5x06_power_init(data, true);
1250 if (err) {
1251 dev_err(&client->dev, "power init failed");
1252 goto unreg_inputdev;
1253 }
1254 }
1255
1256 if (pdata->power_on) {
1257 err = pdata->power_on(true);
1258 if (err) {
1259 dev_err(&client->dev, "power on failed");
1260 goto pwr_deinit;
1261 }
1262 } else {
1263 err = ft5x06_power_on(data, true);
1264 if (err) {
1265 dev_err(&client->dev, "power on failed");
1266 goto pwr_deinit;
1267 }
1268 }
1269
1270 if (gpio_is_valid(pdata->irq_gpio)) {
1271 err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio");
1272 if (err) {
1273 dev_err(&client->dev, "irq gpio request failed");
1274 goto pwr_off;
1275 }
1276 err = gpio_direction_input(pdata->irq_gpio);
1277 if (err) {
1278 dev_err(&client->dev,
1279 "set_direction for irq gpio failed\n");
1280 goto free_irq_gpio;
1281 }
1282 }
1283
1284 if (gpio_is_valid(pdata->reset_gpio)) {
1285 err = gpio_request(pdata->reset_gpio, "ft5x06_reset_gpio");
1286 if (err) {
1287 dev_err(&client->dev, "reset gpio request failed");
1288 goto free_irq_gpio;
1289 }
1290
1291 err = gpio_direction_output(pdata->reset_gpio, 0);
1292 if (err) {
1293 dev_err(&client->dev,
1294 "set_direction for reset gpio failed\n");
1295 goto free_reset_gpio;
1296 }
1297 msleep(FT_RESET_DLY);
1298 gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
1299 }
1300
1301 /* make sure CTP already finish startup process */
1302 msleep(FT_STARTUP_DLY);
1303
Mohan Pallaka3a138202013-05-09 16:30:00 +05301304 /* check the controller id */
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301305 reg_addr = FT_REG_ID;
Mohan Pallaka3a138202013-05-09 16:30:00 +05301306 err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
1307 if (err < 0) {
1308 dev_err(&client->dev, "version read failed");
1309 return err;
1310 }
1311
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301312 dev_info(&client->dev, "Device ID = 0x%x\n", reg_value);
1313
Mohan Pallaka3a138202013-05-09 16:30:00 +05301314 if (pdata->family_id != reg_value) {
1315 dev_err(&client->dev, "%s:Unsupported controller\n", __func__);
1316 goto free_reset_gpio;
1317 }
1318
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301319 data->family_id = reg_value;
1320
Mohan Pallakaa2595072012-01-12 22:23:15 +05301321 err = request_threaded_irq(client->irq, NULL,
1322 ft5x06_ts_interrupt, pdata->irqflags,
1323 client->dev.driver->name, data);
1324 if (err) {
1325 dev_err(&client->dev, "request irq failed\n");
1326 goto free_reset_gpio;
1327 }
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301328
1329 err = device_create_file(&client->dev, &dev_attr_fw_name);
1330 if (err) {
1331 dev_err(&client->dev, "sys file creation failed\n");
1332 goto irq_free;
1333 }
1334
1335 err = device_create_file(&client->dev, &dev_attr_update_fw);
1336 if (err) {
1337 dev_err(&client->dev, "sys file creation failed\n");
1338 goto free_fw_name_sys;
1339 }
1340
1341 err = device_create_file(&client->dev, &dev_attr_force_update_fw);
1342 if (err) {
1343 dev_err(&client->dev, "sys file creation failed\n");
1344 goto free_update_fw_sys;
1345 }
1346
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301347 data->dir = debugfs_create_dir(FT_DEBUG_DIR_NAME, NULL);
1348 if (data->dir == NULL || IS_ERR(data->dir)) {
1349 pr_err("debugfs_create_dir failed(%ld)\n", PTR_ERR(data->dir));
1350 err = PTR_ERR(data->dir);
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301351 goto free_force_update_fw_sys;
1352 }
1353
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301354 temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, data->dir, data,
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301355 &debug_addr_fops);
1356 if (temp == NULL || IS_ERR(temp)) {
1357 pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
1358 err = PTR_ERR(temp);
1359 goto free_debug_dir;
1360 }
1361
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301362 temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, data->dir, data,
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301363 &debug_data_fops);
1364 if (temp == NULL || IS_ERR(temp)) {
1365 pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
1366 err = PTR_ERR(temp);
1367 goto free_debug_dir;
1368 }
1369
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301370 temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, data->dir,
1371 data, &debug_suspend_fops);
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301372 if (temp == NULL || IS_ERR(temp)) {
1373 pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
1374 err = PTR_ERR(temp);
1375 goto free_debug_dir;
1376 }
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301377
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301378 temp = debugfs_create_file("dump_info", S_IRUSR | S_IWUSR, data->dir,
1379 data, &debug_dump_info_fops);
1380 if (temp == NULL || IS_ERR(temp)) {
1381 pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
1382 err = PTR_ERR(temp);
1383 goto free_debug_dir;
1384 }
1385
1386 data->ts_info = kzalloc(FT_INFO_MAX_LEN, GFP_KERNEL);
1387 if (!data->ts_info) {
1388 dev_err(&client->dev, "Not enough memory\n");
1389 goto free_debug_dir;
1390 }
1391
1392 /*get some register information */
1393 reg_addr = FT_REG_POINT_RATE;
1394 ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
1395 if (err < 0)
1396 dev_err(&client->dev, "report rate read failed");
1397
1398 dev_info(&client->dev, "report rate = %dHz\n", reg_value * 10);
1399
1400 reg_addr = FT_REG_THGROUP;
1401 err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
1402 if (err < 0)
1403 dev_err(&client->dev, "threshold read failed");
1404
1405 dev_dbg(&client->dev, "touch threshold = %d\n", reg_value * 4);
1406
1407 reg_addr = FT_REG_FW_VER;
1408 err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
1409 if (err < 0)
1410 dev_err(&client->dev, "version read failed");
1411
1412 dev_info(&client->dev, "Firmware version = 0x%x\n", reg_value);
1413
1414 FT_STORE_TS_INFO(data->ts_info, data->family_id, reg_value);
1415
Mohan Pallakaa5d601b2013-05-10 15:34:44 +05301416#if defined(CONFIG_FB)
1417 data->fb_notif.notifier_call = fb_notifier_callback;
Mohan Pallakaa2595072012-01-12 22:23:15 +05301418
Mohan Pallakaa5d601b2013-05-10 15:34:44 +05301419 err = fb_register_client(&data->fb_notif);
1420
1421 if (err)
1422 dev_err(&client->dev, "Unable to register fb_notifier: %d\n",
1423 err);
1424#elif defined(CONFIG_HAS_EARLYSUSPEND)
Mohan Pallakaa2595072012-01-12 22:23:15 +05301425 data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301426 FT_SUSPEND_LEVEL;
Mohan Pallakaa2595072012-01-12 22:23:15 +05301427 data->early_suspend.suspend = ft5x06_ts_early_suspend;
1428 data->early_suspend.resume = ft5x06_ts_late_resume;
1429 register_early_suspend(&data->early_suspend);
1430#endif
1431
1432 return 0;
1433
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301434free_debug_dir:
1435 debugfs_remove_recursive(data->dir);
1436free_force_update_fw_sys:
1437 device_remove_file(&client->dev, &dev_attr_force_update_fw);
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301438free_update_fw_sys:
1439 device_remove_file(&client->dev, &dev_attr_update_fw);
1440free_fw_name_sys:
1441 device_remove_file(&client->dev, &dev_attr_fw_name);
1442irq_free:
1443 free_irq(client->irq, data);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301444free_reset_gpio:
1445 if (gpio_is_valid(pdata->reset_gpio))
1446 gpio_free(pdata->reset_gpio);
1447free_irq_gpio:
1448 if (gpio_is_valid(pdata->irq_gpio))
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301449 gpio_free(pdata->irq_gpio);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301450pwr_off:
1451 if (pdata->power_on)
1452 pdata->power_on(false);
1453 else
1454 ft5x06_power_on(data, false);
1455pwr_deinit:
1456 if (pdata->power_init)
1457 pdata->power_init(false);
1458 else
1459 ft5x06_power_init(data, false);
1460unreg_inputdev:
1461 input_unregister_device(input_dev);
1462 input_dev = NULL;
1463free_inputdev:
1464 input_free_device(input_dev);
1465free_mem:
1466 kfree(data);
1467 return err;
1468}
1469
1470static int __devexit ft5x06_ts_remove(struct i2c_client *client)
1471{
1472 struct ft5x06_ts_data *data = i2c_get_clientdata(client);
1473
Mohan Pallaka4fcf6f12013-06-07 17:47:42 +05301474 debugfs_remove_recursive(data->dir);
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301475 device_remove_file(&client->dev, &dev_attr_force_update_fw);
1476 device_remove_file(&client->dev, &dev_attr_update_fw);
1477 device_remove_file(&client->dev, &dev_attr_fw_name);
1478
Mohan Pallakaa5d601b2013-05-10 15:34:44 +05301479#if defined(CONFIG_FB)
1480 if (fb_unregister_client(&data->fb_notif))
1481 dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
1482#elif defined(CONFIG_HAS_EARLYSUSPEND)
Mohan Pallakaa2595072012-01-12 22:23:15 +05301483 unregister_early_suspend(&data->early_suspend);
1484#endif
1485 free_irq(client->irq, data);
1486
1487 if (gpio_is_valid(data->pdata->reset_gpio))
1488 gpio_free(data->pdata->reset_gpio);
1489
1490 if (gpio_is_valid(data->pdata->irq_gpio))
Mohan Pallaka6d2ab952013-06-04 17:36:20 +05301491 gpio_free(data->pdata->irq_gpio);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301492
1493 if (data->pdata->power_on)
1494 data->pdata->power_on(false);
1495 else
1496 ft5x06_power_on(data, false);
1497
1498 if (data->pdata->power_init)
1499 data->pdata->power_init(false);
1500 else
1501 ft5x06_power_init(data, false);
1502
1503 input_unregister_device(data->input_dev);
Mohan Pallaka768d5e32013-06-14 17:50:10 +05301504 kfree(data->ts_info);
Mohan Pallakaa2595072012-01-12 22:23:15 +05301505 kfree(data);
1506
1507 return 0;
1508}
1509
1510static const struct i2c_device_id ft5x06_ts_id[] = {
1511 {"ft5x06_ts", 0},
1512 {},
1513};
1514
1515MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id);
1516
Mohan Pallaka3a138202013-05-09 16:30:00 +05301517#ifdef CONFIG_OF
1518static struct of_device_id ft5x06_match_table[] = {
1519 { .compatible = "focaltech,5x06",},
1520 { },
1521};
1522#else
1523#define ft5x06_match_table NULL
1524#endif
1525
Mohan Pallakaa2595072012-01-12 22:23:15 +05301526static struct i2c_driver ft5x06_ts_driver = {
1527 .probe = ft5x06_ts_probe,
1528 .remove = __devexit_p(ft5x06_ts_remove),
1529 .driver = {
1530 .name = "ft5x06_ts",
1531 .owner = THIS_MODULE,
Mohan Pallaka3a138202013-05-09 16:30:00 +05301532 .of_match_table = ft5x06_match_table,
Mohan Pallakaa2595072012-01-12 22:23:15 +05301533#ifdef CONFIG_PM
1534 .pm = &ft5x06_ts_pm_ops,
1535#endif
1536 },
1537 .id_table = ft5x06_ts_id,
1538};
1539
1540static int __init ft5x06_ts_init(void)
1541{
1542 return i2c_add_driver(&ft5x06_ts_driver);
1543}
1544module_init(ft5x06_ts_init);
1545
1546static void __exit ft5x06_ts_exit(void)
1547{
1548 i2c_del_driver(&ft5x06_ts_driver);
1549}
1550module_exit(ft5x06_ts_exit);
1551
1552MODULE_DESCRIPTION("FocalTech ft5x06 TouchScreen driver");
1553MODULE_LICENSE("GPL v2");