blob: 4a91d6439a5ceb70b9c5cafc4162a5e2b814f3e2 [file] [log] [blame]
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001/* Touch_synaptics.c
2 *
3 * Copyright (C) 2011 LGE.
4 *
5 * Author: yehan.ahn@lge.com, hyesung.shin@lge.com
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/err.h>
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/i2c.h>
22#include <linux/slab.h>
23
24#include <linux/gpio.h>
25
26#include <linux/earlysuspend.h>
27#include <linux/input/lge_touch_core.h>
28#include <linux/input/touch_synaptics.h>
29
Jongrak Kwonae680ab2012-06-15 22:06:54 -070030#include "SynaImage.h"
Jongrak Kwonae680ab2012-06-15 22:06:54 -070031#include <linux/regulator/machine.h>
32
33/* RMI4 spec from (RMI4 spec)511-000136-01_revD
34 * Function Purpose See page
35 * $01 RMI Device Control 29
36 * $08 BIST(Built-in Self Test) 38
37 * $09 BIST(Built-in Self Test) 42
38 * $11 2-D TouchPad sensors 46
39 * $19 0-D capacitive button sensors 69
40 * $30 GPIO/LEDs (includes mechanical buttons) 76
41 * $32 Timer 89
42 * $34 Flash Memory Management 93
43 */
44#define RMI_DEVICE_CONTROL 0x01
45#define TOUCHPAD_SENSORS 0x11
46#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
47#define CAPACITIVE_BUTTON_SENSORS 0x1A
48#define GPIO_LEDS 0x31
49#define ANALOG_CONTROL 0x54
50#else
51#define CAPACITIVE_BUTTON_SENSORS 0x19
52#define GPIO_LEDS 0x30
53#endif
54#define TIMER 0x32
55#define FLASH_MEMORY_MANAGEMENT 0x34
56
57/* Register Map & Register bit mask
58 * - Please check "One time" this map before using this device driver
59 */
60
61#define MANUFACTURER_ID_REG (ts->common_dsc.query_base) /* Manufacturer ID */
62#define FW_REVISION_REG (ts->common_dsc.query_base+3) /* FW revision */
63#define PRODUCT_ID_REG (ts->common_dsc.query_base+11) /* Product ID */
64#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
65#define FW_VERSION (ts->flash_dsc.control_base)
66#endif
67
68#define DEVICE_CONTROL_REG (ts->common_dsc.control_base) /* Device Control */
69#define DEVICE_CONTROL_NORMAL_OP 0x00 /* sleep mode : go to doze mode after 500 ms */
70#define DEVICE_CONTROL_SLEEP 0x01 /* sleep mode : go to sleep */
71#define DEVICE_CONTROL_SPECIFIC 0x02 /* sleep mode : go to doze mode after 5 sec */
72#define DEVICE_CONTROL_NOSLEEP 0x04
73#define DEVICE_CONTROL_CONFIGURED 0x80
74
75#define INTERRUPT_ENABLE_REG (ts->common_dsc.control_base+1) /* Interrupt Enable 0 */
76
77#define DEVICE_STATUS_REG (ts->common_dsc.data_base) /* Device Status */
78#define DEVICE_FAILURE_MASK 0x03
79#define DEVICE_CRC_ERROR_MASK 0x04
80#define DEVICE_STATUS_FLASH_PROG 0x40
81#define DEVICE_STATUS_UNCONFIGURED 0x80
82
83#define INTERRUPT_STATUS_REG (ts->common_dsc.data_base+1) /* Interrupt Status */
84#define BUTTON_DATA_REG (ts->button_dsc.data_base) /* Button Data */
85#define MAX_NUM_OF_BUTTON 4
86
87#define FINGER_STATE_REG (ts->finger_dsc.data_base) /* Finger State */
88#define FINGER_DATA_REG_START (ts->finger_dsc.data_base+3) /* Finger Data Register */
89#define FINGER_STATE_MASK 0x03
90#define REG_X_POSITION 0
91#define REG_Y_POSITION 1
92#define REG_YX_POSITION 2
93#define REG_WY_WX 3
94#define REG_Z 4
95
96#define TWO_D_REPORTING_MODE (ts->finger_dsc.control_base+0) /* 2D Reporting Mode */
97#define REPORT_MODE_CONTINUOUS 0x00
98#define REPORT_MODE_REDUCED 0x01
99#define ABS_FILTER 0x08
100#define PALM_DETECT_REG (ts->finger_dsc.control_base+1) /* Palm Detect */
Jongrak Kwon9ed2a932012-06-19 23:38:02 -0700101#define DELTA_X_THRESH_REG (ts->finger_dsc.control_base+2) /* Delta-X Thresh */
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700102#define DELTA_Y_THRESH_REG (ts->finger_dsc.control_base+3) /* Delta-Y Thresh */
103#define SENSOR_MAX_X_POS (ts->finger_dsc.control_base+6) /* SensorMaxXPos */
104#define SENSOR_MAX_Y_POS (ts->finger_dsc.control_base+8) /* SensorMaxYPos */
105#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
106/*do nothing*/
107#else
108#define GESTURE_ENABLE_1_REG (ts->finger_dsc.control_base+10) /* Gesture Enables 1 */
109#define GESTURE_ENABLE_2_REG (ts->finger_dsc.control_base+11) /* Gesture Enables 2 */
110#endif
111
112#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
113#define PAGE_SELECT_REG 0xFF /* Button exists Page 02 */
114#define ANALOG_CONTROL_REG (ts->analog_dsc.control_base)
115#define ANALOG_COMMAND_REG (ts->analog_dsc.command_base)
116#define FAST_RELAXATION_RATE (ts->analog_dsc.control_base+16)
117#define FORCE_FAST_RELAXATION 0x04
118#define FORCE_UPDATE 0x04
119#else
120#define MELT_CONTROL_REG 0xF0
121#define MELT_CONTROL_NO_MELT 0x00
122#define MELT_CONTROL_MELT 0x01
123#define MELT_CONTROL_NUKE_MELT 0x80
124#endif
125
126#define DEVICE_COMMAND_REG (ts->common_dsc.command_base)
127#define FINGER_COMMAND_REG (ts->finger_dsc.command_base)
128#define BUTTON_COMMAND_REG (ts->button_dsc.command_base)
129
130#define FLASH_CONTROL_REG (ts->flash_dsc.data_base+18) /* Flash Control */
131#define FLASH_STATUS_MASK 0xF0
132
133/* Get user-finger-data from register.
134 */
135#define TS_SNTS_GET_X_POSITION(_high_reg, _low_reg) \
136 (((u16)(((_high_reg) << 4) & 0x0FF0) | (u16)((_low_reg) & 0x0F)))
137#define TS_SNTS_GET_Y_POSITION(_high_reg, _low_reg) \
138 (((u16)(((_high_reg) << 4) & 0x0FF0) | (u16)(((_low_reg) >> 4) & 0x0F)))
139#define TS_SNTS_GET_WIDTH_MAJOR(_width) \
140 ((((((_width) & 0xF0) >> 4) - ((_width) & 0x0F)) > 0) ? \
141 ((_width) & 0xF0) >> 4 : (_width) & 0x0F)
142#define TS_SNTS_GET_WIDTH_MINOR(_width) \
143 ((((((_width) & 0xF0) >> 4) - ((_width) & 0x0F)) > 0) ? \
144 (_width) & 0x0F : ((_width) & 0xF0) >> 4)
145#define TS_SNTS_GET_ORIENTATION(_width) \
146 ((((((_width) & 0xF0) >> 4) - ((_width) & 0x0F)) > 0) ? 0 : 1)
147#define TS_SNTS_GET_PRESSURE(_pressure) (_pressure)
148
149
150/* GET_BIT_MASK & GET_INDEX_FROM_MASK
151 *
152 * For easily checking the user input.
153 * Usually, User use only one or two fingers.
154 * However, we should always check all finger-status-register
155 * because we can't know the total number of fingers.
156 * These Macro will prevent it.
157 */
158#define GET_BIT_MASK(_finger_status_reg) \
159 ((_finger_status_reg[2] & 0x04) << 7 | \
160 (_finger_status_reg[2] & 0x01) << 8 | \
161 (_finger_status_reg[1] & 0x40) << 1 | \
162 (_finger_status_reg[1] & 0x10) << 2 | \
163 (_finger_status_reg[1] & 0x04) << 3 | \
164 (_finger_status_reg[1] & 0x01) << 4 | \
165 (_finger_status_reg[0] & 0x40) >> 3 | \
166 (_finger_status_reg[0] & 0x10) >> 2 | \
167 (_finger_status_reg[0] & 0x04) >> 1 | \
168 (_finger_status_reg[0] & 0x01))
169
170#define GET_INDEX_FROM_MASK(_index, _bit_mask, _max_finger) \
171 do { \
172 for (; !((_bit_mask>>_index)&0x01) \
173 && _index <= _max_finger; _index++); \
174 if (_index <= _max_finger) \
175 _bit_mask &= ~(_bit_mask & (1<<(_index))); \
176 } while (0)
177
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700178
179#define FINGER_STATE_NO_PRESENT 0
180#define FINGER_STATE_PRESENT_VALID 1
181#define FINGER_STATE_PRESENT_NOVALID 2
182#define FINGER_STATE_REVSERVED 3
183
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700184int synaptics_ts_get_data(struct i2c_client *client, struct t_data* data,
185 struct b_data* button, u8* total_num)
186{
187 struct synaptics_ts_data* ts =
188 (struct synaptics_ts_data*)get_touch_handle(client);
189
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700190 u32 finger_status=0;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700191 u8 finger_index=0;
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700192 u8 id=0;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700193 u8 cnt;
194
195 if (unlikely(touch_debug_mask & DEBUG_TRACE))
196 TOUCH_DEBUG_MSG("\n");
197
198 if (unlikely(touch_i2c_read(client, DEVICE_STATUS_REG,
Jongrak Kwon5297b722012-06-22 11:18:36 -0700199 sizeof(ts->ts_data.device_status_reg),
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700200 &ts->ts_data.device_status_reg) < 0)) {
201 TOUCH_ERR_MSG("DEVICE_STATUS_REG read fail\n");
202 goto err_synaptics_getdata;
203 }
204
205 /* ESD damage check */
206 if ((ts->ts_data.device_status_reg & DEVICE_FAILURE_MASK) ==
207 DEVICE_FAILURE_MASK) {
208 TOUCH_ERR_MSG("ESD damage occured. Reset Touch IC\n");
209 goto err_synaptics_device_damage;
210 }
211
212 /* Internal reset check */
213 if (((ts->ts_data.device_status_reg & DEVICE_STATUS_UNCONFIGURED) >> 7) == 1) {
214 TOUCH_ERR_MSG("Touch IC resetted internally. "
215 "Reconfigure register setting\n");
216 goto err_synaptics_device_damage;
217 }
218
219 if (unlikely(touch_i2c_read(client, INTERRUPT_STATUS_REG,
220 sizeof(ts->ts_data.interrupt_status_reg),
221 &ts->ts_data.interrupt_status_reg) < 0)) {
222 TOUCH_ERR_MSG("INTERRUPT_STATUS_REG read fail\n");
223 goto err_synaptics_getdata;
224 }
225
226 if (unlikely(touch_debug_mask & DEBUG_GET_DATA))
227 TOUCH_INFO_MSG("Interrupt_status : 0x%x\n",
228 ts->ts_data.interrupt_status_reg);
229
230 /* IC bug Exception handling - Interrupt status reg is 0 when interrupt occur */
231 if (ts->ts_data.interrupt_status_reg == 0) {
232 TOUCH_ERR_MSG("Interrupt_status reg is 0. "
233 "Something is wrong in IC\n");
234 goto err_synaptics_device_damage;
235 }
236
237 /* Because of ESD damage... */
238 if (unlikely(ts->ts_data.interrupt_status_reg & ts->interrupt_mask.flash)) {
239 TOUCH_ERR_MSG("Impossible Interrupt\n");
240 goto err_synaptics_device_damage;
241 }
242
243 /* Finger */
244 if (likely(ts->ts_data.interrupt_status_reg & ts->interrupt_mask.abs)) {
245 if (unlikely(touch_i2c_read(client, FINGER_STATE_REG,
246 sizeof(ts->ts_data.finger.finger_status_reg),
247 ts->ts_data.finger.finger_status_reg) < 0)) {
248 TOUCH_ERR_MSG("FINGER_STATE_REG read fail\n");
249 goto err_synaptics_getdata;
250 }
251
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700252 finger_status = ts->ts_data.finger.finger_status_reg[0] |
253 ts->ts_data.finger.finger_status_reg[1] << 8 |
254 (ts->ts_data.finger.finger_status_reg[2] & 0xF) << 16;
255
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700256 if (unlikely(touch_debug_mask & DEBUG_GET_DATA)) {
257 TOUCH_INFO_MSG("Finger_status : 0x%x, 0x%x, 0x%x\n",
258 ts->ts_data.finger.finger_status_reg[0],
259 ts->ts_data.finger.finger_status_reg[1],
260 ts->ts_data.finger.finger_status_reg[2]);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700261 TOUCH_INFO_MSG("Touch_bit_mask: 0x%x\n", finger_status);
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700262 }
263
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700264 for (id = 0; id < MAX_FINGER; id++) {
265 switch (((finger_status >> (id*2)) & 0x3)) {
266 case FINGER_STATE_PRESENT_VALID:
267 touch_i2c_read(ts->client,
268 FINGER_DATA_REG_START + NUM_OF_EACH_FINGER_DATA_REG * id,
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700269 NUM_OF_EACH_FINGER_DATA_REG,
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700270 ts->ts_data.finger.finger_reg[id]);
271 data[id].state = ABS_PRESS;
272 data[id].x_position = TS_SNTS_GET_X_POSITION(
273 ts->ts_data.finger.finger_reg[id][REG_X_POSITION],
274 ts->ts_data.finger.finger_reg[id][REG_YX_POSITION]);
275 data[id].y_position = TS_SNTS_GET_Y_POSITION(ts->ts_data.finger.finger_reg[id][REG_Y_POSITION], ts->ts_data.finger.finger_reg[id][REG_YX_POSITION]);
276 data[id].width_major = TS_SNTS_GET_WIDTH_MAJOR(ts->ts_data.finger.finger_reg[id][REG_WY_WX]);
277 data[id].width_minor = TS_SNTS_GET_WIDTH_MINOR(ts->ts_data.finger.finger_reg[id][REG_WY_WX]);
278 data[id].width_orientation = TS_SNTS_GET_ORIENTATION(ts->ts_data.finger.finger_reg[id][REG_WY_WX]);
279 data[id].pressure = TS_SNTS_GET_PRESSURE(ts->ts_data.finger.finger_reg[id][REG_Z]);
280
281 if (unlikely(touch_debug_mask & DEBUG_GET_DATA))
282 TOUCH_INFO_MSG("[%d] pos(%4d,%4d) w_m[%2d] w_n[%2d] w_o[%2d] p[%2d]\n",
283 finger_index,
284 data[id].x_position,
285 data[id].y_position,
286 data[id].width_major,
287 data[id].width_minor,
288 data[id].width_orientation,
289 data[id].pressure);
290 (*total_num)++;
291 break;
292
293 case FINGER_STATE_NO_PRESENT:
294 if (data[id].state == ABS_PRESS)
295 data[id].state = ABS_RELEASE;
296 break;
297
298 default:
299 /* Do nothing including inacurate data */
300 break;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700301 }
302
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700303 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700304 if (unlikely(touch_debug_mask & DEBUG_GET_DATA))
305 TOUCH_INFO_MSG("Total_num: %d\n", *total_num);
306 }
307
308 /* Button */
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700309 if ((ts->button_dsc.id != 0) && (ts->ts_data.interrupt_status_reg &
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700310 ts->interrupt_mask.button)) {
311
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700312 if (unlikely(touch_i2c_write_byte(client,
313 PAGE_SELECT_REG, 0x02) < 0)) {
314 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
315 return -EIO;
316 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700317
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700318 if (unlikely(touch_i2c_read(client, BUTTON_DATA_REG,
319 sizeof(ts->ts_data.button_data_reg),
320 &ts->ts_data.button_data_reg) < 0)) {
321 TOUCH_ERR_MSG("BUTTON_DATA_REG read fail\n");
322 goto err_synaptics_getdata;
323 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700324
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700325 if (unlikely(touch_i2c_write_byte(client,
326 PAGE_SELECT_REG, 0x00) < 0)) {
327 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
328 return -EIO;
329 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700330
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700331 if (unlikely(touch_debug_mask & DEBUG_BUTTON))
332 TOUCH_DEBUG_MSG("Button register: 0x%x\n",
333 ts->ts_data.button_data_reg);
334
335 if (ts->ts_data.button_data_reg) {
336 /* pressed - find first one */
337 for (cnt = 0; cnt < ts->pdata->caps->number_of_button; cnt++) {
338 if ((ts->ts_data.button_data_reg >> cnt) & 1)
339 {
340 ts->ts_data.button.key_code =
341 ts->pdata->caps->button_name[cnt];
342 button->key_code =
343 ts->ts_data.button.key_code;
344 button->state = 1;
345 break;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700346 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700347 }
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700348 } else {
349 /* release */
350 button->key_code = ts->ts_data.button.key_code;
351 button->state = 0;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700352 }
353 }
354
355 return 0;
356
357err_synaptics_device_damage:
358err_synaptics_getdata:
359 return -EIO;
360}
361
362static int read_page_description_table(struct i2c_client* client)
363{
364 struct synaptics_ts_data* ts =
365 (struct synaptics_ts_data*)get_touch_handle(client);
366 struct ts_function_descriptor buffer;
367 unsigned short u_address;
368
369 if (touch_debug_mask & DEBUG_TRACE)
370 TOUCH_DEBUG_MSG("\n");
371
372 memset(&buffer, 0x0, sizeof(struct ts_function_descriptor));
373
374 ts->common_dsc.id = 0;
375 ts->finger_dsc.id = 0;
376 ts->button_dsc.id = 0;
377 ts->flash_dsc.id = 0;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700378 ts->analog_dsc.id = 0;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700379
380 for (u_address = DESCRIPTION_TABLE_START; u_address > 10;
381 u_address -= sizeof(struct ts_function_descriptor)) {
382 if (unlikely(touch_i2c_read(client, u_address, sizeof(buffer),
383 (unsigned char *)&buffer) < 0)) {
384 TOUCH_ERR_MSG("RMI4 Function Descriptor read fail\n");
385 return -EIO;
386 }
387
388 if (buffer.id == 0)
389 break;
390
391 switch (buffer.id) {
392 case RMI_DEVICE_CONTROL:
393 ts->common_dsc = buffer;
394 break;
395 case TOUCHPAD_SENSORS:
396 ts->finger_dsc = buffer;
397 break;
398 case FLASH_MEMORY_MANAGEMENT:
399 ts->flash_dsc = buffer;
Jongrak Kwon420825a2012-06-26 16:33:25 -0700400 break;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700401 }
402 }
403
404#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
405 if (unlikely(touch_i2c_write_byte(client, PAGE_SELECT_REG, 0x01) < 0)) {
406 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
407 return -EIO;
408 }
409
Jongrak Kwon420825a2012-06-26 16:33:25 -0700410 if (unlikely(touch_i2c_read(client, ANALOG_TABLE_START, sizeof(buffer), (unsigned char *)&buffer) < 0)) {
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700411 TOUCH_ERR_MSG("RMI4 Function Descriptor read fail\n");
412 return -EIO;
413 }
414
Jongrak Kwon420825a2012-06-26 16:33:25 -0700415 if (buffer.id == ANALOG_CONTROL) {
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700416 ts->analog_dsc = buffer;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700417 }
418
419 if (unlikely(touch_i2c_write_byte(client, PAGE_SELECT_REG, 0x02) < 0)) {
420 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
421 return -EIO;
422 }
423
Jongrak Kwon420825a2012-06-26 16:33:25 -0700424 if (unlikely(touch_i2c_read(ts->client, BUTTON_TABLE_START, sizeof(buffer), (unsigned char *)&buffer))) {
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700425 TOUCH_ERR_MSG("Button ts_function_descriptor read fail\n");
426 return -EIO;
427 }
428
Jongrak Kwon420825a2012-06-26 16:33:25 -0700429 if (buffer.id == CAPACITIVE_BUTTON_SENSORS)
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700430 ts->button_dsc = buffer;
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700431
432 if (unlikely(touch_i2c_write_byte(client, PAGE_SELECT_REG, 0x00) < 0)) {
433 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
434 return -EIO;
435 }
436#endif
437
438 /* set interrupt mask */
439 ts->interrupt_mask.flash = 0x1;
440 ts->interrupt_mask.status = 0x2;
441
442 if (ts->button_dsc.id == 0) {
443 ts->interrupt_mask.abs = 0x4;
444 } else {
445 if (ts->finger_dsc.data_base > ts->button_dsc.data_base) {
446#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
447 ts->interrupt_mask.abs = 0x4;
448 ts->interrupt_mask.button = 0x20;
449#else
450 ts->interrupt_mask.abs = 0x8;
451 ts->interrupt_mask.button = 0x4;
452#endif
453 } else {
454 ts->interrupt_mask.abs = 0x4;
455 ts->interrupt_mask.button = 0x8;
456 }
457 }
458
459 if (ts->common_dsc.id == 0 || ts->finger_dsc.id == 0 ||
460 ts->flash_dsc.id == 0) {
461 TOUCH_ERR_MSG("common_dsc/finger_dsc/flash_dsc are not initiailized\n");
462 return -EPERM;
463 }
464
465 if (touch_debug_mask & DEBUG_BASE_INFO)
466 TOUCH_INFO_MSG("common[%d] finger[%d] flash[%d] button[%d]\n",
467 ts->common_dsc.id, ts->finger_dsc.id,
468 ts->flash_dsc.id, ts->button_dsc.id);
469
470 return 0;
471}
472
473int get_ic_info(struct synaptics_ts_data* ts, struct touch_fw_info* fw_info)
474{
475#if defined(ARRAYED_TOUCH_FW_BIN)
476 int cnt;
477#endif
478 u8 device_status = 0;
479 u8 flash_control = 0;
480
481 read_page_description_table(ts->client);
482
483 memset(fw_info, 0, sizeof(fw_info));
484
485 if (unlikely(touch_i2c_read(ts->client, FW_REVISION_REG,
486 sizeof(fw_info->fw_rev), &fw_info->fw_rev) < 0)) {
487 TOUCH_ERR_MSG("FW_REVISION_REG read fail\n");
488 return -EIO;
489 }
490
491 if (unlikely(touch_i2c_read(ts->client, MANUFACTURER_ID_REG,
492 sizeof(fw_info->manufacturer_id),
493 &fw_info->manufacturer_id) < 0)) {
494 TOUCH_ERR_MSG("MANUFACTURER_ID_REG read fail\n");
495 return -EIO;
496 }
497
498 if (unlikely(touch_i2c_read(ts->client, PRODUCT_ID_REG,
499 sizeof(fw_info->product_id) - 1,
500 fw_info->product_id) < 0)) {
501 TOUCH_ERR_MSG("PRODUCT_ID_REG read fail\n");
502 return -EIO;
503 }
504
505 if (unlikely(touch_i2c_read(ts->client, FW_VERSION,
506 sizeof(fw_info->fw_version) - 1,
507 fw_info->fw_version) < 0)) {
508 TOUCH_ERR_MSG("FW_VERSION read fail\n");
509 return -EIO;
510 }
511
512#if defined(CONFIG_TOUCH_REG_MAP_TM2000)
513 if ((strncmp(fw_info->fw_version, "0000", 4) == 0) ||
514 (strncmp(fw_info->fw_version, "S001", 4) == 0)) {
515 ts->ic_panel_type = IC7020_GFF;
516 TOUCH_INFO_MSG("IC is 7020, panel is GFF.");
517 } else {
518 if (fw_info->fw_version[0] == 'E' &&
519 (int)simple_strtol(&fw_info->fw_version[1], NULL, 10) < 14) {
520 ts->ic_panel_type = IC7020_G2;
521 TOUCH_INFO_MSG("IC is 7020, panel is G2.");
522 } else if ((fw_info->fw_version[0] == 'E'
523 && (int)simple_strtol(&fw_info->fw_version[1], NULL, 10) >= 14
524 && (int)simple_strtol(&fw_info->fw_version[1], NULL, 10) < 27)
525 || fw_info->fw_version[0] == 'T') {
526 ts->ic_panel_type = IC3203_G2;
527 TOUCH_INFO_MSG("IC is 3203, panel is G2.");
528 } else {
529 ts->ic_panel_type = IC7020_G2_H_PTN;
530 TOUCH_INFO_MSG("IC is 7020, H pattern, panel is G2.");
531
532 if ((fw_info->fw_version[0] == 'E')
533 && ((int)simple_strtol(&fw_info->fw_version[1],
534 NULL, 10) >= 40)) {
535 ts->interrupt_mask.button = 0x10;
536 }
537 }
538 }
539#elif defined(CONFIG_TOUCH_REG_MAP_TM2372)
540 ts->ic_panel_type = IC7020_GFF_H_PTN;
541 TOUCH_INFO_MSG("IC is 7020, H pattern, panel is GFF.");
542#endif
543
544#if defined(ARRAYED_TOUCH_FW_BIN)
545 for (cnt = 0; cnt < sizeof(SynaFirmware)/sizeof(SynaFirmware[0]); cnt++) {
546 strncpy(fw_info->fw_image_product_id,
547 &SynaFirmware[cnt][16], 10);
548 if (!(strncmp(fw_info->product_id,
549 fw_info->fw_image_product_id, 10)))
550 break;
551 }
552 fw_info->fw_start = (unsigned char *)&SynaFirmware[cnt][0];
553 fw_info->fw_size = sizeof(SynaFirmware[0]);
554#else
555 strncpy(fw_info->fw_image_product_id, &SynaFirmware[16], 10);
556#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
557 strncpy(fw_info->fw_image_version, &SynaFirmware[0xb100],4);
558#endif
559 fw_info->fw_start = (unsigned char *)&SynaFirmware[0];
560 fw_info->fw_size = sizeof(SynaFirmware);
561#endif
562
563 fw_info->fw_image_rev = fw_info->fw_start[31];
564
565 if (unlikely(touch_i2c_read(ts->client, FLASH_CONTROL_REG,
566 sizeof(flash_control), &flash_control) < 0)) {
567 TOUCH_ERR_MSG("FLASH_CONTROL_REG read fail\n");
568 return -EIO;
569 }
570
571 if (unlikely(touch_i2c_read(ts->client, DEVICE_STATUS_REG,
572 sizeof(device_status), &device_status) < 0)) {
573 TOUCH_ERR_MSG("DEVICE_STATUS_REG read fail\n");
574 return -EIO;
575 }
576
577 /* Firmware has a problem, so we should firmware-upgrade */
578 if (device_status & DEVICE_STATUS_FLASH_PROG
579 || (device_status & DEVICE_CRC_ERROR_MASK) != 0
580 || (flash_control & FLASH_STATUS_MASK) != 0) {
581 TOUCH_ERR_MSG("Firmware has a unknown-problem, "
582 "so it needs firmware-upgrade.\n");
583 TOUCH_ERR_MSG("FLASH_CONTROL[%x] DEVICE_STATUS_REG[%x]\n",
584 (u32)flash_control, (u32)device_status);
585
586 fw_info->fw_rev = 0;
587#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
588 fw_info->fw_force_rework = true;
589#endif
590 }
591
592 ts->fw_info = fw_info;
593
594 return 0;
595}
596
597int synaptics_ts_init(struct i2c_client* client, struct touch_fw_info* fw_info)
598{
599 struct synaptics_ts_data* ts =
600 (struct synaptics_ts_data*)get_touch_handle(client);
Jongrak Kwon9ed2a932012-06-19 23:38:02 -0700601 struct lge_touch_data *lg_ts =
602 (struct lge_touch_data *) i2c_get_clientdata(client);
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700603 u8 buf;
604
605 if (touch_debug_mask & DEBUG_TRACE)
606 TOUCH_DEBUG_MSG("\n");
607
608 if (!ts->is_probed)
609 if (unlikely(get_ic_info(ts, fw_info) < 0))
610 return -EIO;
611
612 if (unlikely(touch_i2c_write_byte(client, DEVICE_CONTROL_REG,
613 DEVICE_CONTROL_NOSLEEP | DEVICE_CONTROL_CONFIGURED) < 0)) {
614 TOUCH_ERR_MSG("DEVICE_CONTROL_REG write fail\n");
615 return -EIO;
616 }
617
618 if (unlikely(touch_i2c_read(client, INTERRUPT_ENABLE_REG,
619 1, &buf) < 0)) {
620 TOUCH_ERR_MSG("INTERRUPT_ENABLE_REG read fail\n");
621 return -EIO;
622 }
Jongrak Kwon9ed2a932012-06-19 23:38:02 -0700623
624 if (!lg_ts->pdata->caps->button_support) {
625 buf &= ~ts->interrupt_mask.button;
626 ts->interrupt_mask.button = 0;
627 }
628
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700629 if (unlikely(touch_i2c_write_byte(client, INTERRUPT_ENABLE_REG,
630 buf | ts->interrupt_mask.abs | ts->interrupt_mask.button) < 0)) {
631 TOUCH_ERR_MSG("INTERRUPT_ENABLE_REG write fail\n");
632 return -EIO;
633 }
634
635#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700636 if (ts->pdata->role->report_mode == CONTINUOUS_REPORT_MODE) {
637 if (unlikely(touch_i2c_write_byte(client, TWO_D_REPORTING_MODE,
638 REPORT_MODE_CONTINUOUS) < 0)) {
639 TOUCH_ERR_MSG("TWO_D_REPORTING_MODE write fail\n");
640 return -EIO;
641 }
642 } else { /* REDUCED_REPORT_MODE */
643 if (unlikely(touch_i2c_write_byte(client, TWO_D_REPORTING_MODE,
644 REPORT_MODE_REDUCED) < 0)) {
645 TOUCH_ERR_MSG("TWO_D_REPORTING_MODE write fail\n");
646 return -EIO;
647 }
Jongrak Kwon9ed2a932012-06-19 23:38:02 -0700648
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700649 if (unlikely(touch_i2c_write_byte(client, DELTA_X_THRESH_REG,
650 ts->pdata->role->delta_pos_threshold) < 0)) {
651 TOUCH_ERR_MSG("DELTA_X_THRESH_REG write fail\n");
652 return -EIO;
653 }
654 if (unlikely(touch_i2c_write_byte(client, DELTA_Y_THRESH_REG,
655 ts->pdata->role->delta_pos_threshold) < 0)) {
656 TOUCH_ERR_MSG("DELTA_Y_THRESH_REG write fail\n");
657 return -EIO;
658 }
659 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700660#else
661 if (unlikely(touch_i2c_write_byte(client,
662 GESTURE_ENABLE_1_REG, 0x00) < 0)) {
663 TOUCH_ERR_MSG("GESTURE_ENABLE_1_REG write fail\n");
664 return -EIO;
665 }
666 if (unlikely(touch_i2c_write_byte(client, GESTURE_ENABLE_2_REG, 0x00) < 0)) {
667 TOUCH_ERR_MSG("GESTURE_ENABLE_2_REG write fail\n");
668 return -EIO;
669 }
670
671 if (ts->pdata->role->report_mode == CONTINUOUS_REPORT_MODE) {
672 if (unlikely(touch_i2c_write_byte(client, TWO_D_REPORTING_MODE,
673 REPORT_MODE_CONTINUOUS) < 0)) {
674 TOUCH_ERR_MSG("TWO_D_REPORTING_MODE write fail\n");
675 return -EIO;
676 }
677 } else { /* REDUCED_REPORT_MODE */
678 if (unlikely(touch_i2c_write_byte(client, TWO_D_REPORTING_MODE,
679 REPORT_MODE_REDUCED) < 0)) {
680 TOUCH_ERR_MSG("TWO_D_REPORTING_MODE write fail\n");
681 return -EIO;
682 }
683
684 if (unlikely(touch_i2c_write_byte(client, DELTA_X_THRESH_REG,
685 ts->pdata->role->delta_pos_threshold) < 0)) {
686 TOUCH_ERR_MSG("DELTA_X_THRESH_REG write fail\n");
687 return -EIO;
688 }
689 if (unlikely(touch_i2c_write_byte(client, DELTA_Y_THRESH_REG,
690 ts->pdata->role->delta_pos_threshold) < 0)) {
691 TOUCH_ERR_MSG("DELTA_Y_THRESH_REG write fail\n");
692 return -EIO;
693 }
694 }
695#endif
696
697 if (unlikely(touch_i2c_read(client, INTERRUPT_STATUS_REG, 1, &buf) < 0)) {
698 TOUCH_ERR_MSG("INTERRUPT_STATUS_REG read fail\n");
699 return -EIO; /* it is critical problem because interrupt will not occur. */
700 }
701
702 if (unlikely(touch_i2c_read(client, FINGER_STATE_REG,
703 sizeof(ts->ts_data.finger.finger_status_reg),
704 ts->ts_data.finger.finger_status_reg) < 0)) {
705 TOUCH_ERR_MSG("FINGER_STATE_REG read fail\n");
706 /* it is critical problem because interrupt will not occur on some FW. */
707 return -EIO;
708 }
709
710 ts->is_probed = 1;
711
712 return 0;
713}
714
715int synaptics_ts_power(struct i2c_client* client, int power_ctrl)
716{
717 struct synaptics_ts_data* ts =
718 (struct synaptics_ts_data*)get_touch_handle(client);
719
720 if (touch_debug_mask & DEBUG_TRACE)
721 TOUCH_DEBUG_MSG("\n");
722
723 switch (power_ctrl) {
724 case POWER_OFF:
725 if (ts->pdata->pwr->use_regulator) {
726 regulator_disable(ts->regulator_vio);
727 regulator_disable(ts->regulator_vdd);
728 }
729 else
730 ts->pdata->pwr->power(0);
731
732 break;
733 case POWER_ON:
734 if (ts->pdata->pwr->use_regulator) {
735 regulator_enable(ts->regulator_vdd);
736 regulator_enable(ts->regulator_vio);
737 }
738 else
739 ts->pdata->pwr->power(1);
740
741 /* P2 H/W bug fix */
742 if (ts->pdata->reset_pin > 0) {
743 msleep(10);
744 gpio_set_value(ts->pdata->reset_pin, 0);
745 msleep(ts->pdata->role->reset_delay);
746 gpio_set_value(ts->pdata->reset_pin, 1);
747 }
748 break;
749 case POWER_SLEEP:
750 if (unlikely(touch_i2c_write_byte(client, DEVICE_CONTROL_REG,
751 DEVICE_CONTROL_SLEEP |
752 DEVICE_CONTROL_CONFIGURED) < 0)) {
753 TOUCH_ERR_MSG("DEVICE_CONTROL_REG write fail\n");
754 return -EIO;
755 }
756 break;
757 case POWER_WAKE:
758 if (unlikely(touch_i2c_write_byte(client, DEVICE_CONTROL_REG,
759 DEVICE_CONTROL_SPECIFIC |
760 DEVICE_CONTROL_CONFIGURED) < 0)) {
761 TOUCH_ERR_MSG("DEVICE_CONTROL_REG write fail\n");
762 return -EIO;
763 }
764 break;
765 default:
766 return -EIO;
767 break;
768 }
769
770 return 0;
771}
772
773int synaptics_ts_probe(struct i2c_client* client)
774{
775 struct synaptics_ts_data* ts;
776 int ret = 0;
777
778 if (touch_debug_mask & DEBUG_TRACE)
779 TOUCH_DEBUG_MSG("\n");
780
781 ts = kzalloc(sizeof(struct synaptics_ts_data), GFP_KERNEL);
782 if (!ts) {
783 TOUCH_ERR_MSG("Can not allocate memory\n");
784 ret = -ENOMEM;
785 goto err_alloc_data_failed;
786 }
787
788 set_touch_handle(client, ts);
789
790 ts->client = client;
791 ts->pdata = client->dev.platform_data;
792#if defined(CONFIG_TOUCH_REG_MAP_TM2000)
793 ts->ic_panel_type = IC7020_G2_H_PTN;
794#elif defined(CONFIG_TOUCH_REG_MAP_TM2372)
795 ts->ic_panel_type = IC7020_GFF_H_PTN;
796#endif
797
798 if (ts->pdata->pwr->use_regulator) {
799 ts->regulator_vdd =
800 regulator_get_exclusive(NULL, ts->pdata->pwr->vdd);
801 if (IS_ERR(ts->regulator_vdd)) {
802 TOUCH_ERR_MSG("FAIL: regulator_get_vdd - %s\n",
803 ts->pdata->pwr->vdd);
804 ret = -EPERM;
805 goto err_get_vdd_failed;
806 }
807
808 ts->regulator_vio = regulator_get_exclusive(NULL,
809 ts->pdata->pwr->vio);
810 if (IS_ERR(ts->regulator_vio)) {
811 TOUCH_ERR_MSG("FAIL: regulator_get_vio - %s\n",
812 ts->pdata->pwr->vio);
813 ret = -EPERM;
814 goto err_get_vio_failed;
815 }
816
817 if (ts->pdata->pwr->vdd_voltage > 0) {
818 ret = regulator_set_voltage(ts->regulator_vdd,
819 ts->pdata->pwr->vdd_voltage,
820 ts->pdata->pwr->vdd_voltage);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700821 if (ret < 0) {
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700822 TOUCH_ERR_MSG("FAIL: VDD voltage setting"
823 " - (%duV)\n",
824 ts->pdata->pwr->vdd_voltage);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700825 ret = -EPERM;
826 goto err_set_voltage;
827 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700828 }
829
830 if (ts->pdata->pwr->vio_voltage > 0) {
831 ret = regulator_set_voltage(ts->regulator_vio,
832 ts->pdata->pwr->vio_voltage,
833 ts->pdata->pwr->vio_voltage);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700834 if (ret < 0) {
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700835 TOUCH_ERR_MSG("FAIL: VIO voltage setting"
836 " - (%duV)\n",
837 ts->pdata->pwr->vio_voltage);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700838 ret = -EPERM;
839 goto err_set_voltage;
840 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700841 }
842 }
843
844 return ret;
845
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700846err_set_voltage:
847 if (ts->pdata->pwr->use_regulator) {
848 regulator_put(ts->regulator_vio);
849 }
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700850err_get_vio_failed:
851 if (ts->pdata->pwr->use_regulator) {
852 regulator_put(ts->regulator_vdd);
853 }
854err_get_vdd_failed:
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700855 kfree(ts);
Jongrak Kwon098aa9d2012-06-26 11:53:27 -0700856err_alloc_data_failed:
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700857 return ret;
858}
859
860void synaptics_ts_remove(struct i2c_client* client)
861{
862 struct synaptics_ts_data* ts =
863 (struct synaptics_ts_data*)get_touch_handle(client);
864
865 if (touch_debug_mask & DEBUG_TRACE)
866 TOUCH_DEBUG_MSG("\n");
867
868 if (ts->pdata->pwr->use_regulator) {
869 regulator_put(ts->regulator_vio);
870 regulator_put(ts->regulator_vdd);
871 }
872
873 kfree(ts);
874}
875
876int synaptics_ts_fw_upgrade(struct i2c_client* client, const char* fw_path)
877{
878 struct synaptics_ts_data* ts =
879 (struct synaptics_ts_data*)get_touch_handle(client);
880 int ret = 0;
881
882 ts->is_probed = 0;
883
884 ret = FirmwareUpgrade(ts, fw_path);
885
886 /* update IC info */
887 get_ic_info(ts, ts->fw_info);
888
889 return ret;
890}
891
892int synaptics_ts_ic_ctrl(struct i2c_client *client, u8 code, u16 value)
893{
894 struct synaptics_ts_data* ts =
895 (struct synaptics_ts_data*)get_touch_handle(client);
896 u8 buf = 0;
897
898 switch (code) {
899 case IC_CTRL_BASELINE:
900 switch (value) {
901 case BASELINE_OPEN:
Jongrak Kwon420825a2012-06-26 16:33:25 -0700902 if (!ts->analog_dsc.id) /* If not supported, ignore */
903 break;
904
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700905#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
906 if (unlikely(touch_i2c_write_byte(client,
907 PAGE_SELECT_REG, 0x01) < 0)) {
908 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
909 return -EIO;
910 }
911
912 if (unlikely(touch_i2c_write_byte(client,
913 ANALOG_CONTROL_REG,
914 FORCE_FAST_RELAXATION) < 0)) {
915 TOUCH_ERR_MSG("ANALOG_CONTROL_REG write fail\n");
916 return -EIO;
917 }
918
919 msleep(10);
920
921 if (unlikely(touch_i2c_write_byte(client,
922 ANALOG_COMMAND_REG,
923 FORCE_UPDATE) < 0)) {
924 TOUCH_ERR_MSG("force fast relaxation command write fail\n");
925 return -EIO;
926 }
927
928 if (unlikely(touch_i2c_write_byte(client,
929 PAGE_SELECT_REG, 0x00) < 0)) {
930 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
931 return -EIO;
932 }
933
934 if (unlikely(touch_debug_mask & DEBUG_GHOST))
935 TOUCH_INFO_MSG("BASELINE_OPEN ~~~~~~~~\n");
936#else
937 if (unlikely(touch_i2c_write_byte(client,
938 MELT_CONTROL_REG,
939 MELT_CONTROL_MELT) < 0)) {
940 TOUCH_ERR_MSG("MELT_CONTROL_REG write fail\n");
941 return -EIO;
942 }
943#endif
944 break;
945 case BASELINE_FIX:
Jongrak Kwon420825a2012-06-26 16:33:25 -0700946 if (!ts->analog_dsc.id) /* If not supported, ignore */
947 break;
948
Jongrak Kwonae680ab2012-06-15 22:06:54 -0700949#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
950 if (unlikely(touch_i2c_write_byte(client,
951 PAGE_SELECT_REG, 0x01) < 0)) {
952 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
953 return -EIO;
954 }
955
956 if (unlikely(touch_i2c_write_byte(client,
957 ANALOG_CONTROL_REG, 0x0) < 0)) {
958 TOUCH_ERR_MSG("ANALOG_CONTROL_REG write fail\n");
959 return -EIO;
960 }
961
962 msleep(10);
963
964 if (unlikely(touch_i2c_write_byte(client,
965 ANALOG_COMMAND_REG,
966 FORCE_UPDATE) < 0)) {
967 TOUCH_ERR_MSG("force fast relaxation command write fail\n");
968 return -EIO;
969 }
970
971 if (unlikely(touch_i2c_write_byte(client,
972 PAGE_SELECT_REG, 0x00) < 0)) {
973 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
974 return -EIO;
975 }
976
977 if (unlikely(touch_debug_mask & DEBUG_GHOST))
978 TOUCH_INFO_MSG("BASELINE_FIX ~~~~~~~~\n");
979#else
980 if (unlikely(touch_i2c_write_byte(client,
981 MELT_CONTROL_REG,
982 MELT_CONTROL_NO_MELT) < 0)) {
983 TOUCH_ERR_MSG("MELT_CONTROL_REG write fail\n");
984 return -EIO;
985 }
986#endif
987 break;
988 case BASELINE_REBASE:
989 /* rebase base line */
990 if (likely(ts->finger_dsc.id != 0)) {
991 if (unlikely(touch_i2c_write_byte(client,
992 FINGER_COMMAND_REG, 0x1) < 0)) {
993 TOUCH_ERR_MSG("finger baseline reset "
994 "command write fail\n");
995 return -EIO;
996 }
997 }
998
999#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
1000/* do nothing */
1001#else
1002 if (unlikely(ts->button_dsc.id != 0)) {
1003 if (unlikely(touch_i2c_write_byte(client,
1004 BUTTON_COMMAND_REG, 0x1) < 0)) {
1005 TOUCH_ERR_MSG("finger baseline reset "
1006 "command write fail\n");
1007 return -EIO;
1008 }
1009 }
1010#endif
1011 break;
1012 default:
1013 break;
1014 }
1015 break;
1016 case IC_CTRL_READ:
Jongrak Kwon9ed2a932012-06-19 23:38:02 -07001017#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
1018 if (unlikely(touch_i2c_write_byte(client,
1019 PAGE_SELECT_REG, ((value & 0xFF00) >> 8)) < 0)) {
1020 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
1021 return -EIO;
1022 }
1023
1024 if (touch_i2c_read(client, (value & 0xFF), 1, &buf) < 0) {
1025 TOUCH_ERR_MSG("IC register read fail\n");
1026 return -EIO;
1027 }
1028
1029 if (unlikely(touch_i2c_write_byte(client,
1030 PAGE_SELECT_REG, 0x00) < 0)) {
1031 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
1032 return -EIO;
1033 }
1034#else
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001035 if (touch_i2c_read(client, value, 1, &buf) < 0) {
1036 TOUCH_ERR_MSG("IC register read fail\n");
1037 return -EIO;
1038 }
Jongrak Kwon9ed2a932012-06-19 23:38:02 -07001039#endif
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001040 break;
1041 case IC_CTRL_WRITE:
Jongrak Kwon9ed2a932012-06-19 23:38:02 -07001042#if defined(CONFIG_TOUCH_REG_MAP_TM2000) || defined(CONFIG_TOUCH_REG_MAP_TM2372)
1043 if (unlikely(touch_i2c_write_byte(client,
1044 PAGE_SELECT_REG, ((value & 0xFF0000) >> 16)) < 0)) {
1045 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
1046 return -EIO;
1047 }
1048
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001049 if (touch_i2c_write_byte(client,
1050 ((value & 0xFF00) >> 8), (value & 0xFF)) < 0) {
1051 TOUCH_ERR_MSG("IC register write fail\n");
1052 return -EIO;
1053 }
Jongrak Kwon9ed2a932012-06-19 23:38:02 -07001054
1055 if (unlikely(touch_i2c_write_byte(client,
1056 PAGE_SELECT_REG, 0x00) < 0)) {
1057 TOUCH_ERR_MSG("PAGE_SELECT_REG write fail\n");
1058 return -EIO;
1059 }
1060#else
1061 if (touch_i2c_write_byte(client,
1062 ((value & 0xFF00) >> 8), (value & 0xFF)) < 0) {
1063 TOUCH_ERR_MSG("IC register write fail\n");
1064 return -EIO;
1065 }
1066#endif
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001067 break;
1068 case IC_CTRL_RESET_CMD:
1069 if (unlikely(touch_i2c_write_byte(client,
1070 DEVICE_COMMAND_REG, 0x1) < 0)) {
1071 TOUCH_ERR_MSG("IC Reset command write fail\n");
1072 return -EIO;
1073 }
1074 break;
1075 default:
1076 break;
1077 }
1078
1079 return buf;
1080}
1081
1082int synaptics_ts_fw_upgrade_check(struct lge_touch_data *ts)
1083{
1084#if defined(CONFIG_TOUCH_REG_MAP_TM2000)
1085 if (ts->fw_info.fw_force_rework) {
1086 TOUCH_INFO_MSG("FW-upgrade Force Rework.\n");
1087 } else {
1088 /* do not update 7020 gff, 7020 g2, 3203 g2 */
1089 if (((ts->fw_info.fw_version[0] == '0' &&
1090 (int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) == 0) ||
1091 (ts->fw_info.fw_version[0] == 'S' &&
1092 (int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) == 1) ||
1093 (ts->fw_info.fw_version[0] == 'E' &&
1094 (int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) < 27) ||
1095 (ts->fw_info.fw_version[0] == 'T'))) {
1096 TOUCH_INFO_MSG("DO NOT UPDATE 7020 gff, 7020 g2, 3203 " "g2 FW-upgrade is not executed\n");
1097 return -1;
1098 }
1099
1100 if ((ts->fw_info.fw_version[0] == 'E' &&
1101 (int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) >= 27) && !ts->fw_upgrade.fw_force_upgrade) { /* 7020 g2 h pattern */
1102
1103 if (((int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) >= (int)simple_strtoul(&ts->fw_info.fw_image_version[1], NULL, 10))) {
1104 TOUCH_INFO_MSG("DO NOT UPDATE 7020 G2 H " "pattern FW-upgrade is not executed\n");
1105 return -1;
1106 } else {
1107 TOUCH_INFO_MSG("7020 G2 H pattern FW-upgrade " "is executed\n");
1108 }
1109 } else {
1110 if (!ts->fw_upgrade.fw_force_upgrade) {
1111 TOUCH_INFO_MSG("UNKNOWN PANEL. FW-upgrade is" " not executed\n");
1112 return -1;
1113 }
1114 }
1115 }
1116#elif defined(CONFIG_TOUCH_REG_MAP_TM2372)
1117 if (ts->fw_info.fw_force_rework) {
1118 TOUCH_INFO_MSG("FW-upgrade Force Rework.\n");
1119 } else {
1120 if ((ts->fw_info.fw_version[0] == 'E' &&
1121 (int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) >= 1) &&
1122 !ts->fw_upgrade.fw_force_upgrade) {
1123
1124 if (((int)simple_strtoul(&ts->fw_info.fw_version[1], NULL, 10) >=
1125 (int)simple_strtoul(&ts->fw_info.fw_image_version[1],
1126 NULL, 10))) {
1127 TOUCH_INFO_MSG("DO NOT UPDATE 7020 GFF H " "pattern FW-upgrade is not executed\n");
1128 return -1;
1129 } else {
1130 TOUCH_INFO_MSG("7020 GFF H pattern FW-upgrade " "is executed\n");
1131 }
1132 } else {
1133 if (!ts->fw_upgrade.fw_force_upgrade) {
1134 TOUCH_INFO_MSG("UNKNOWN PANEL. FW-upgrade is not executed\n");
1135 return -1;
1136 }
1137 }
1138 }
1139#else
Jongrak Kwon9ed2a932012-06-19 23:38:02 -07001140#error NOT SUPPORTED TYPE
Jongrak Kwonae680ab2012-06-15 22:06:54 -07001141#endif
1142
1143 return 0;
1144}
1145
1146struct touch_device_driver synaptics_ts_driver = {
1147 .probe = synaptics_ts_probe,
1148 .remove = synaptics_ts_remove,
1149 .init = synaptics_ts_init,
1150 .data = synaptics_ts_get_data,
1151 .power = synaptics_ts_power,
1152 .fw_upgrade = synaptics_ts_fw_upgrade,
1153 .ic_ctrl = synaptics_ts_ic_ctrl,
1154 .fw_upgrade_check = synaptics_ts_fw_upgrade_check,
1155};
1156
1157static int __devinit touch_init(void)
1158{
1159 if (touch_debug_mask & DEBUG_TRACE)
1160 TOUCH_DEBUG_MSG("\n");
1161
1162 return touch_driver_register(&synaptics_ts_driver);
1163}
1164
1165static void __exit touch_exit(void)
1166{
1167 if (touch_debug_mask & DEBUG_TRACE)
1168 TOUCH_DEBUG_MSG("\n");
1169
1170 touch_driver_unregister();
1171}
1172
1173module_init(touch_init);
1174module_exit(touch_exit);
1175
1176MODULE_AUTHOR("yehan.ahn@lge.com, hyesung.shin@lge.com");
1177MODULE_DESCRIPTION("LGE Touch Driver");
1178MODULE_LICENSE("GPL");
1179